Merge "feat: add base media player container" into androidx-main
diff --git a/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityComposeIssueRegistry.kt b/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityComposeIssueRegistry.kt
index 76b1f3e..656270a 100644
--- a/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityComposeIssueRegistry.kt
+++ b/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityComposeIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class ActivityComposeIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ActivityResultLaunchDetector.LaunchDuringComposition
diff --git a/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt b/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt
index 168ec91..794624c 100644
--- a/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt
+++ b/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt
@@ -26,7 +26,7 @@
 @Suppress("UnstableApiUsage")
 class ActivityIssueRegistry : IssueRegistry() {
     // tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ActivityResultFragmentVersionDetector.ISSUE
diff --git a/activity/activity/api/1.7.0-beta02.txt b/activity/activity/api/1.7.0-beta02.txt
index bf98034..4bbcdbb 100644
--- a/activity/activity/api/1.7.0-beta02.txt
+++ b/activity/activity/api/1.7.0-beta02.txt
@@ -319,7 +319,9 @@
     method @Deprecated public static final boolean isPhotoPickerAvailable();
     method public static final boolean isPhotoPickerAvailable(android.content.Context context);
     method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final String ACTION_SYSTEM_FALLBACK_PICK_IMAGES = "androidx.activity.result.contract.action.PICK_IMAGES";
     field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+    field public static final String EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX = "androidx.activity.result.contract.extra.PICK_IMAGES_MAX";
   }
 
   public static final class ActivityResultContracts.PickVisualMedia.Companion {
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index bf98034..4bbcdbb 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -319,7 +319,9 @@
     method @Deprecated public static final boolean isPhotoPickerAvailable();
     method public static final boolean isPhotoPickerAvailable(android.content.Context context);
     method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final String ACTION_SYSTEM_FALLBACK_PICK_IMAGES = "androidx.activity.result.contract.action.PICK_IMAGES";
     field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+    field public static final String EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX = "androidx.activity.result.contract.extra.PICK_IMAGES_MAX";
   }
 
   public static final class ActivityResultContracts.PickVisualMedia.Companion {
diff --git a/activity/activity/api/public_plus_experimental_1.7.0-beta02.txt b/activity/activity/api/public_plus_experimental_1.7.0-beta02.txt
index bf98034..4bbcdbb 100644
--- a/activity/activity/api/public_plus_experimental_1.7.0-beta02.txt
+++ b/activity/activity/api/public_plus_experimental_1.7.0-beta02.txt
@@ -319,7 +319,9 @@
     method @Deprecated public static final boolean isPhotoPickerAvailable();
     method public static final boolean isPhotoPickerAvailable(android.content.Context context);
     method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final String ACTION_SYSTEM_FALLBACK_PICK_IMAGES = "androidx.activity.result.contract.action.PICK_IMAGES";
     field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+    field public static final String EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX = "androidx.activity.result.contract.extra.PICK_IMAGES_MAX";
   }
 
   public static final class ActivityResultContracts.PickVisualMedia.Companion {
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index bf98034..4bbcdbb 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -319,7 +319,9 @@
     method @Deprecated public static final boolean isPhotoPickerAvailable();
     method public static final boolean isPhotoPickerAvailable(android.content.Context context);
     method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final String ACTION_SYSTEM_FALLBACK_PICK_IMAGES = "androidx.activity.result.contract.action.PICK_IMAGES";
     field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+    field public static final String EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX = "androidx.activity.result.contract.extra.PICK_IMAGES_MAX";
   }
 
   public static final class ActivityResultContracts.PickVisualMedia.Companion {
diff --git a/activity/activity/api/restricted_1.7.0-beta02.txt b/activity/activity/api/restricted_1.7.0-beta02.txt
index 7561e11..2997940 100644
--- a/activity/activity/api/restricted_1.7.0-beta02.txt
+++ b/activity/activity/api/restricted_1.7.0-beta02.txt
@@ -318,7 +318,9 @@
     method @Deprecated public static final boolean isPhotoPickerAvailable();
     method public static final boolean isPhotoPickerAvailable(android.content.Context context);
     method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final String ACTION_SYSTEM_FALLBACK_PICK_IMAGES = "androidx.activity.result.contract.action.PICK_IMAGES";
     field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+    field public static final String EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX = "androidx.activity.result.contract.extra.PICK_IMAGES_MAX";
   }
 
   public static final class ActivityResultContracts.PickVisualMedia.Companion {
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index 7561e11..2997940 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -318,7 +318,9 @@
     method @Deprecated public static final boolean isPhotoPickerAvailable();
     method public static final boolean isPhotoPickerAvailable(android.content.Context context);
     method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final String ACTION_SYSTEM_FALLBACK_PICK_IMAGES = "androidx.activity.result.contract.action.PICK_IMAGES";
     field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+    field public static final String EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX = "androidx.activity.result.contract.extra.PICK_IMAGES_MAX";
   }
 
   public static final class ActivityResultContracts.PickVisualMedia.Companion {
diff --git a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt
index 81d62c5..ed0c940 100644
--- a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt
+++ b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt
@@ -32,9 +32,11 @@
 import androidx.activity.result.IntentSenderRequest
 import androidx.activity.result.PickVisualMediaRequest
 import androidx.activity.result.contract.ActivityResultContracts.GetMultipleContents.Companion.getClipDataUris
+import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion.ACTION_SYSTEM_FALLBACK_PICK_IMAGES
 import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion.GMS_ACTION_PICK_IMAGES
 import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion.GMS_EXTRA_PICK_IMAGES_MAX
 import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion.getGmsPicker
+import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion.getSystemFallbackPicker
 import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult.Companion.ACTION_INTENT_SENDER_REQUEST
 import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult.Companion.EXTRA_SEND_INTENT_EXCEPTION
 import androidx.annotation.CallSuper
@@ -608,8 +610,21 @@
     }
 
     /**
-     * An [ActivityResultContract] to use the photo picker through [MediaStore.ACTION_PICK_IMAGES]
-     * when available, and else rely on ACTION_OPEN_DOCUMENT.
+     * An [ActivityResultContract] to use the
+     * [Photo Picker](https://developer.android.com/training/data-storage/shared/photopicker)
+     * to select a single image, video, or other type of visual media.
+     *
+     * This contract always prefers the system framework provided Photo Picker available via
+     * [MediaStore.ACTION_PICK_IMAGES] when it is available, but will also provide a fallback
+     * on devices that it is not available to ensure a consistent API surface across all
+     * Android API 19 or higher devices.
+     *
+     * The priority order for handling the Photo Picker is:
+     * 1. The system framework provided [MediaStore.ACTION_PICK_IMAGES].
+     * - An OEM can provide a system app that implements [ACTION_SYSTEM_FALLBACK_PICK_IMAGES] to
+     * provide a consistent Photo Picker to older devices.
+     * - [Intent.ACTION_OPEN_DOCUMENT] is used as a final fallback on all Android API 19 or
+     * higher devices.
      *
      * The input is a [PickVisualMediaRequest].
      *
@@ -624,13 +639,15 @@
         companion object {
             /**
              * Check if the current device has support for the photo picker by checking the running
-             * Android version or the SDK extension version (not including the picker
-             * provided by Google Play services)
+             * Android version or the SDK extension version.
+             *
+             * Note that this does not check for any Intent handled by
+             * [ACTION_SYSTEM_FALLBACK_PICK_IMAGES].
              */
             @SuppressLint("ClassVerificationFailure", "NewApi")
             @Deprecated(
                 message = "This method is deprecated in favor of isPhotoPickerAvailable(context) " +
-                    "to support the picker provided by Google Play services",
+                    "to support the picker provided by updatable system apps",
                 replaceWith = ReplaceWith("isPhotoPickerAvailable(context)")
             )
             @JvmStatic
@@ -638,6 +655,37 @@
                 return isSystemPickerAvailable()
             }
 
+            /**
+             * In cases where the system framework provided [MediaStore.ACTION_PICK_IMAGES]
+             * Photo Picker cannot be implemented, OEMs or system apps can provide a consistent
+             * Photo Picker experience to those devices by creating an Activity that handles
+             * this action. This app must also include [Intent.CATEGORY_DEFAULT] in the activity's
+             * intent filter.
+             *
+             * Only system apps can implement this action - any non-system apps will be ignored
+             * when searching for the activities that handle this Intent.
+             *
+             * Note: this should not be used directly, instead relying on the selection logic
+             * done by [createIntent] to create the correct Intent for the current device.
+             */
+            @Suppress("ActionValue") /* Don't include SYSTEM_FALLBACk in the action */
+            const val ACTION_SYSTEM_FALLBACK_PICK_IMAGES =
+                "androidx.activity.result.contract.action.PICK_IMAGES"
+
+            /**
+             * Extra that will be sent by [PickMultipleVisualMedia] to an Activity that handles
+             * [ACTION_SYSTEM_FALLBACK_PICK_IMAGES] that indicates that maximum number of photos
+             * the user should select.
+             *
+             * If this extra is not present, only a single photo should be selectable.
+             *
+             * If this extra is present but equal to [Int.MAX_VALUE], then no limit should
+             * be enforced.
+             */
+            @Suppress("ActionValue") /* Don't include SYSTEM_FALLBACk in the extra */
+            const val EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX =
+                "androidx.activity.result.contract.extra.PICK_IMAGES_MAX"
+
             internal const val GMS_ACTION_PICK_IMAGES =
                 "com.google.android.gms.provider.action.PICK_IMAGES"
             internal const val GMS_EXTRA_PICK_IMAGES_MAX =
@@ -645,19 +693,22 @@
 
             /**
              * Check if the current device has support for the photo picker by checking the running
-             * Android version, the SDK extension version or the picker provided by Google Play
-             * services
+             * Android version, the SDK extension version or the picker provided by
+             * a system app implementing [ACTION_SYSTEM_FALLBACK_PICK_IMAGES].
              */
             @SuppressLint("ClassVerificationFailure", "NewApi")
             @JvmStatic
             fun isPhotoPickerAvailable(context: Context): Boolean {
-                return isSystemPickerAvailable() || isGmsPickerAvailable(context)
+                return isSystemPickerAvailable() || isSystemFallbackPickerAvailable(context) ||
+                    isGmsPickerAvailable(context)
             }
 
             /**
-             * Check if the current device has support for the Android photo picker by checking the
-             * running Android version or the SDK extension version (not including the picker
-             * provided by Google Play services)
+             * Check if the current device has support for the system framework provided photo
+             * picker by checking the running Android version or the SDK extension version.
+             *
+             * Note that this does not check for any Intent handled by
+             * [ACTION_SYSTEM_FALLBACK_PICK_IMAGES].
              */
             @SuppressLint("ClassVerificationFailure", "NewApi")
             @JvmStatic
@@ -674,6 +725,20 @@
             }
 
             @JvmStatic
+            internal fun isSystemFallbackPickerAvailable(context: Context): Boolean {
+                return getSystemFallbackPicker(context) != null
+            }
+
+            @Suppress("DEPRECATION")
+            @JvmStatic
+            internal fun getSystemFallbackPicker(context: Context): ResolveInfo? {
+                return context.packageManager.resolveActivity(
+                    Intent(ACTION_SYSTEM_FALLBACK_PICK_IMAGES),
+                    PackageManager.MATCH_DEFAULT_ONLY or PackageManager.MATCH_SYSTEM_ONLY
+                )
+            }
+
+            @JvmStatic
             internal fun isGmsPickerAvailable(context: Context): Boolean {
                 return getGmsPicker(context) != null
             }
@@ -730,6 +795,12 @@
                 Intent(MediaStore.ACTION_PICK_IMAGES).apply {
                     type = getVisualMimeType(input.mediaType)
                 }
+            } else if (isSystemFallbackPickerAvailable(context)) {
+                val fallbackPicker = checkNotNull(getSystemFallbackPicker(context)).activityInfo
+                Intent(ACTION_SYSTEM_FALLBACK_PICK_IMAGES).apply {
+                    setClassName(fallbackPicker.applicationInfo.packageName, fallbackPicker.name)
+                    type = getVisualMimeType(input.mediaType)
+                }
             } else if (isGmsPickerAvailable(context)) {
                 val gmsPicker = checkNotNull(getGmsPicker(context)).activityInfo
                 Intent(GMS_ACTION_PICK_IMAGES).apply {
@@ -769,12 +840,27 @@
     }
 
     /**
-     * An [ActivityResultContract] to use the Photo Picker through [MediaStore.ACTION_PICK_IMAGES]
-     * when available, and else rely on ACTION_OPEN_DOCUMENT.
+     * An [ActivityResultContract] to use the
+     * [Photo Picker](https://developer.android.com/training/data-storage/shared/photopicker)
+     * to select a single image, video, or other type of visual media.
      *
-     * The constructor accepts one parameter `maxItems` to limit the number of selectable items when
-     * using the photo picker to return. Keep in mind that this parameter isn't supported on devices
-     * when the photo picker isn't available.
+     * This contract always prefers the system framework provided Photo Picker available via
+     * [MediaStore.ACTION_PICK_IMAGES] when it is available, but will also provide a fallback
+     * on devices that it is not available to provide a consistent API surface across all
+     * Android API 19 or higher devices.
+     *
+     * The priority order for handling the Photo Picker is:
+     * 1. The system framework provided [MediaStore.ACTION_PICK_IMAGES].
+     * - An OEM can provide a system app that implements
+     * [PickVisualMedia.ACTION_SYSTEM_FALLBACK_PICK_IMAGES] to provide a consistent Photo Picker
+     * to older devices. These system apps may handle the
+     * [PickVisualMedia.EXTRA_SYSTEM_FALLBACK_PICK_IMAGES_MAX] extra to respect the
+     * [maxItems] passed to this contract.
+     * - [Intent.ACTION_OPEN_DOCUMENT] is used as a final fallback on all Android API 19 or
+     * higher devices. This Intent does not allow limiting the max items the user selects.
+     *
+     * The constructor accepts one parameter [maxItems] to limit the number of selectable items when
+     * using the photo picker to return.
      *
      * The input is a [PickVisualMediaRequest].
      *
@@ -808,6 +894,13 @@
 
                     putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxItems)
                 }
+            } else if (PickVisualMedia.isSystemFallbackPickerAvailable(context)) {
+                val fallbackPicker = checkNotNull(getSystemFallbackPicker(context)).activityInfo
+                Intent(ACTION_SYSTEM_FALLBACK_PICK_IMAGES).apply {
+                    setClassName(fallbackPicker.applicationInfo.packageName, fallbackPicker.name)
+                    type = PickVisualMedia.getVisualMimeType(input.mediaType)
+                    putExtra(GMS_EXTRA_PICK_IMAGES_MAX, maxItems)
+                }
             } else if (PickVisualMedia.isGmsPickerAvailable(context)) {
                 val gmsPicker = checkNotNull(getGmsPicker(context)).activityInfo
                 Intent(GMS_ACTION_PICK_IMAGES).apply {
@@ -848,8 +941,8 @@
             /**
              * The system photo picker has a maximum limit of selectable items returned by
              * [MediaStore.getPickImagesMaxLimit()]
-             * On devices supporting picker provided by Google Play services, the limit is ignored
-             * if it's higher than the allowed limit.
+             * On devices supporting picker provided via [ACTION_SYSTEM_FALLBACK_PICK_IMAGES],
+             * the limit may be ignored if it's higher than the allowed limit.
              * On devices not supporting the photo picker, the limit is ignored.
              *
              * @see MediaStore.EXTRA_PICK_IMAGES_MAX
diff --git a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalIssueRegistry.kt b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalIssueRegistry.kt
index 1cf3f9a..0f6ff59 100644
--- a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalIssueRegistry.kt
+++ b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalIssueRegistry.kt
@@ -23,7 +23,7 @@
 @Suppress("UnstableApiUsage")
 class ExperimentalIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues get() = ExperimentalDetector.ISSUES + AnnotationRetentionDetector.ISSUES
     override val vendor = Vendor(
         feedbackUrl = "https://issuetracker.google.com/issues/new?component=459778",
diff --git a/appactions/interaction/interaction-capabilities-core/build.gradle b/appactions/interaction/interaction-capabilities-core/build.gradle
index fdb938f..2fccf45 100644
--- a/appactions/interaction/interaction-capabilities-core/build.gradle
+++ b/appactions/interaction/interaction-capabilities-core/build.gradle
@@ -24,11 +24,13 @@
 }
 
 dependencies {
+    api(libs.kotlinStdlib)
     api(libs.autoValueAnnotations)
     api(libs.kotlinStdlib)
     annotationProcessor(libs.autoValue)
     implementation(libs.protobufLite)
     implementation(libs.guavaListenableFuture)
+    implementation(libs.kotlinCoroutinesGuava)
     implementation("androidx.concurrent:concurrent-futures:1.1.0")
     implementation(project(":appactions:interaction:interaction-proto"))
 
@@ -37,6 +39,7 @@
     testImplementation(libs.truth)
     testImplementation(libs.testCore)
     testImplementation(libs.mockitoCore)
+    testImplementation(libs.mockitoKotlin4)
     testImplementation(libs.kotlinStdlib)
     testImplementation(libs.androidLint)
     testImplementation(libs.androidLintTests)
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/AbstractCapabilityBuilder.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/AbstractCapabilityBuilder.java
index a7c0999..44762184 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/AbstractCapabilityBuilder.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/AbstractCapabilityBuilder.java
@@ -18,13 +18,14 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.appactions.interaction.capabilities.core.impl.spec.ActionCapabilityImpl;
+import androidx.appactions.interaction.capabilities.core.impl.SingleTurnCapabilityImpl;
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec;
 import androidx.appactions.interaction.capabilities.core.task.impl.AbstractTaskUpdater;
 import androidx.appactions.interaction.capabilities.core.task.impl.TaskCapabilityImpl;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
 import java.util.Objects;
-import java.util.Optional;
 
 /**
  * An abstract Builder class for ActionCapability.
@@ -39,7 +40,12 @@
 public abstract class AbstractCapabilityBuilder<
         BuilderT extends
                 AbstractCapabilityBuilder<
-                        BuilderT, PropertyT, ArgumentT, OutputT, ConfirmationT, TaskUpdaterT>,
+                                BuilderT,
+                                PropertyT,
+                                ArgumentT,
+                                OutputT,
+                                ConfirmationT,
+                                TaskUpdaterT>,
         PropertyT,
         ArgumentT,
         OutputT,
@@ -47,14 +53,10 @@
         TaskUpdaterT extends AbstractTaskUpdater> {
 
     private final ActionSpec<PropertyT, ArgumentT, OutputT> mActionSpec;
-    @Nullable
-    private String mId;
-    @Nullable
-    private PropertyT mProperty;
-    @Nullable
-    private ActionExecutor<ArgumentT, OutputT> mActionExecutor;
-    @Nullable
-    private TaskHandler<ArgumentT, OutputT, ConfirmationT, TaskUpdaterT> mTaskHandler;
+    @Nullable private String mId;
+    @Nullable private PropertyT mProperty;
+    @Nullable private ActionExecutor<ArgumentT, OutputT> mActionExecutor;
+    @Nullable private TaskHandler<ArgumentT, OutputT, ConfirmationT, TaskUpdaterT> mTaskHandler;
 
     /**
      * @param actionSpec
@@ -90,10 +92,9 @@
 
     /**
      * Sets the TaskHandler for this capability. The individual capability factory classes can
-     * decide
-     * to expose their own public {@code setTaskHandler} method and invoke this parent method.
-     * Setting
-     * the TaskHandler should build a capability instance that supports multi-turn tasks.
+     * decide to expose their own public {@code setTaskHandler} method and invoke this parent
+     * method. Setting the TaskHandler should build a capability instance that supports multi-turn
+     * tasks.
      */
     protected final BuilderT setTaskHandler(
             @NonNull TaskHandler<ArgumentT, OutputT, ConfirmationT, TaskUpdaterT> taskHandler) {
@@ -115,22 +116,31 @@
         Objects.requireNonNull(mProperty, "property must not be null.");
         if (mTaskHandler == null) {
             Objects.requireNonNull(mActionExecutor, "actionExecutor must not be null.");
-            return new ActionCapabilityImpl<>(
-                    mActionSpec, Optional.ofNullable(mId), mProperty, mActionExecutor);
+            return new SingleTurnCapabilityImpl<PropertyT, ArgumentT, OutputT>(
+                    mId,
+                    mActionSpec,
+                    mProperty,
+                    (hostProperties)->new BaseSession<ArgumentT, OutputT>() {
+                        @Override
+                        public ListenableFuture<ExecutionResult<OutputT>> onFinishAsync(
+                                ArgumentT argument) {
+                            return mActionExecutor.execute(argument);
+                        }
+                    });
         }
         TaskCapabilityImpl<PropertyT, ArgumentT, OutputT, ConfirmationT, TaskUpdaterT>
                 taskCapability =
-                new TaskCapabilityImpl<>(
-                        Objects.requireNonNull(mId, "id field must not be null."),
-                        mActionSpec,
-                        mProperty,
-                        mTaskHandler.getParamsRegistry(),
-                        mTaskHandler.getOnInitListener(),
-                        mTaskHandler.getOnReadyToConfirmListener(),
-                        mTaskHandler.getOnFinishListener(),
-                        mTaskHandler.getConfirmationDataBindings(),
-                        mTaskHandler.getExecutionOutputBindings(),
-                        Runnable::run);
+                        new TaskCapabilityImpl<>(
+                                Objects.requireNonNull(mId, "id field must not be null."),
+                                mActionSpec,
+                                mProperty,
+                                mTaskHandler.getParamsRegistry(),
+                                mTaskHandler.getOnInitListener(),
+                                mTaskHandler.getOnReadyToConfirmListener(),
+                                mTaskHandler.getOnFinishListener(),
+                                mTaskHandler.getConfirmationDataBindings(),
+                                mTaskHandler.getExecutionOutputBindings(),
+                                Runnable::run);
         taskCapability.setTaskUpdaterSupplier(mTaskHandler.getTaskUpdaterSupplier());
         return taskCapability;
     }
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/ActionCapability.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/ActionCapability.kt
similarity index 64%
rename from appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/ActionCapability.java
rename to appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/ActionCapability.kt
index 6e1f4c3..2325c2a 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/ActionCapability.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/ActionCapability.kt
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package androidx.appactions.interaction.capabilities.core;
+package androidx.appactions.interaction.capabilities.core
 
-import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
-import androidx.appactions.interaction.capabilities.core.impl.ArgumentsWrapper;
-import androidx.appactions.interaction.capabilities.core.impl.CallbackInternal;
-import androidx.appactions.interaction.capabilities.core.impl.TouchEventCallback;
-import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
-
-import java.util.Optional;
+import androidx.annotation.RestrictTo
+import androidx.appactions.interaction.capabilities.core.impl.ActionCapabilitySession
+import androidx.appactions.interaction.capabilities.core.impl.ArgumentsWrapper
+import androidx.appactions.interaction.capabilities.core.impl.CallbackInternal
+import androidx.appactions.interaction.capabilities.core.impl.TouchEventCallback
+import androidx.appactions.interaction.proto.AppActionsContext.AppAction
 
 /**
  * <b>Do not implement this interface yourself.</b>
@@ -32,11 +30,15 @@
  *
  * <p>Use helper classes provided by the capability library to get instances of this interface.
  */
-public interface ActionCapability {
+interface ActionCapability {
 
     /** Returns the unique Id of this capability declaration. */
-    @NonNull
-    Optional<String> getId();
+    val id: String?
+
+    /**
+     * Returns whether or not this capability supports multi-turn task.
+     */
+    val supportsMultiTurnTask: Boolean
 
     /**
      * Returns an app action proto describing how to fulfill this capability.
@@ -44,18 +46,23 @@
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    AppAction getAppAction();
+    fun getAppAction(): AppAction
 
     /**
      * Executes the action and returns the result of execution.
      *
      * @param argumentsWrapper The arguments send from assistant to the activity.
      * @param callback The callback to receive app action result.
+     *
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    void execute(@NonNull ArgumentsWrapper argumentsWrapper, @NonNull CallbackInternal callback);
+    fun execute(
+        argumentsWrapper: ArgumentsWrapper,
+        callback: CallbackInternal,
+    ) {
+        throw UnsupportedOperationException()
+    }
 
     /**
      * Support for manual input. This method should be invoked by AppInteraction SDKs
@@ -65,5 +72,16 @@
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    default void setTouchEventCallback(@NonNull TouchEventCallback callback) {}
+    fun setTouchEventCallback(callback: TouchEventCallback) {}
+
+    /**
+     * Create a new capability session. The capability library doesn't maintain registry of
+     * capabilities, so it's not going to assign any session id.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun createSession(hostProperties: HostProperties): ActionCapabilitySession {
+        throw UnsupportedOperationException()
+    }
 }
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/BaseSession.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/BaseSession.kt
new file mode 100644
index 0000000..e4b20fe
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/BaseSession.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core
+
+import com.google.common.util.concurrent.ListenableFuture
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.guava.future
+/**
+ * Base interface for Session of all verticals.
+ */
+interface BaseSession<ArgumentT, OutputT> {
+    /**
+     * Implement any initialization logic.
+     *
+     * This method is called once, before any other listeners are invoked.
+     */
+    fun onInit(initArg: InitArg) {}
+
+    /**
+     * Called when all arguments are finalized.
+     * @param argument the Argument instance containing data for fulfillment.
+     * @return an ExecutionResult instance.
+     */
+    suspend fun onFinish(argument: ArgumentT): ExecutionResult<OutputT> {
+        throw NotImplementedError()
+    }
+
+    /**
+     * Called when all arguments are finalized.
+     * @param argument the Argument instance containing data for fulfillment.
+     * @return a ListenableFuture containing an ExecutionResult instance.
+     */
+    @kotlin.OptIn(DelicateCoroutinesApi::class)
+    fun onFinishAsync(argument: ArgumentT): ListenableFuture<ExecutionResult<OutputT>> {
+        return GlobalScope.future { onFinish(argument) }
+    }
+
+    /**
+     * Implement any cleanup logic.
+     * This method is called some time after the session finishes.
+     */
+    fun onDestroy() {}
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/HostProperties.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/HostProperties.kt
new file mode 100644
index 0000000..c0ceb39
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/HostProperties.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core
+
+import android.util.SizeF
+import java.util.Objects
+
+/**
+ * HostProperties contains information about the host that can be used to customize behaviour for
+ * different environments.
+ */
+class HostProperties internal constructor(val maxHostSizeDp: SizeF) {
+    override fun toString() =
+        "HostProperties(maxHostSizeDp=$maxHostSizeDp)"
+
+    override fun equals(other: Any?): Boolean {
+        return other is HostProperties && maxHostSizeDp == other.maxHostSizeDp
+    }
+
+    override fun hashCode() = Objects.hash(maxHostSizeDp)
+
+    /**
+     * Builder class for HostProperties.
+     */
+    class Builder {
+        private var maxHostSizeDp: SizeF? = null
+
+        /** Sets the dimensions of the host area where the app content will be displayed in dp. */
+        fun setMaxHostSizeDp(maxHostSizeDp: SizeF) = apply {
+            this.maxHostSizeDp = maxHostSizeDp
+        }
+
+        /**
+         * Builds and returns the HostProperties instance.
+         */
+        fun build() = HostProperties(
+            requireNotNull(maxHostSizeDp, { "maxHostSizeDp must be set." }),
+        )
+    }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/InitArg.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/InitArg.kt
new file mode 100644
index 0000000..f01729c
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/InitArg.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core
+
+/**
+ * InitArg contains data passed to {@code BaseSession#onInit}.
+ */
+class InitArg internal constructor() {
+    override fun toString() =
+        "InitArg()"
+
+    override fun equals(other: Any?): Boolean {
+        return other is InitArg
+    }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/SessionBuilder.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/SessionBuilder.kt
new file mode 100644
index 0000000..7aa2a29
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/SessionBuilder.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core
+
+/**
+ * Interface to be implemented for creating SessionT instances.
+ */
+fun interface SessionBuilder<SessionT> {
+    /**
+     * @return A new SessionT instance for handling a task.
+     */
+    fun createSession(
+        hostProperties: HostProperties,
+    ): SessionT
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ActionCapabilitySession.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ActionCapabilitySession.kt
new file mode 100644
index 0000000..0a9fb0e
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ActionCapabilitySession.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.impl
+
+import androidx.annotation.RestrictTo
+
+/**
+ * Internal interface for a session, contains developer's Session instance
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+interface ActionCapabilitySession {
+    /**
+     * Executes the action and returns the result of execution.
+     *
+     * @param argumentsWrapper The arguments send from assistant to the activity.
+     * @param callback The callback to receive app action result.
+     */
+    fun execute(
+        argumentsWrapper: ArgumentsWrapper,
+        callback: CallbackInternal,
+    )
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityImpl.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityImpl.kt
new file mode 100644
index 0000000..76ed7b5
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityImpl.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.impl
+
+import androidx.annotation.NonNull
+import androidx.appactions.interaction.capabilities.core.ActionCapability
+import androidx.appactions.interaction.capabilities.core.BaseSession
+import androidx.appactions.interaction.capabilities.core.HostProperties
+import androidx.appactions.interaction.capabilities.core.SessionBuilder
+import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec
+import androidx.appactions.interaction.proto.AppActionsContext.AppAction
+import androidx.appactions.interaction.proto.TaskInfo
+
+import androidx.annotation.RestrictTo
+
+/** @hide */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+internal class SingleTurnCapabilityImpl<
+    PropertyT,
+    ArgumentT,
+    OutputT,
+    > constructor(
+    override val id: String?,
+    val actionSpec: ActionSpec<PropertyT, ArgumentT, OutputT>,
+    val property: PropertyT,
+    val sessionBuilder: SessionBuilder<BaseSession<ArgumentT, OutputT>>,
+) : ActionCapability {
+    override val supportsMultiTurnTask = false
+
+    @NonNull
+    override fun getAppAction(): AppAction {
+        val appActionBuilder = actionSpec.convertPropertyToProto(property).toBuilder()
+            .setTaskInfo(TaskInfo.newBuilder().setSupportsPartialFulfillment(false))
+        id?.let(appActionBuilder::setIdentifier)
+        return appActionBuilder.build()
+    }
+
+    @NonNull
+    override fun createSession(hostProperties: HostProperties): ActionCapabilitySession {
+        return SingleTurnCapabilitySession(
+            actionSpec,
+            sessionBuilder.createSession(hostProperties),
+        )
+    }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilitySession.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilitySession.kt
new file mode 100644
index 0000000..1b8bcf5
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilitySession.kt
@@ -0,0 +1,90 @@
+
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.impl
+
+import androidx.annotation.NonNull
+import androidx.appactions.interaction.capabilities.core.ExecutionResult
+import androidx.appactions.interaction.capabilities.core.BaseSession
+import androidx.appactions.interaction.capabilities.core.impl.concurrent.FutureCallback
+import androidx.appactions.interaction.capabilities.core.impl.concurrent.Futures
+import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec
+import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.FulfillmentValue
+import androidx.appactions.interaction.proto.FulfillmentResponse
+import androidx.appactions.interaction.proto.ParamValue
+
+import androidx.annotation.RestrictTo
+
+/**
+ * ActionCapabilitySession implementation for executing single-turn fulfillment requests.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+internal class SingleTurnCapabilitySession<
+    ArgumentT,
+    OutputT,
+>(
+    val actionSpec: ActionSpec<*, ArgumentT, OutputT>,
+    val externalSession: BaseSession<ArgumentT, OutputT>,
+) : ActionCapabilitySession {
+    override fun execute(
+        @NonNull argumentsWrapper: ArgumentsWrapper,
+        @NonNull callback: CallbackInternal,
+    ) {
+        val paramValuesMap: Map<String, List<ParamValue>> = argumentsWrapper.paramValues().entries
+            .associate {
+                    entry: Map.Entry<String, List<FulfillmentValue>> ->
+                Pair(
+                    entry.key,
+                    entry.value.mapNotNull {
+                            fulfillmentValue: FulfillmentValue ->
+                        fulfillmentValue.getValue()
+                    },
+                )
+            }
+        val argument = actionSpec.buildArgument(paramValuesMap)
+        Futures.addCallback(
+            externalSession.onFinishAsync(argument),
+            object : FutureCallback<ExecutionResult<OutputT>> {
+                override fun onSuccess(executionResult: ExecutionResult<OutputT>) {
+                    callback.onSuccess(convertToFulfillmentResponse(executionResult))
+                }
+
+                override fun onFailure(t: Throwable) {
+                    callback.onError(ErrorStatusInternal.CANCELLED)
+                }
+            },
+            Runnable::run,
+        )
+    }
+
+    /** Converts typed {@link ExecutionResult} to {@link FulfillmentResponse} proto. */
+    private fun convertToFulfillmentResponse(
+        executionResult: ExecutionResult<OutputT>,
+    ): FulfillmentResponse {
+        val fulfillmentResponseBuilder =
+            FulfillmentResponse.newBuilder()
+                .setStartDictation(executionResult.startDictation)
+        executionResult.output?.let { it ->
+            fulfillmentResponseBuilder.setExecutionOutput(
+                actionSpec.convertOutputToProto(it),
+            )
+        }
+        return fulfillmentResponseBuilder.build()
+    }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/PropertyConverter.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/PropertyConverter.java
index f665360..d1354c0 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/PropertyConverter.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/PropertyConverter.java
@@ -36,8 +36,7 @@
 /** Contains utility functions that convert properties to IntentParameter proto. */
 public final class PropertyConverter {
 
-    private PropertyConverter() {
-    }
+    private PropertyConverter() {}
 
     /** Create IntentParameter proto from a StringProperty. */
     @NonNull
@@ -112,16 +111,18 @@
     @NonNull
     public static Entity entityToProto(
             @NonNull androidx.appactions.interaction.capabilities.core.properties.Entity entity) {
-        Entity.Builder builder = Entity.newBuilder().addAllAlternateNames(
-                entity.getAlternateNames());
-        entity.getName().ifPresent(builder::setName);
-        entity.getId().ifPresent(builder::setIdentifier);
+        Entity.Builder builder =
+                Entity.newBuilder()
+                        .setName(entity.getName())
+                        .addAllAlternateNames(entity.getAlternateNames());
+        if (entity.getId() != null) {
+            builder.setIdentifier(entity.getId());
+        }
         return builder.build();
     }
 
     /**
-     * Converts a capabilities library StringProperty.PossibleValue to a appactions Entity proto
-     * .
+     * Converts a capabilities library StringProperty.PossibleValue to a appactions Entity proto .
      */
     @NonNull
     public static Entity possibleValueToProto(@NonNull PossibleValue possibleValue) {
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionCapabilityImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionCapabilityImpl.java
deleted file mode 100644
index a6bfaad..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionCapabilityImpl.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
-import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableMap;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.ActionCapability;
-import androidx.appactions.interaction.capabilities.core.ActionExecutor;
-import androidx.appactions.interaction.capabilities.core.ExecutionResult;
-import androidx.appactions.interaction.capabilities.core.impl.ArgumentsWrapper;
-import androidx.appactions.interaction.capabilities.core.impl.CallbackInternal;
-import androidx.appactions.interaction.capabilities.core.impl.ErrorStatusInternal;
-import androidx.appactions.interaction.capabilities.core.impl.concurrent.FutureCallback;
-import androidx.appactions.interaction.capabilities.core.impl.concurrent.Futures;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.impl.utils.CapabilityLogger;
-import androidx.appactions.interaction.capabilities.core.impl.utils.LoggerInternal;
-import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
-import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.FulfillmentValue;
-import androidx.appactions.interaction.proto.FulfillmentResponse;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * The implementation of the {@link ActionCapability} interface.
- *
- * @param <PropertyT>
- * @param <ArgumentT>
- * @param <OutputT>
- */
-public final class ActionCapabilityImpl<PropertyT, ArgumentT, OutputT> implements ActionCapability {
-
-    private static final String LOG_TAG = "ActionCapability";
-    private final ActionSpec<PropertyT, ArgumentT, OutputT> mActionSpec;
-    private final Optional<String> mIdentifier;
-    private final PropertyT mProperty;
-    private final ActionExecutor<ArgumentT, OutputT> mActionExecutor;
-
-    public ActionCapabilityImpl(
-            @NonNull ActionSpec<PropertyT, ArgumentT, OutputT> actionSpec,
-            @NonNull Optional<String> identifier,
-            @NonNull PropertyT property,
-            @NonNull ActionExecutor<ArgumentT, OutputT> actionExecutor) {
-        this.mActionSpec = actionSpec;
-        this.mIdentifier = identifier;
-        this.mProperty = property;
-        this.mActionExecutor = actionExecutor;
-    }
-
-    @NonNull
-    @Override
-    public Optional<String> getId() {
-        return mIdentifier;
-    }
-
-    @NonNull
-    @Override
-    public AppAction getAppAction() {
-        AppAction appAction = mActionSpec.convertPropertyToProto(mProperty);
-        if (mIdentifier.isPresent()) {
-            appAction = appAction.toBuilder().setIdentifier(mIdentifier.get()).build();
-        }
-        return appAction;
-    }
-
-    @Override
-    public void execute(
-            @NonNull ArgumentsWrapper argumentsWrapper, @NonNull CallbackInternal callback) {
-        // Filter out the task parts of ArgumentsWrapper. Send the raw arguments for one-shot
-        // capabilities.
-        Map<String, List<ParamValue>> args =
-                argumentsWrapper.paramValues().entrySet().stream()
-                        .collect(
-                                toImmutableMap(
-                                        Map.Entry::getKey,
-                                        e ->
-                                                e.getValue().stream()
-                                                        .filter(FulfillmentValue::hasValue)
-                                                        .map(FulfillmentValue::getValue)
-                                                        .collect(toImmutableList())));
-        try {
-            Futures.addCallback(
-                    mActionExecutor.execute(mActionSpec.buildArgument(args)),
-                    new FutureCallback<ExecutionResult<OutputT>>() {
-                        @Override
-                        public void onSuccess(ExecutionResult<OutputT> executionResult) {
-                            callback.onSuccess(convertToFulfillmentResponse(executionResult));
-                        }
-
-                        @Override
-                        public void onFailure(Throwable t) {
-                            callback.onError(ErrorStatusInternal.CANCELLED);
-                        }
-                    },
-                    Runnable::run);
-        } catch (StructConversionException e) {
-            if (e.getMessage() != null) {
-                LoggerInternal.log(CapabilityLogger.LogLevel.ERROR, LOG_TAG, e.getMessage());
-            }
-            callback.onError(ErrorStatusInternal.STRUCT_CONVERSION_FAILURE);
-        }
-    }
-
-    /** Converts typed {@link ExecutionResult} to {@link FulfillmentResponse} proto. */
-    FulfillmentResponse convertToFulfillmentResponse(ExecutionResult<OutputT> executionResult) {
-        FulfillmentResponse.Builder fulfillmentResponseBuilder =
-                FulfillmentResponse.newBuilder()
-                        .setStartDictation(executionResult.getStartDictation());
-        OutputT output = executionResult.getOutput();
-        if (output != null && !(output instanceof Void)) {
-            fulfillmentResponseBuilder.setExecutionOutput(mActionSpec.convertOutputToProto(output));
-        }
-        return fulfillmentResponseBuilder.build();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java
index de3aa6a..1c427d1 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java
@@ -33,7 +33,7 @@
 
 /** The implementation of {@code ActionSpec} interface. */
 final class ActionSpecImpl<
-        PropertyT, ArgumentT, ArgumentBuilderT extends BuilderOf<ArgumentT>, OutputT>
+                PropertyT, ArgumentT, ArgumentBuilderT extends BuilderOf<ArgumentT>, OutputT>
         implements ActionSpec<PropertyT, ArgumentT, OutputT> {
 
     private final String mCapabilityName;
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/properties/Entity.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/properties/Entity.java
deleted file mode 100644
index a40eae1..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/properties/Entity.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.properties;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Entities are used when defining ActionCapability for defining possible values for ParamProperty.
- */
-public final class Entity {
-    private final Optional<String> mId;
-    private final Optional<String> mName;
-    private final List<String> mAlternateNames;
-
-    private Entity(Builder builder) {
-        this.mId = builder.mId;
-        this.mName = builder.mName;
-        this.mAlternateNames = builder.mAlternateNames;
-    }
-
-    /** Returns a new Builder to build an Entity instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new Builder();
-    }
-
-    /** The id of this Entity. */
-    @NonNull
-    public Optional<String> getId() {
-        return mId;
-    }
-
-    /** The name of this entity. The name is what a user may say to refer to this Entity. */
-    @NonNull
-    public Optional<String> getName() {
-        return mName;
-    }
-
-    /**
-     * The alternate names of this entity. These are alternate names a user may say to refer to
-     * this
-     * Entity.
-     */
-    @NonNull
-    public List<String> getAlternateNames() {
-        if (mAlternateNames == null) {
-            return Collections.emptyList();
-        }
-        return mAlternateNames;
-    }
-
-    /** Builder class for Entity. */
-    public static class Builder {
-        private Optional<String> mId = Optional.empty();
-        private Optional<String> mName = Optional.empty();
-        private @Nullable List<String> mAlternateNames = null;
-
-        /** Sets the id of the Entity to be built. */
-        @NonNull
-        public Builder setId(@NonNull String id) {
-            this.mId = Optional.of(id);
-            return this;
-        }
-
-        /** Sets the name of the Entity to be built. */
-        @NonNull
-        public Builder setName(@NonNull String name) {
-            this.mName = Optional.of(name);
-            return this;
-        }
-
-        /** Sets the list of alternate names of the Entity to be built. */
-        @NonNull
-        public Builder setAlternateNames(@NonNull List<String> alternateNames) {
-            this.mAlternateNames = alternateNames;
-            return this;
-        }
-
-        /** Sets the list of alternate names of the Entity to be built. */
-        @NonNull
-        public final Builder setAlternateNames(@NonNull String... alternateNames) {
-            return setAlternateNames(Collections.unmodifiableList(Arrays.asList(alternateNames)));
-        }
-
-        /** Builds and returns an Entity. */
-        @NonNull
-        public Entity build() {
-            return new Entity(this);
-        }
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/properties/Entity.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/properties/Entity.kt
new file mode 100644
index 0000000..08946cb
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/properties/Entity.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.properties
+
+/**
+ * Entities are used when defining ActionCapability for defining possible values for ParamProperty.
+ */
+class Entity internal constructor(
+    val id: String?,
+    val name: String,
+    val alternateNames: List<String>,
+) {
+    /** Builder class for Entity. */
+    class Builder {
+        private var id: String? = null
+        private var name: String? = null
+        private var alternateNames: List<String> = listOf()
+
+        /** Sets the id of the Entity to be built. */
+        fun setId(id: String) = apply {
+            this.id = id
+        }
+
+        /** Sets the name of the Entity to be built. */
+        fun setName(name: String) = apply {
+            this.name = name
+        }
+
+        /** Sets the list of alternate names of the Entity to be built. */
+
+        fun setAlternateNames(alternateNames: List<String>) = apply {
+            this.alternateNames = alternateNames
+        }
+
+        /** Sets the list of alternate names of the Entity to be built. */
+
+        fun setAlternateNames(vararg alternateNames: String) = setAlternateNames(
+            alternateNames.asList(),
+        )
+
+        /** Builds and returns an Entity. */
+        fun build() = Entity(
+            id,
+            requireNotNull(name, {
+                "setName must be called before build"
+            }),
+            alternateNames,
+        )
+    }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImpl.java
index 2655700..c3e46f2 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImpl.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImpl.java
@@ -19,6 +19,7 @@
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
 import androidx.appactions.interaction.capabilities.core.ActionCapability;
 import androidx.appactions.interaction.capabilities.core.impl.ArgumentsWrapper;
 import androidx.appactions.interaction.capabilities.core.impl.CallbackInternal;
@@ -47,7 +48,9 @@
  * @param <OutputT>
  * @param <ConfirmationT>
  * @param <TaskUpdaterT>
+ * @hide
  */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
 public final class TaskCapabilityImpl<
                 PropertyT,
                 ArgumentT,
@@ -104,8 +107,13 @@
 
     @NonNull
     @Override
-    public Optional<String> getId() {
-        return Optional.of(mIdentifier);
+    public String getId() {
+        return mIdentifier;
+    }
+
+    @Override
+    public boolean getSupportsMultiTurnTask() {
+        return true;
     }
 
     public void setTaskUpdaterSupplier(@NonNull Supplier<TaskUpdaterT> taskUpdaterSupplier) {
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
new file mode 100644
index 0000000..2082eb6
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.impl
+
+import android.util.SizeF
+import androidx.appactions.interaction.capabilities.core.ActionCapability
+import androidx.appactions.interaction.capabilities.core.ExecutionResult
+import androidx.appactions.interaction.capabilities.core.HostProperties
+import androidx.appactions.interaction.capabilities.core.impl.concurrent.Futures
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
+import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec
+import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
+import androidx.appactions.interaction.capabilities.core.properties.EntityProperty
+import androidx.appactions.interaction.capabilities.core.properties.StringProperty
+import androidx.appactions.interaction.capabilities.core.testing.ArgumentUtils
+import androidx.appactions.interaction.capabilities.core.testing.spec.Argument
+import androidx.appactions.interaction.capabilities.core.testing.spec.Output
+import androidx.appactions.interaction.capabilities.core.testing.spec.Property
+import androidx.appactions.interaction.capabilities.core.testing.spec.Session
+import androidx.appactions.interaction.proto.FulfillmentResponse
+import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput
+import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput.OutputValue
+import androidx.appactions.interaction.proto.ParamValue
+import com.google.common.util.concurrent.ListenableFuture
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.mock
+
+@RunWith(JUnit4::class)
+class SingleTurnCapabilityTest {
+
+    val mockCalback: CallbackInternal = mock()
+
+    @Test
+    fun oneShotCapability_successWithOutput() {
+        val capability: ActionCapability =
+            SingleTurnCapabilityImpl<Property, Argument, Output>(
+                "capabilityId",
+                ACTION_SPEC,
+                Property.newBuilder().setRequiredEntityField(
+                    EntityProperty.EMPTY,
+                ).setOptionalStringField(
+                    StringProperty.PROHIBITED,
+                ).build(),
+                {
+                    object : Session {
+                        override fun onFinishAsync(
+                            argument: Argument,
+                        ): ListenableFuture<ExecutionResult<Output>> {
+                            return Futures.immediateFuture(
+                                ExecutionResult.Builder<Output>().setOutput(
+                                    Output.builder().setOptionalStringField("stringOutput")
+                                        .build(),
+                                ).build(),
+                            )
+                        }
+                    }
+                },
+            )
+        val expectedFulfillmentResponse: FulfillmentResponse =
+            FulfillmentResponse.newBuilder().setExecutionOutput(
+                StructuredOutput.newBuilder()
+                    .addOutputValues(
+                        OutputValue.newBuilder()
+                            .setName("optionalStringOutput")
+                            .addValues(
+                                ParamValue.newBuilder()
+                                    .setStringValue("stringOutput")
+                                    .build(),
+                            )
+                            .build(),
+                    )
+                    .build(),
+            ).build()
+
+        val capabilitySession = capability.createSession(
+            HostProperties.Builder().setMaxHostSizeDp(SizeF(300f, 500f)).build(),
+        )
+        capabilitySession.execute(
+            ArgumentUtils.buildArgs(
+                mapOf(
+                    "optionalString" to ParamValue.newBuilder().setIdentifier(
+                        "string argument value",
+                    ).build(),
+                ),
+            ),
+            mockCalback,
+        )
+
+        verify(mockCalback).onSuccess(expectedFulfillmentResponse)
+    }
+
+    companion object {
+        val ACTION_SPEC: ActionSpec<Property, Argument, Output> =
+            ActionSpecBuilder.ofCapabilityNamed(
+                "actions.intent.TEST",
+            )
+                .setDescriptor(Property::class.java)
+                .setArgument(Argument::class.java, Argument::newBuilder)
+                .setOutput(Output::class.java)
+                .bindOptionalStringParameter(
+                    "optionalString",
+                    Property::optionalStringField,
+                    Argument.Builder::setOptionalStringField,
+                )
+                .bindOptionalOutput(
+                    "optionalStringOutput",
+                    Output::optionalStringField,
+                    TypeConverters::toParamValue,
+                ).build()
+    }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionCapabilityImplTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionCapabilityImplTest.java
deleted file mode 100644
index f057569..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionCapabilityImplTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-
-import androidx.appactions.interaction.capabilities.core.ExecutionResult;
-import androidx.appactions.interaction.capabilities.core.impl.ArgumentsWrapper;
-import androidx.appactions.interaction.capabilities.core.impl.CallbackInternal;
-import androidx.appactions.interaction.capabilities.core.impl.concurrent.Futures;
-import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters;
-import androidx.appactions.interaction.capabilities.core.properties.EntityProperty;
-import androidx.appactions.interaction.capabilities.core.testing.spec.Argument;
-import androidx.appactions.interaction.capabilities.core.testing.spec.Output;
-import androidx.appactions.interaction.capabilities.core.testing.spec.Property;
-import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment;
-import androidx.appactions.interaction.proto.FulfillmentResponse;
-import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput;
-import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput.OutputValue;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.List;
-import java.util.Optional;
-
-@RunWith(JUnit4.class)
-public final class ActionCapabilityImplTest {
-
-    private static final ActionSpec<Property, Argument, Output> ACTION_SPEC =
-            ActionSpecBuilder.ofCapabilityNamed("actions.intent.TEST")
-                    .setDescriptor(Property.class)
-                    .setArgument(Argument.class, Argument::newBuilder)
-                    .setOutput(Output.class)
-                    .bindRequiredEntityParameter(
-                            "requiredEntity",
-                            Property::requiredEntityField,
-                            Argument.Builder::setRequiredEntityField)
-                    .bindOptionalOutput(
-                            "optionalStringOutput",
-                            Output::optionalStringField,
-                            TypeConverters::toParamValue)
-                    .bindRepeatedOutput(
-                            "repeatedStringOutput",
-                            Output::repeatedStringField,
-                            TypeConverters::toParamValue)
-                    .build();
-    @Rule public final MockitoRule mockito = MockitoJUnit.rule();
-    @Captor ArgumentCaptor<FulfillmentResponse> mCaptor;
-    @Mock private CallbackInternal mCallbackInternal;
-
-    @Test
-    @SuppressWarnings("JdkImmutableCollections")
-    public void execute_convertExecutionResult() {
-        Property property =
-                Property.newBuilder()
-                        .setRequiredEntityField(EntityProperty.newBuilder().build())
-                        .build();
-
-        ExecutionResult<Output> executionResult =
-                new ExecutionResult.Builder<Output>()
-                        .setOutput(
-                                Output.builder()
-                                        .setOptionalStringField("test2")
-                                        .setRepeatedStringField(List.of("test3", "test4"))
-                                        .build())
-                        .build();
-        ActionCapabilityImpl<Property, Argument, Output> capability =
-                new ActionCapabilityImpl<>(
-                        ACTION_SPEC,
-                        Optional.of("id"),
-                        property,
-                        (argument) -> Futures.immediateFuture(executionResult));
-        StructuredOutput expectedExecutionOutput =
-                StructuredOutput.newBuilder()
-                        .addOutputValues(
-                                OutputValue.newBuilder()
-                                        .setName("optionalStringOutput")
-                                        .addValues(
-                                                ParamValue.newBuilder()
-                                                        .setStringValue("test2")
-                                                        .build())
-                                        .build())
-                        .addOutputValues(
-                                OutputValue.newBuilder()
-                                        .setName("repeatedStringOutput")
-                                        .addValues(
-                                                ParamValue.newBuilder()
-                                                        .setStringValue("test3")
-                                                        .build())
-                                        .addValues(
-                                                ParamValue.newBuilder()
-                                                        .setStringValue("test4")
-                                                        .build())
-                                        .build())
-                        .build();
-
-        capability.execute(
-                ArgumentsWrapper.create(Fulfillment.getDefaultInstance()), mCallbackInternal);
-
-        verify(mCallbackInternal).onSuccess(mCaptor.capture());
-        assertThat(mCaptor.getValue().getExecutionOutput().getOutputValuesList())
-                .containsExactlyElementsIn(expectedExecutionOutput.getOutputValuesList());
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
index 341351f..05a49f5 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
@@ -19,15 +19,12 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.ActionCapability;
-import androidx.appactions.interaction.capabilities.core.ActionExecutor;
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters;
 import androidx.appactions.interaction.capabilities.core.properties.Entity;
 import androidx.appactions.interaction.capabilities.core.properties.EntityProperty;
 import androidx.appactions.interaction.capabilities.core.properties.EnumProperty;
 import androidx.appactions.interaction.capabilities.core.properties.StringProperty;
-import androidx.appactions.interaction.capabilities.core.testing.TestingUtils;
 import androidx.appactions.interaction.capabilities.core.testing.spec.Output;
 import androidx.appactions.interaction.capabilities.core.values.EntityValue;
 import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
@@ -92,18 +89,13 @@
                             TypeConverters::toParamValue)
                     .build();
 
-    private static ActionCapability createCapability(
-            String id, Property property, ActionExecutor<Argument, Output> executor) {
-        return new ActionCapabilityImpl<>(ACTION_SPEC, Optional.of(id), property, executor);
-    }
-
     @Test
     public void getAppAction_onlyRequiredProperty() {
         Property property =
                 Property.create(
                         EntityProperty.newBuilder()
                                 .addPossibleEntity(
-                                        Entity.newBuilder()
+                                        new Entity.Builder()
                                                 .setId("contact_2")
                                                 .setName("Donald")
                                                 .setAlternateNames("Duck")
@@ -112,13 +104,9 @@
                                 .build(),
                         StringProperty.EMPTY);
 
-        ActionCapability capability =
-                        createCapability("id", property, TestingUtils.createFakeActionExecutor());
-
-        assertThat(capability.getAppAction())
+        assertThat(ACTION_SPEC.convertPropertyToProto(property))
                 .isEqualTo(
                         AppAction.newBuilder()
-                                .setIdentifier("id")
                                 .setName("actions.intent.TEST")
                                 .addParams(
                                         IntentParameter.newBuilder()
@@ -142,7 +130,7 @@
                 Property.create(
                         EntityProperty.newBuilder()
                                 .addPossibleEntity(
-                                        Entity.newBuilder()
+                                        new Entity.Builder()
                                                 .setId("contact_2")
                                                 .setName("Donald")
                                                 .setAlternateNames("Duck")
@@ -151,7 +139,7 @@
                         Optional.of(
                                 EntityProperty.newBuilder()
                                         .addPossibleEntity(
-                                                Entity.newBuilder()
+                                                new Entity.Builder()
                                                         .setId("entity1")
                                                         .setName("optional possible entity")
                                                         .build())
@@ -165,12 +153,12 @@
                         Optional.of(
                                 EntityProperty.newBuilder()
                                         .addPossibleEntity(
-                                                Entity.newBuilder()
+                                                new Entity.Builder()
                                                         .setId("entity1")
                                                         .setName("repeated entity1")
                                                         .build())
                                         .addPossibleEntity(
-                                                Entity.newBuilder()
+                                                new Entity.Builder()
                                                         .setId("entity2")
                                                         .setName("repeated entity2")
                                                         .build())
@@ -185,13 +173,9 @@
                                         .build()),
                         Optional.of(StringProperty.PROHIBITED));
 
-        ActionCapability capability =
-                        createCapability("id", property, TestingUtils.createFakeActionExecutor());
-
-        assertThat(capability.getAppAction())
+        assertThat(ACTION_SPEC.convertPropertyToProto(property))
                 .isEqualTo(
                         AppAction.newBuilder()
-                                .setIdentifier("id")
                                 .setName("actions.intent.TEST")
                                 .addParams(
                                         IntentParameter.newBuilder()
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.java
index c18a61a..5464ff6 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.java
@@ -18,6 +18,7 @@
 
 import com.google.auto.value.AutoValue;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
@@ -26,12 +27,11 @@
 public abstract class Output {
 
     public static Builder builder() {
-        return new AutoValue_Output.Builder();
+        return new AutoValue_Output.Builder().setRepeatedStringField(Collections.emptyList());
     }
 
     public abstract Optional<String> optionalStringField();
 
-    @SuppressWarnings("AutoValueImmutableFields")
     public abstract List<String> repeatedStringField();
 
     @AutoValue.Builder
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Session.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Session.kt
new file mode 100644
index 0000000..60de640
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Session.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2023 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+import androidx.appactions.interaction.capabilities.core.BaseSession
+
+interface Session : BaseSession<Argument, Output>
\ No newline at end of file
diff --git a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppInteractionService.java b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppInteractionService.java
index 47cca71..41df1b9 100644
--- a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppInteractionService.java
+++ b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppInteractionService.java
@@ -23,6 +23,7 @@
 
 import androidx.annotation.CallSuper;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appactions.interaction.capabilities.core.ActionCapability;
 import androidx.appactions.interaction.service.proto.AppActionsServiceGrpc;
 
@@ -135,7 +136,7 @@
 
     @Override
     @NonNull
-    public IBinder onBind(Intent intent) {
+    public IBinder onBind(@Nullable Intent intent) {
         return mBinderSupplier.get();
     }
 
diff --git a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppVerificationInfo.kt b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppVerificationInfo.kt
index 56ca2a4..90af3ce 100644
--- a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppVerificationInfo.kt
+++ b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/AppVerificationInfo.kt
@@ -47,7 +47,11 @@
         /** Set the packageName that will be part of the [AppVerificationInfo] */
         fun addSignature(signatures: List<ByteArray>) = apply { this.signatures = signatures }
 
-        /** Creates a new instance of [AppVerificationInfo] */
+        /**
+         * Creates a new instance of [AppVerificationInfo]
+         *
+         * @Throws IllegalArgumentException if packageName is null or signatures are empty.
+         */
         fun build(): AppVerificationInfo {
             if (packageName == null) {
                 throw IllegalArgumentException("App verification info packageName is missing.")
diff --git a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiResponse.kt b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiResponse.kt
index 37a4387..c118e72 100644
--- a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiResponse.kt
+++ b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiResponse.kt
@@ -16,6 +16,7 @@
 
 package androidx.appactions.interaction.service
 
+import android.annotation.SuppressLint
 import android.util.SizeF
 import android.widget.RemoteViews
 import android.widget.RemoteViewsService.RemoteViewsFactory
@@ -54,6 +55,7 @@
          * @param layout the wear-tile [LayoutElementBuilders.Layout] to be displayed.
          * @param resources the resources associated with the layout.
          */
+        @SuppressLint("MissingGetterMatchingBuilder")
         fun setTileLayout(
             layout: LayoutElementBuilders.Layout,
             resources: ResourceBuilders.Resources
@@ -80,6 +82,7 @@
          * @param remoteViews the `RemoteViews` to be displayed
          * @param size the size, in dp, of the RemoteViews being displayed
          */
+        @SuppressLint("MissingGetterMatchingBuilder")
         fun setRemoteViews(remoteViews: RemoteViews, size: SizeF?): RemoteViewsUiBuilder {
             this.remoteViews = remoteViews
             this.size = size
@@ -92,6 +95,7 @@
          * Any errors resulting from the provided view IDs will contain "RemoteViewsCollection
          * error: " errors with some message from the host.
          */
+        @SuppressLint("MissingGetterMatchingBuilder")
         fun addViewIdForCollectionUpdate(@IdRes viewId: Int): RemoteViewsUiBuilder {
             changedViewIds.add(viewId)
             return this
@@ -105,6 +109,7 @@
          * @param viewId the id of the collection view
          * @param factory a RemoteViewsFactory associated with the collection view
          */
+        @SuppressLint("MissingGetterMatchingBuilder")
         fun addRemoteViewsFactory(
             @IdRes viewId: Int,
             factory: RemoteViewsFactory
diff --git a/appcompat/appcompat-lint/integration-tests/OWNERS b/appcompat/appcompat-lint/integration-tests/OWNERS
index 7928c5c..97d8080 100644
--- a/appcompat/appcompat-lint/integration-tests/OWNERS
+++ b/appcompat/appcompat-lint/integration-tests/OWNERS
@@ -1,2 +1,2 @@
-# Bug components: 461199
+# Bug component: 461199
 [email protected]
diff --git a/appcompat/appcompat-lint/src/main/kotlin/androidx/appcompat/AppCompatIssueRegistry.kt b/appcompat/appcompat-lint/src/main/kotlin/androidx/appcompat/AppCompatIssueRegistry.kt
index 65f052b..ffb51ab 100644
--- a/appcompat/appcompat-lint/src/main/kotlin/androidx/appcompat/AppCompatIssueRegistry.kt
+++ b/appcompat/appcompat-lint/src/main/kotlin/androidx/appcompat/AppCompatIssueRegistry.kt
@@ -32,7 +32,7 @@
 @Suppress("UnstableApiUsage")
 class AppCompatIssueRegistry : IssueRegistry() {
     override val minApi = 10 // Only compatible with the latest lint
-    override val api = 14
+    override val api = 13
     override val issues get() = listOf(
         SetActionBarDetector.USING_CORE_ACTION_BAR,
         ColorStateListAlphaDetector.NOT_USING_ANDROID_ALPHA,
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java
index cdb54ca..9f951fd 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java
@@ -452,9 +452,6 @@
 
     /**
      * Returns whether the {@link Features#NUMERIC_SEARCH} feature is enabled.
-     *
-     * TODO(b/259744228): add more documentation about the numeric search feature and when it
-     * needs to be enabled.
      */
     public boolean isNumericSearchEnabled() {
         return getEnabledFeatures().contains(Features.NUMERIC_SEARCH);
@@ -462,9 +459,6 @@
 
     /**
      * Returns whether the {@link Features#VERBATIM_SEARCH} feature is enabled.
-     *
-     * TODO(b/204333391): add more documentation about the verbatim search feature and when it
-     * needs to be enabled.
      */
     public boolean isVerbatimSearchEnabled() {
         return getEnabledFeatures().contains(Features.VERBATIM_SEARCH);
@@ -472,9 +466,6 @@
 
     /**
      * Returns whether the {@link Features#LIST_FILTER_QUERY_LANGUAGE} feature is enabled.
-     *
-     * TODO(b/208654892): add more documentation about the list filter query language feature and
-     * when it needs to be enabled.
      */
     public boolean isListFilterQueryLanguageEnabled() {
         return getEnabledFeatures().contains(Features.LIST_FILTER_QUERY_LANGUAGE);
@@ -1283,8 +1274,9 @@
          *
          * @param enabled Enables the feature if true, otherwise disables it.
          *
-         * TODO(b/259744228): add more documentation about the numeric search feature and when it
-         *               needs to be enabled.
+         * <p>If disabled, disallows use of
+         * {@link AppSearchSchema.LongPropertyConfig#INDEXING_TYPE_RANGE} and all other numeric
+         * querying features.
          */
         // @exportToFramework:startStrip()
         @RequiresFeature(
@@ -1303,8 +1295,13 @@
          *
          * @param enabled Enables the feature if true, otherwise disables it
          *
-         * TODO(b/204333391): add more documentation about the verbatim search feature and when
-         *                it needs to be enabled.
+         * <p>If disabled, disallows use of
+         * {@link AppSearchSchema.StringPropertyConfig#TOKENIZER_TYPE_VERBATIM} and all other
+         * verbatim search features within the query language that allows clients to search
+         * using the verbatim string operator.
+         *
+         * <p>Ex. The verbatim string operator '"foo/bar" OR baz' will ensure that 'foo/bar' is
+         * treated as a single 'verbatim' token.
          */
         // @exportToFramework:startStrip()
         @RequiresFeature(
@@ -1323,8 +1320,28 @@
          *
          * @param enabled Enables the feature if true, otherwise disables it.
          *
-         * TODO(b/208654892): add more documentation about the list filter query language feature
-         *               and when it needs to be enabled.
+         * This feature covers the expansion of the query language to conform to the definition
+         * of the list filters language (https://aip.dev/160). This includes:
+         * <ul>
+         * <li>addition of explicit 'AND' and 'NOT' operators</li>
+         * <li>property restricts are allowed with grouping (ex. "prop:(a OR b)")</li>
+         * <li>addition of custom functions to control matching</li>
+         * </ul>
+         *
+         * <p>The newly added custom functions covered by this feature are:
+         * <ul>
+         * <li>createList(String...)</li>
+         * <li>termSearch(String, List<String>)</li>
+         * </ul>
+         *
+         * <p>createList takes a variable number of strings and returns a list of strings.
+         * It is for use with termSearch.
+         *
+         * <p>termSearch takes a query string that will be parsed according to the supported
+         * query language and an optional list of strings that specify the properties to be
+         * restricted to. This exists as a convenience for multiple property restricts. So,
+         * for example, the query "(subject:foo OR body:foo) (subject:bar OR body:bar)"
+         * could be rewritten as "termSearch(\"foo bar\", createList(\"subject\", \"bar\"))"
          */
         // @exportToFramework:startStrip()
         @RequiresFeature(
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
index 65ac589..c2348b5 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
@@ -47,7 +47,7 @@
 import org.junit.runners.Parameterized
 import org.junit.runners.Parameterized.Parameters
 
-private const val tracingPerfettoVersion = "1.0.0-alpha10" // TODO(224510255): get by 'reflection'
+private const val tracingPerfettoVersion = "1.0.0-alpha11" // TODO(224510255): get by 'reflection'
 private const val minSupportedSdk = Build.VERSION_CODES.R // TODO(234351579): Support API < 30
 
 @RunWith(Parameterized::class)
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/metalava/UpdateApiTaskTest.kt b/buildSrc-tests/src/test/kotlin/androidx/build/metalava/UpdateApiTaskTest.kt
new file mode 100644
index 0000000..a502b62d
--- /dev/null
+++ b/buildSrc-tests/src/test/kotlin/androidx/build/metalava/UpdateApiTaskTest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2023 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 androidx.build.metalava
+
+import org.gradle.api.GradleException
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertThrows
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+
+class UpdateApiTaskTest {
+    @Rule
+    @JvmField
+    val tmpFolder = TemporaryFolder()
+
+    @Test
+    fun testCompareLineCount() {
+        val testCases = mapOf(
+            "No lines" to 0,
+            "Has one\nline" to 1,
+            "Has\ntwo\nlines" to 2,
+            "" to 0,
+            "\n" to 1,
+            "\n\n" to 2
+        )
+
+        for ((text, count) in testCases) {
+            assertEquals(compareLineCount(text, count), 0)
+        }
+    }
+
+    @Test
+    fun testCopyThrowsExceptionOnDiff() {
+        val source = tmpFolder.newFile().apply {
+            writeText("""
+// Signature format: 4.0
+            """.trimIndent())
+        }
+        val dest = tmpFolder.newFile().apply {
+            writeText("""
+// Signature format: 4.0
+package androidx.core.accessibilityservice {
+  public final class AccessibilityServiceInfoCompat {
+    method public static String capabilityToString(int);
+  }
+}
+            """.trimIndent())
+        }
+
+        assertThrows(GradleException::class.java) {
+            copy(source, dest, false)
+        }
+    }
+}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt
index a81686a..328350a 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt
@@ -48,7 +48,7 @@
         val outputFile = File(outputDir.get().asFile, relativePath.get())
         outputFile.parentFile.mkdirs()
         val writer = PrintWriter(outputFile)
-        writer.println(version)
+        writer.println(version.get())
         writer.close()
     }
 }
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
index f3a8727..d827a8d 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
@@ -81,7 +81,11 @@
     }
 }
 
-private fun summarizeDiff(a: File, b: File): String {
+/**
+ * Returns the output of running the `diff` command-line tool on files [a] and [b], truncated to
+ * [maxSummaryLines] lines.
+ */
+fun summarizeDiff(a: File, b: File, maxSummaryLines: Int = 50): String {
     if (!a.exists()) {
         return "$a does not exist"
     }
@@ -93,7 +97,6 @@
         .start()
     process.waitFor(5, TimeUnit.SECONDS)
     var diffLines = process.inputStream.bufferedReader().readLines().toMutableList()
-    val maxSummaryLines = 50
     if (diffLines.size > maxSummaryLines) {
         diffLines = diffLines.subList(0, maxSummaryLines)
         diffLines.plusAssign("[long diff was truncated]")
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateApiTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateApiTask.kt
index 80a4c17..0286efc 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateApiTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateApiTask.kt
@@ -150,7 +150,7 @@
     source: File,
     dest: File,
     permitOverwriting: Boolean,
-    logger: Logger
+    logger: Logger? = null
 ) {
     val sourceText = if (source.exists()) {
         source.readText()
@@ -161,11 +161,18 @@
     val changing = overwriting || (dest.exists() != source.exists())
     if (changing) {
         if (overwriting && !permitOverwriting) {
+            val diff = summarizeDiff(source, dest, maxDiffLines + 1)
+            val diffMsg = if (compareLineCount(diff, maxDiffLines) > 0) {
+                "Diff is greater than $maxDiffLines lines, use diff tool to compare.\n\n"
+            } else {
+                "Diff:\n$diff\n\n"
+            }
             val message = "Modifying the API definition for a previously released artifact " +
                 "having a final API version (version not ending in '-alpha') is not " +
                 "allowed.\n\n" +
                 "Previously declared definition is $dest\n" +
                 "Current generated   definition is $source\n\n" +
+                diffMsg +
                 "Did you mean to increment the library version first?\n\n" +
                 "If you have a valid reason to override Semantic Versioning policy, see " +
                 "go/androidx/versioning#beta-api-change for information on obtaining approval."
@@ -174,10 +181,37 @@
         if (source.exists()) {
             @Suppress("UnstableApiUsage")
             Files.copy(source, dest)
-            logger.lifecycle("Copied $source to $dest")
+            logger?.lifecycle("Copied $source to $dest")
         } else {
             dest.delete()
-            logger.lifecycle("Deleted $dest because $source does not exist")
+            logger?.lifecycle("Deleted $dest because $source does not exist")
         }
     }
 }
+
+/**
+ * Returns -1 if [text] has fewer than [count] newline characters, 0 if equal, and 1 if greater
+ * than.
+ */
+fun compareLineCount(text: String, count: Int): Int {
+    var found = 0
+    var index = 0
+    while (found < count) {
+        index = text.indexOf('\n', index)
+        if (index < 0) {
+            break
+        }
+        found++
+        index++
+    }
+    return if (found < count) {
+        -1
+    } else if (found == count) {
+        0
+    } else {
+        1
+    }
+}
+
+/** Maximum number of diff lines to include in output. */
+internal const val maxDiffLines = 8
diff --git a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/EncoderProfilesProviderAdapterDeviceTest.kt b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/EncoderProfilesProviderAdapterDeviceTest.kt
index c61aa16..5d6c9c4 100644
--- a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/EncoderProfilesProviderAdapterDeviceTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/EncoderProfilesProviderAdapterDeviceTest.kt
@@ -21,6 +21,8 @@
 import android.media.EncoderProfiles.VideoProfile.YUV_420
 import android.os.Build
 import androidx.camera.camera2.pipe.integration.adapter.EncoderProfilesProviderAdapter
+import androidx.camera.camera2.pipe.integration.compat.quirk.DeviceQuirks
+import androidx.camera.camera2.pipe.integration.compat.quirk.InvalidVideoProfilesQuirk
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy.BIT_DEPTH_8
 import androidx.camera.testing.CameraUtil
@@ -68,7 +70,6 @@
 
     @Before
     fun setup() {
-        skipTestOnProblematicBuildsOfCuttlefishApi33()
         Assume.assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK))
 
         cameraId = CameraUtil.getCameraIdWithLensFacing(CameraSelector.LENS_FACING_BACK)!!
@@ -156,6 +157,7 @@
     @Test
     fun afterApi33_hasSameContentAsEncoderProfiles() {
         Assume.assumeTrue(CamcorderProfile.hasProfile(quality))
+        skipTestOnDevicesWithProblematicBuild()
 
         val profiles = CamcorderProfile.getAll(cameraId, quality)
         val video = profiles!!.videoProfiles[0]
@@ -184,13 +186,14 @@
         assertThat(audioProxy.profile).isEqualTo(audio.profile)
     }
 
-    // TODO: removes after b/265613005 is fixed
-    private fun skipTestOnProblematicBuildsOfCuttlefishApi33() {
-        // Skip test for b/265613005
+    private fun skipTestOnDevicesWithProblematicBuild() {
+        // Skip test for b/265613005 and b/223439995
+        val hasVideoProfilesQuirk = DeviceQuirks[InvalidVideoProfilesQuirk::class.java] != null
+        val isProblematicCuttlefishBuild =
+            Build.MODEL.contains("Cuttlefish") && Build.ID.startsWith("TP1A")
         Assume.assumeFalse(
-            "Cuttlefish has null VideoProfile issue. Unable to test.",
-            Build.MODEL.contains("Cuttlefish") && Build.VERSION.SDK_INT == 33 &&
-                Build.ID.startsWith("TP1A")
+            "Skip test with null VideoProfile issue. Unable to test.",
+            hasVideoProfilesQuirk || isProblematicCuttlefishBuild
         )
     }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/UseCaseSurfaceManagerDeviceTest.kt b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/UseCaseSurfaceManagerDeviceTest.kt
index 65e72dc..b6ba0b18 100644
--- a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/UseCaseSurfaceManagerDeviceTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/UseCaseSurfaceManagerDeviceTest.kt
@@ -41,11 +41,9 @@
 import androidx.camera.testing.activity.Camera2TestActivity
 import androidx.camera.testing.fakes.FakeUseCase
 import androidx.camera.testing.fakes.FakeUseCaseConfig
-import androidx.camera.testing.waitForIdle
 import androidx.core.os.HandlerCompat
 import androidx.test.core.app.ActivityScenario
 import androidx.test.core.app.ApplicationProvider
-import androidx.test.espresso.IdlingResource
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
@@ -149,8 +147,15 @@
         assertThat(cameraClosedUsageCount).isEqualTo(1)
     }
 
+    /**
+     * This test launches another (test) Activity with the intention of taking away camera from the
+     * test itself. On Android T and above, we listen to onCameraAccessPrioritiesChanged() and
+     * retries opening the camera when the camera is disconnected. That means the test activity will
+     * no longer deterministically get the final camera access on Android T and above. As such, we
+     * set the maximum SDK version to S_V2.
+     */
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.M)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.M, maxSdkVersion = Build.VERSION_CODES.S_V2)
     fun disconnectOpenedCameraGraph_deferrableSurfaceUsageCountTest() = runBlocking {
         CoreAppTestUtil.prepareDeviceUI(InstrumentationRegistry.getInstrumentation())
 
@@ -194,9 +199,13 @@
                 putExtra(Camera2TestActivity.EXTRA_CAMERA_ID, cameraId)
             }
         ).use {
-            lateinit var previewReady: IdlingResource
-            it.onActivity { activity -> previewReady = activity.mPreviewReady!! }
-            previewReady.waitForIdle()
+            // TODO(b/268768235): Under some conditions, it is possible that the camera gets
+            //  disconnected for both the foreground and test activity, before the preview has a
+            //  chance to be ready. Fix it with follow-up changes to change this test by using a
+            //  CameraGraphSimulator rather than a real CameraGraph.
+            // lateinit var previewReady: IdlingResource
+            // it.onActivity { activity -> previewReady = activity.mPreviewReady!! }
+            // previewReady.waitForIdle()
 
             cameraDisconnectedUsageCount = testSessionParameters.deferrableSurface.useCount
         }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CamcorderProfileProviderAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CamcorderProfileProviderAdapter.kt
deleted file mode 100644
index b75b73d..0000000
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CamcorderProfileProviderAdapter.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2022 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 androidx.camera.camera2.pipe.integration.adapter
-
-import android.media.CamcorderProfile
-import android.os.Build
-import androidx.annotation.Nullable
-import androidx.annotation.RequiresApi
-import androidx.camera.core.Logger
-import androidx.camera.core.impl.CamcorderProfileProvider
-import androidx.camera.core.impl.CamcorderProfileProxy
-
-/**
- * Adapt the [CamcorderProfileProvider] interface to [CameraPipe].
- */
-@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
-class CamcorderProfileProviderAdapter(cameraIdString: String) : CamcorderProfileProvider {
-    private val hasValidCameraId: Boolean
-    private val cameraId: Int
-
-    init {
-        var hasValidCameraId = false
-        var intCameraId = -1
-        try {
-            intCameraId = cameraIdString.toInt()
-            hasValidCameraId = true
-        } catch (e: NumberFormatException) {
-            Logger.w(
-                TAG,
-                "Camera id is not an integer: " +
-                    "$cameraIdString, unable to create CamcorderProfileProvider"
-            )
-        }
-        this.hasValidCameraId = hasValidCameraId
-        cameraId = intCameraId
-
-        // TODO(b/241296464): CamcorderProfileResolutionQuirk and CamcorderProfileResolutionValidator
-    }
-
-    override fun hasProfile(quality: Int): Boolean {
-        if (!hasValidCameraId) {
-            return false
-        }
-        return CamcorderProfile.hasProfile(cameraId, quality)
-        // TODO: b241296464 CamcorderProfileResolutionQuirk and
-        // CamcorderProfileResolutionValidator. If has quick, check if the proxy profile has
-        // valid video resolution
-    }
-
-    override fun get(quality: Int): CamcorderProfileProxy? {
-        if (!hasValidCameraId) {
-            return null
-        }
-        return if (!CamcorderProfile.hasProfile(cameraId, quality)) {
-            null
-        } else getProfileInternal(quality)
-        // TODO: b241296464 CamcorderProfileResolutionQuirk and
-        // CamcorderProfileResolutionValidator. If has quick, check if the proxy profile has
-        // valid video resolution
-    }
-
-    @Nullable
-    @Suppress("DEPRECATION")
-    private fun getProfileInternal(quality: Int): CamcorderProfileProxy? {
-        var profile: CamcorderProfile? = null
-        try {
-            profile = CamcorderProfile.get(cameraId, quality)
-        } catch (e: RuntimeException) {
-            // CamcorderProfile.get() will throw
-            // - RuntimeException if not able to retrieve camcorder profile params.
-            // - IllegalArgumentException if quality is not valid.
-            Logger.w(TAG, "Unable to get CamcorderProfile by quality: $quality", e)
-        }
-        return if (profile != null) CamcorderProfileProxy.fromCamcorderProfile(profile) else null
-    }
-
-    companion object {
-        private const val TAG = "CamcorderProfileProviderAdapter"
-    }
-}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraControlAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraControlAdapter.kt
index 9f5dbc4..50a01d6 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraControlAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraControlAdapter.kt
@@ -108,21 +108,19 @@
 
     override fun cancelFocusAndMetering(): ListenableFuture<Void> {
         return Futures.nonCancellationPropagating(
-            FutureChain.from(
-                focusMeteringControl.cancelFocusAndMeteringAsync().asListenableFuture()
-            ).transform(
-                Function { return@Function null }, CameraXExecutors.directExecutor()
-            )
+            threads.sequentialScope.async {
+                focusMeteringControl.cancelFocusAndMeteringAsync().join()
+                // Convert to null once the task is done, ignore the results.
+                return@async null
+            }.asListenableFuture()
         )
     }
 
     override fun setZoomRatio(ratio: Float): ListenableFuture<Void> =
-        zoomControl.setZoomRatioAsync(ratio)
+        zoomControl.setZoomRatio(ratio)
 
-    override fun setLinearZoom(linearZoom: Float): ListenableFuture<Void> {
-        val ratio = zoomControl.toZoomRatio(linearZoom)
-        return setZoomRatio(ratio)
-    }
+    override fun setLinearZoom(linearZoom: Float): ListenableFuture<Void> =
+        zoomControl.setLinearZoom(linearZoom)
 
     override fun getFlashMode(): Int {
         return flashControl.flashMode
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraFactoryAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraFactoryAdapter.kt
index c62c357..56257d4 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraFactoryAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraFactoryAdapter.kt
@@ -31,6 +31,7 @@
 import androidx.camera.camera2.pipe.integration.internal.CameraCompatibilityFilter
 import androidx.camera.camera2.pipe.integration.internal.CameraSelectionOptimizer
 import androidx.camera.core.CameraSelector
+import androidx.camera.core.concurrent.CameraCoordinator
 import androidx.camera.core.impl.CameraFactory
 import androidx.camera.core.impl.CameraInternal
 import androidx.camera.core.impl.CameraThreadConfig
@@ -88,5 +89,10 @@
         // Use a LinkedHashSet to preserve order
         LinkedHashSet(mAvailableCameraIds)
 
+    override fun getCameraCoordinator(): CameraCoordinator? {
+        // TODO(b/262772650): camera-pipe support for concurrent camera.
+        return null
+    }
+
     override fun getCameraManager(): Any? = appComponent
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
index 8e53e5c..1834af5 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
@@ -40,9 +40,9 @@
 import androidx.camera.core.ExposureState
 import androidx.camera.core.FocusMeteringAction
 import androidx.camera.core.ZoomState
-import androidx.camera.core.impl.CamcorderProfileProvider
 import androidx.camera.core.impl.CameraCaptureCallback
 import androidx.camera.core.impl.CameraInfoInternal
+import androidx.camera.core.impl.EncoderProfilesProvider
 import androidx.camera.core.impl.ImageFormatConstants
 import androidx.camera.core.impl.Quirks
 import androidx.camera.core.impl.Timebase
@@ -68,7 +68,7 @@
     private val cameraCallbackMap: CameraCallbackMap,
     private val focusMeteringControl: FocusMeteringControl
 ) : CameraInfoInternal {
-    private lateinit var camcorderProfileProviderAdapter: CamcorderProfileProviderAdapter
+    private lateinit var encoderProfilesProviderAdapter: EncoderProfilesProviderAdapter
     @OptIn(ExperimentalCamera2Interop::class)
     internal val camera2CameraInfo: Camera2CameraInfo by lazy {
         Camera2CameraInfo.create(cameraProperties)
@@ -127,11 +127,11 @@
 
     override fun getImplementationType(): String = "CameraPipe"
 
-    override fun getCamcorderProfileProvider(): CamcorderProfileProvider {
-        if (!::camcorderProfileProviderAdapter.isInitialized) {
-            camcorderProfileProviderAdapter = CamcorderProfileProviderAdapter(cameraId)
+    override fun getEncoderProfilesProvider(): EncoderProfilesProvider {
+        if (!::encoderProfilesProviderAdapter.isInitialized) {
+            encoderProfilesProviderAdapter = EncoderProfilesProviderAdapter(cameraId)
         }
-        return camcorderProfileProviderAdapter
+        return encoderProfilesProviderAdapter
     }
 
     override fun getTimebase(): Timebase {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt
index 4c03b51..9e84e9c 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt
@@ -65,7 +65,7 @@
                 SupportedSurfaceCombination(
                     context,
                     checkNotNull(cameraMetadata),
-                    CamcorderProfileProviderAdapter(cameraId)
+                    EncoderProfilesProviderAdapter(cameraId)
                 )
         }
     }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CoroutineAdapters.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CoroutineAdapters.kt
index 1e31588..491c696 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CoroutineAdapters.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CoroutineAdapters.kt
@@ -21,10 +21,11 @@
 import androidx.annotation.RequiresApi
 import androidx.concurrent.futures.CallbackToFutureAdapter
 import com.google.common.util.concurrent.ListenableFuture
+import java.util.concurrent.CancellationException
+import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
-import java.util.concurrent.CancellationException
 
 /**
  * Convert a job into a ListenableFuture<Void>.
@@ -75,4 +76,20 @@
             tag
         }
     return CallbackToFutureAdapter.getFuture(resolver)
+}
+
+@OptIn(ExperimentalCoroutinesApi::class)
+fun <T> Deferred<T>.propagateTo(destination: CompletableDeferred<T>) {
+    invokeOnCompletion {
+        if (it != null) {
+            if (it is CancellationException) {
+                destination.cancel(it)
+            } else {
+                destination.completeExceptionally(it)
+            }
+        } else {
+            // Ignore exceptions - This should never throw in this situation.
+            destination.complete(getCompleted())
+        }
+    }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/EncoderProfilesProviderAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/EncoderProfilesProviderAdapter.kt
index 224eeab..73addda 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/EncoderProfilesProviderAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/EncoderProfilesProviderAdapter.kt
@@ -22,6 +22,8 @@
 import androidx.annotation.DoNotInline
 import androidx.annotation.Nullable
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.integration.compat.quirk.DeviceQuirks
+import androidx.camera.camera2.pipe.integration.compat.quirk.InvalidVideoProfilesQuirk
 import androidx.camera.core.Logger
 import androidx.camera.core.impl.EncoderProfilesProvider
 import androidx.camera.core.impl.EncoderProfilesProxy
@@ -71,23 +73,44 @@
     }
 
     @Nullable
-    @Suppress("DEPRECATION")
     private fun getProfilesInternal(quality: Int): EncoderProfilesProxy? {
-        return if (Build.VERSION.SDK_INT >= 31) {
-            val profiles: EncoderProfiles? = Api31Impl.getAll(cameraIdString, quality)
-            if (profiles != null) EncoderProfilesProxyCompat.from(profiles) else null
-        } else {
-            var profile: CamcorderProfile? = null
-            try {
-                profile = CamcorderProfile.get(cameraId, quality)
-            } catch (e: RuntimeException) {
-                // CamcorderProfile.get() will throw
-                // - RuntimeException if not able to retrieve camcorder profile params.
-                // - IllegalArgumentException if quality is not valid.
-                Logger.w(TAG, "Unable to get CamcorderProfile by quality: $quality", e)
+        if (Build.VERSION.SDK_INT >= 31) {
+            val profiles: EncoderProfiles = Api31Impl.getAll(cameraIdString, quality) ?: return null
+
+            val isVideoProfilesInvalid = DeviceQuirks[InvalidVideoProfilesQuirk::class.java] != null
+            if (isVideoProfilesInvalid) {
+                Logger.d(
+                    TAG, "EncoderProfiles contains invalid video profiles, use " +
+                        "CamcorderProfile to create EncoderProfilesProxy."
+                )
+            } else {
+                try {
+                    return EncoderProfilesProxyCompat.from(profiles)
+                } catch (e: NullPointerException) {
+                    Logger.w(
+                        TAG, "Failed to create EncoderProfilesProxy, EncoderProfiles might " +
+                            "contain invalid video profiles. Use CamcorderProfile instead.", e
+                    )
+                }
             }
-            if (profile != null) EncoderProfilesProxyCompat.from(profile) else null
         }
+
+        return createProfilesFromCamcorderProfile(quality)
+    }
+
+    @Nullable
+    @Suppress("DEPRECATION")
+    private fun createProfilesFromCamcorderProfile(quality: Int): EncoderProfilesProxy? {
+        var profile: CamcorderProfile? = null
+        try {
+            profile = CamcorderProfile.get(cameraId, quality)
+        } catch (e: RuntimeException) {
+            // CamcorderProfile.get() will throw
+            // - RuntimeException if not able to retrieve camcorder profile params.
+            // - IllegalArgumentException if quality is not valid.
+            Logger.w(TAG, "Unable to get CamcorderProfile by quality: $quality", e)
+        }
+        return if (profile != null) EncoderProfilesProxyCompat.from(profile) else null
     }
 
     @RequiresApi(31)
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt
index 05cb202..527cc63 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt
@@ -34,7 +34,7 @@
 import androidx.camera.core.AspectRatio
 import androidx.camera.core.Logger
 import androidx.camera.core.impl.AttachedSurfaceInfo
-import androidx.camera.core.impl.CamcorderProfileProxy
+import androidx.camera.core.impl.EncoderProfilesProxy
 import androidx.camera.core.impl.ImageFormatConstants
 import androidx.camera.core.impl.ImageOutputConfig
 import androidx.camera.core.impl.StreamSpec
@@ -70,7 +70,7 @@
 class SupportedSurfaceCombination(
     context: Context,
     private val cameraMetadata: CameraMetadata,
-    private val camcorderProfileProviderAdapter: CamcorderProfileProviderAdapter
+    private val encoderProfilesProviderAdapter: EncoderProfilesProviderAdapter
 ) {
     private val cameraId = cameraMetadata.camera.value
     private val hardwareLevel =
@@ -289,12 +289,12 @@
             // StreamConfigurationMap to determine the RECORD size.
             return getRecordSizeFromStreamConfigurationMap()
         }
-        var profile: CamcorderProfileProxy? = null
-        if (camcorderProfileProviderAdapter.hasProfile(cameraId)) {
-            profile = camcorderProfileProviderAdapter.get(cameraId)
+        var profiles: EncoderProfilesProxy? = null
+        if (encoderProfilesProviderAdapter.hasProfile(cameraId)) {
+            profiles = encoderProfilesProviderAdapter.getAll(cameraId)
         }
-        return if (profile != null) {
-            Size(profile.videoFrameWidth, profile.videoFrameHeight)
+        return if (profiles != null && profiles.videoProfiles.isNotEmpty()) {
+            Size(profiles.videoProfiles[0].width, profiles.videoProfiles[0].height)
         } else getRecordSizeByHasProfile()
     }
 
@@ -337,25 +337,25 @@
      */
     private fun getRecordSizeByHasProfile(): Size {
         var recordSize: Size = RESOLUTION_480P
-        var profile: CamcorderProfileProxy? = null
+        var profiles: EncoderProfilesProxy? = null
 
         // Check whether 4KDCI, 2160P, 2K, 1080P, 720P, 480P (sorted by size) are supported by
-        // CamcorderProfile
-        if (camcorderProfileProviderAdapter.hasProfile(CamcorderProfile.QUALITY_4KDCI)) {
-            profile = camcorderProfileProviderAdapter.get(CamcorderProfile.QUALITY_4KDCI)
-        } else if (camcorderProfileProviderAdapter.hasProfile(CamcorderProfile.QUALITY_2160P)) {
-            profile = camcorderProfileProviderAdapter.get(CamcorderProfile.QUALITY_2160P)
-        } else if (camcorderProfileProviderAdapter.hasProfile(CamcorderProfile.QUALITY_2K)) {
-            profile = camcorderProfileProviderAdapter.get(CamcorderProfile.QUALITY_2K)
-        } else if (camcorderProfileProviderAdapter.hasProfile(CamcorderProfile.QUALITY_1080P)) {
-            profile = camcorderProfileProviderAdapter.get(CamcorderProfile.QUALITY_1080P)
-        } else if (camcorderProfileProviderAdapter.hasProfile(CamcorderProfile.QUALITY_720P)) {
-            profile = camcorderProfileProviderAdapter.get(CamcorderProfile.QUALITY_720P)
-        } else if (camcorderProfileProviderAdapter.hasProfile(CamcorderProfile.QUALITY_480P)) {
-            profile = camcorderProfileProviderAdapter.get(CamcorderProfile.QUALITY_480P)
+        // EncoderProfiles
+        if (encoderProfilesProviderAdapter.hasProfile(CamcorderProfile.QUALITY_4KDCI)) {
+            profiles = encoderProfilesProviderAdapter.getAll(CamcorderProfile.QUALITY_4KDCI)
+        } else if (encoderProfilesProviderAdapter.hasProfile(CamcorderProfile.QUALITY_2160P)) {
+            profiles = encoderProfilesProviderAdapter.getAll(CamcorderProfile.QUALITY_2160P)
+        } else if (encoderProfilesProviderAdapter.hasProfile(CamcorderProfile.QUALITY_2K)) {
+            profiles = encoderProfilesProviderAdapter.getAll(CamcorderProfile.QUALITY_2K)
+        } else if (encoderProfilesProviderAdapter.hasProfile(CamcorderProfile.QUALITY_1080P)) {
+            profiles = encoderProfilesProviderAdapter.getAll(CamcorderProfile.QUALITY_1080P)
+        } else if (encoderProfilesProviderAdapter.hasProfile(CamcorderProfile.QUALITY_720P)) {
+            profiles = encoderProfilesProviderAdapter.getAll(CamcorderProfile.QUALITY_720P)
+        } else if (encoderProfilesProviderAdapter.hasProfile(CamcorderProfile.QUALITY_480P)) {
+            profiles = encoderProfilesProviderAdapter.getAll(CamcorderProfile.QUALITY_480P)
         }
-        if (profile != null) {
-            recordSize = Size(profile.videoFrameWidth, profile.videoFrameHeight)
+        if (profiles != null && profiles.videoProfiles.isNotEmpty()) {
+            recordSize = Size(profiles.videoProfiles[0].width, profiles.videoProfiles[0].height)
         }
         return recordSize
     }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/ZoomValue.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/ZoomValue.kt
index 5cc5969..8d19d82 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/ZoomValue.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/ZoomValue.kt
@@ -17,6 +17,8 @@
 package androidx.camera.camera2.pipe.integration.adapter
 
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.integration.internal.ZoomMath.getLinearZoomFromZoomRatio
+import androidx.camera.camera2.pipe.integration.internal.ZoomMath.getZoomRatioFromLinearZoom
 import androidx.camera.core.ZoomState
 
 /**
@@ -26,16 +28,39 @@
 data class ZoomValue(
     private val zoomRatio: Float,
     private val minZoomRatio: Float,
-    private val maxZoomRatio: Float
+    private val maxZoomRatio: Float,
 ) : ZoomState {
+    private var linearZoom: Float? = null
+
+    /**
+     * ZoomValue should be created with either zoomRatio or linearZoom and the other value should
+     * be calculated. If both are allowed to be set from outside, it becomes confusing regarding
+     * which value to use if the values don't align with conversion values.
+     * Secondary constructor with a LinearZoom value wrapper class is used for this purpose.
+     */
+    data class LinearZoom(val value: Float)
+    constructor(
+        linearZoom: LinearZoom,
+        minZoomRatio: Float,
+        maxZoomRatio: Float,
+    ) : this(
+        getZoomRatioFromLinearZoom(
+            linearZoom = linearZoom.value,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        ),
+        minZoomRatio,
+        maxZoomRatio
+    ) {
+        this.linearZoom = linearZoom.value
+    }
+
     override fun getZoomRatio(): Float = zoomRatio
     override fun getMaxZoomRatio(): Float = maxZoomRatio
     override fun getMinZoomRatio(): Float = minZoomRatio
-    override fun getLinearZoom(): Float {
-        val range = maxZoomRatio - minZoomRatio
-        if (range > 0) {
-            return (zoomRatio - minZoomRatio) / range
-        }
-        return 1.0f
-    }
-}
\ No newline at end of file
+    override fun getLinearZoom() = linearZoom ?: getLinearZoomFromZoomRatio(
+        zoomRatio = zoomRatio,
+        minZoomRatio = minZoomRatio,
+        maxZoomRatio = maxZoomRatio
+    )
+}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt
index b00002b..33adefc 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt
@@ -24,6 +24,7 @@
 import androidx.camera.camera2.pipe.FrameNumber
 import androidx.camera.camera2.pipe.Request
 import androidx.camera.camera2.pipe.RequestMetadata
+import androidx.camera.camera2.pipe.integration.adapter.propagateTo
 import androidx.camera.camera2.pipe.integration.config.CameraScope
 import androidx.camera.camera2.pipe.integration.impl.Camera2ImplConfig
 import androidx.camera.camera2.pipe.integration.impl.UseCaseCamera
@@ -51,7 +52,7 @@
     fun clearRequestOption()
     fun cancelCurrentTask()
 
-    fun applyAsync(camera: UseCaseCamera?): Deferred<Void?>
+    fun applyAsync(camera: UseCaseCamera?, cancelPreviousTask: Boolean = true): Deferred<Void?>
 
     @Module
     abstract class Bindings {
@@ -114,15 +115,23 @@
         }
     }
 
-    override fun applyAsync(camera: UseCaseCamera?): Deferred<Void?> {
+    override fun applyAsync(camera: UseCaseCamera?, cancelPreviousTask: Boolean): Deferred<Void?> {
         val signal: CompletableDeferred<Void?> = CompletableDeferred()
         val config = synchronized(lock) {
             configBuilder.build()
         }
         threads.sequentialScope.launch {
             if (camera != null) {
-                // Cancel the previous request signal if exist.
-                updateSignal?.cancelSignal()
+                if (cancelPreviousTask) {
+                    // Cancel the previous request signal if exist.
+                    updateSignal?.cancelSignal()
+                } else {
+                    // propagate the result to the previous updateSignal
+                    updateSignal?.let { previousUpdateSignal ->
+                        signal.propagateTo(previousUpdateSignal)
+                    }
+                }
+
                 updateSignal = signal
                 camera.requestControl.setConfigAsync(
                     type = UseCaseCameraRequestControl.Type.CAMERA2_CAMERA_CONTROL,
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/EvCompCompat.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/EvCompCompat.kt
index 7324125..3dafac7 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/EvCompCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/EvCompCompat.kt
@@ -29,6 +29,7 @@
 import androidx.camera.camera2.pipe.FrameNumber
 import androidx.camera.camera2.pipe.Request
 import androidx.camera.camera2.pipe.RequestMetadata
+import androidx.camera.camera2.pipe.integration.adapter.propagateTo
 import androidx.camera.camera2.pipe.integration.config.CameraScope
 import androidx.camera.camera2.pipe.integration.impl.CameraProperties
 import androidx.camera.camera2.pipe.integration.impl.ComboRequestListener
@@ -37,21 +38,22 @@
 import androidx.camera.core.CameraControl
 import dagger.Binds
 import dagger.Module
+import javax.inject.Inject
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.launch
-import javax.inject.Inject
 
 interface EvCompCompat {
     val supported: Boolean
     val range: Range<Int>
     val step: Rational
 
-    fun stopRunningTask()
+    fun stopRunningTask(throwable: Throwable)
 
     fun applyAsync(
         evCompIndex: Int,
-        camera: UseCaseCamera
+        camera: UseCaseCamera,
+        cancelPreviousTask: Boolean,
     ): Deferred<Int>
 
     @Module
@@ -90,18 +92,38 @@
     private var updateSignal: CompletableDeferred<Int>? = null
     private var updateListener: Request.Listener? = null
 
-    override fun stopRunningTask() {
+    override fun stopRunningTask(throwable: Throwable) {
         threads.sequentialScope.launch {
-            stopRunningTaskInternal()
+            updateSignal?.completeExceptionally(throwable)
         }
     }
 
-    override fun applyAsync(evCompIndex: Int, camera: UseCaseCamera): Deferred<Int> {
+    override fun applyAsync(
+        evCompIndex: Int,
+        camera: UseCaseCamera,
+        cancelPreviousTask: Boolean,
+    ): Deferred<Int> {
         val signal = CompletableDeferred<Int>()
 
         threads.sequentialScope.launch {
-            stopRunningTaskInternal()
+            updateSignal?.let { previousUpdateSignal ->
+                if (cancelPreviousTask) {
+                    // Cancel the previous request signal if exist.
+                    previousUpdateSignal.completeExceptionally(
+                        CameraControl.OperationCanceledException(
+                            "Cancelled by another setExposureCompensationIndex()"
+                        )
+                    )
+                } else {
+                    // Propagate the result to the previous updateSignal
+                    signal.propagateTo(previousUpdateSignal)
+                }
+            }
             updateSignal = signal
+            updateListener?.let {
+                comboRequestListener.removeListener(it)
+                updateListener = null
+            }
 
             camera.setParameterAsync(CONTROL_AE_EXPOSURE_COMPENSATION, evCompIndex)
 
@@ -110,7 +132,7 @@
                 override fun onComplete(
                     requestMetadata: RequestMetadata,
                     frameNumber: FrameNumber,
-                    result: FrameInfo
+                    result: FrameInfo,
                 ) {
                     val state = result.metadata[CaptureResult.CONTROL_AE_STATE]
                     val evResult = result.metadata[CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION]
@@ -121,7 +143,6 @@
                             CaptureResult.CONTROL_AE_STATE_LOCKED ->
                                 if (evResult == evCompIndex) {
                                     signal.complete(evCompIndex)
-                                    comboRequestListener.removeListener(this)
                                 }
                             else -> {
                             }
@@ -130,32 +151,14 @@
                         // If AE state is null, only wait for the exposure result to the desired
                         // value.
                         signal.complete(evCompIndex)
-
-                        // Remove the capture result listener. The updateSignal and
-                        // updateListener will be cleared before the next set exposure task.
-                        comboRequestListener.removeListener(this)
                     }
                 }
+            }.also { requestListener ->
+                comboRequestListener.addListener(requestListener, threads.sequentialExecutor)
+                signal.invokeOnCompletion { comboRequestListener.removeListener(requestListener) }
             }
-            comboRequestListener.addListener(updateListener!!, threads.sequentialExecutor)
         }
 
         return signal
     }
-
-    private fun stopRunningTaskInternal() {
-        updateSignal?.let {
-            it.completeExceptionally(
-                CameraControl.OperationCanceledException(
-                    "Cancelled by another setExposureCompensationIndex()"
-                )
-            )
-            updateSignal = null
-        }
-
-        updateListener?.let {
-            comboRequestListener.removeListener(it)
-            updateListener = null
-        }
-    }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/ZoomCompat.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/ZoomCompat.kt
index 38d92ef..a9e1348 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/ZoomCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/ZoomCompat.kt
@@ -30,14 +30,21 @@
 import dagger.Provides
 
 interface ZoomCompat {
-    val minZoom: Float
-    val maxZoom: Float
+    val minZoomRatio: Float
+    val maxZoomRatio: Float
 
     fun apply(
         zoomRatio: Float,
         camera: UseCaseCamera
     )
 
+    /**
+     * Returns the current crop sensor region which should be used for converting
+     * [androidx.camera.core.MeteringPoint] to sensor coordinates. Returns the sensor
+     * rect if there is no crop region being set.
+     */
+    fun getCropSensorRegion(): Rect
+
     @Module
     abstract class Bindings {
         companion object {
@@ -47,7 +54,7 @@
                     val range =
                         cameraProperties.metadata[CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE]
                     if (range != null) {
-                        AndroidRZoomCompat(range)
+                        AndroidRZoomCompat(cameraProperties, range)
                     } else {
                         CropRegionZoomCompat(cameraProperties)
                     }
@@ -60,23 +67,28 @@
 }
 
 class CropRegionZoomCompat(private val cameraProperties: CameraProperties) : ZoomCompat {
-    override val minZoom: Float
+    override val minZoomRatio: Float
         get() = 1.0f
-    override val maxZoom: Float
+    override val maxZoomRatio: Float
         get() = cameraProperties.metadata.getOrDefault(
-            CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, minZoom
+            CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, minZoomRatio
         )
 
+    private var currentCropRect: Rect? = null
+
     override fun apply(
         zoomRatio: Float,
         camera: UseCaseCamera
     ) {
         val sensorRect =
             cameraProperties.metadata[CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE]!!
-        val cropRect = computeCropRect(sensorRect, zoomRatio)
-        camera.setParameterAsync(CaptureRequest.SCALER_CROP_REGION, cropRect)
+        currentCropRect = computeCropRect(sensorRect, zoomRatio)
+        camera.setParameterAsync(CaptureRequest.SCALER_CROP_REGION, currentCropRect)
     }
 
+    override fun getCropSensorRegion() = currentCropRect
+        ?: cameraProperties.metadata[CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE]!!
+
     private fun computeCropRect(sensorRect: Rect, zoomRatio: Float): Rect {
         val cropWidth: Float = sensorRect.width() / zoomRatio
         val cropHeight: Float = sensorRect.height() / zoomRatio
@@ -92,17 +104,23 @@
 }
 
 @RequiresApi(Build.VERSION_CODES.R)
-class AndroidRZoomCompat(private val range: Range<Float>) : ZoomCompat {
-    override val minZoom: Float
+class AndroidRZoomCompat(
+    private val cameraProperties: CameraProperties,
+    private val range: Range<Float>,
+) : ZoomCompat {
+    override val minZoomRatio: Float
         get() = range.lower
-    override val maxZoom: Float
+    override val maxZoomRatio: Float
         get() = range.upper
 
     override fun apply(
         zoomRatio: Float,
         camera: UseCaseCamera
     ) {
-        require(zoomRatio in minZoom..maxZoom)
+        require(zoomRatio in minZoomRatio..maxZoomRatio)
         camera.setParameterAsync(CaptureRequest.CONTROL_ZOOM_RATIO, zoomRatio)
     }
-}
\ No newline at end of file
+
+    override fun getCropSensorRegion(): Rect =
+        cameraProperties.metadata[CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE]!!
+}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/DeviceQuirks.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/DeviceQuirks.kt
new file mode 100644
index 0000000..a46eb22
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/DeviceQuirks.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 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.
+ */
+
+@file:RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+
+package androidx.camera.camera2.pipe.integration.compat.quirk
+
+import androidx.annotation.RequiresApi
+import androidx.camera.core.impl.Quirk
+import androidx.camera.core.impl.Quirks
+
+/**
+ * Provider of device specific quirks, which are used for device specific workarounds.
+ *
+ * Device specific quirks depend on device properties, including the manufacturer
+ * ([android.os.Build.MANUFACTURER]), model ([android.os.Build.MODEL]) and OS
+ * level ([android.os.Build.VERSION.SDK_INT]).
+ *
+ * Device specific quirks are lazily loaded, i.e. They are loaded the first time they're needed.
+ */
+object DeviceQuirks {
+
+    /** Returns all device specific quirks loaded on the current device.  */
+    val all: Quirks by lazy {
+        Quirks(DeviceQuirksLoader.loadQuirks())
+    }
+
+    /**
+     * Retrieves a specific device [Quirk] instance given its type.
+     *
+     * @param quirkClass The type of device quirk to retrieve.
+     * @return A device [Quirk] instance of the provided type, or `null` if it isn't found.
+     */
+    operator fun <T : Quirk?> get(quirkClass: Class<T>): T? {
+        return all.get(quirkClass)
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/DeviceQuirksLoader.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/DeviceQuirksLoader.kt
new file mode 100644
index 0000000..43b87c6
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/DeviceQuirksLoader.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 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.
+ */
+
+@file:RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+
+package androidx.camera.camera2.pipe.integration.compat.quirk
+
+import androidx.annotation.RequiresApi
+import androidx.camera.core.impl.Quirk
+
+/**
+ * Loads all device specific quirks required for the current device.
+ */
+object DeviceQuirksLoader {
+
+    /**
+     * Goes through all defined device-specific quirks, and returns those that should be loaded
+     * on the current device.
+     */
+    fun loadQuirks(): List<Quirk> {
+        val quirks: MutableList<Quirk> = mutableListOf()
+
+        // Load all device specific quirks.
+        if (InvalidVideoProfilesQuirk.load()) {
+            quirks.add(InvalidVideoProfilesQuirk())
+        }
+
+        return quirks
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/InvalidVideoProfilesQuirk.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/InvalidVideoProfilesQuirk.kt
new file mode 100644
index 0000000..20abaa1
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/InvalidVideoProfilesQuirk.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2023 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.
+ */
+
+@file:RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+
+package androidx.camera.camera2.pipe.integration.compat.quirk
+
+import android.annotation.SuppressLint
+import android.media.EncoderProfiles
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.camera.core.impl.Quirk
+
+/**
+ * Quirk denoting the video profile list returns by [EncoderProfiles] is invalid.
+ *
+ * QuirkSummary
+ * - Bug Id: 267727595
+ * - Description: When using [EncoderProfiles] on TP1A or TD1A builds of Android API 33,
+ *   [EncoderProfiles.getVideoProfiles] returns a list with size one, but the single value in the
+ *   list is null. This is not the expected behavior, and makes [EncoderProfiles] lack of video
+ *   information.
+ * - Device(s): Pixel 4 and above pixel devices with TP1A or TD1A builds (API 33).
+ *
+ * TODO: enable CameraXQuirksClassDetector lint check when kotlin is supported.
+ */
+@SuppressLint("CameraXQuirksClassDetector")
+class InvalidVideoProfilesQuirk : Quirk {
+
+    companion object {
+        private val AFFECTED_MODELS: List<String> = listOf(
+            "pixel 4",
+            "pixel 4a",
+            "pixel 4 xl",
+            "pixel 5",
+            "pixel 5a",
+            "pixel 6",
+            "pixel 6a",
+            "pixel 6 pro",
+            "pixel 7",
+            "pixel 7 pro"
+        )
+
+        fun load(): Boolean {
+            return isAffectedModel() && isAffectedBuild()
+        }
+
+        private fun isAffectedModel(): Boolean {
+            return AFFECTED_MODELS.contains(
+                Build.MODEL.lowercase()
+            )
+        }
+
+        private fun isAffectedBuild(): Boolean {
+            return isTp1aBuild() || isTd1aBuild()
+        }
+
+        private fun isTp1aBuild(): Boolean {
+            return Build.ID.startsWith("TP1A")
+        }
+
+        private fun isTd1aBuild(): Boolean {
+            return Build.ID.startsWith("TD1A")
+        }
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/package-info.java b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/package-info.java
new file mode 100644
index 0000000..eca73c3
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2023 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.
+ */
+
+/**
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+package androidx.camera.camera2.pipe.integration.compat.quirk;
+
+import androidx.annotation.RestrictTo;
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt
index a4be0a8..2bba010 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt
@@ -63,16 +63,15 @@
         get() = _useCaseCamera
         set(value) {
             _useCaseCamera = value
-            updateAsync(evCompIndex)
+            updateAsync(evCompIndex, cancelPreviousTask = false)
         }
 
     override fun reset() {
-        evCompIndex = 0
-        compat.stopRunningTask()
-        updateAsync(0)
+        evCompIndex = DEFAULT_EXPOSURE_COMPENSATION
+        updateAsync(DEFAULT_EXPOSURE_COMPENSATION)
     }
 
-    fun updateAsync(exposureIndex: Int): Deferred<Int> {
+    fun updateAsync(exposureIndex: Int, cancelPreviousTask: Boolean = true): Deferred<Int> {
         if (!compat.supported) {
             return createFailureResult(
                 IllegalArgumentException("ExposureCompensation is not supported")
@@ -88,12 +87,15 @@
             )
         }
 
-        useCaseCamera?.let {
+        return useCaseCamera?.let { camera ->
             evCompIndex = exposureIndex
-            return compat.applyAsync(exposureIndex, it)
-        } ?: return createFailureResult(
-            CameraControl.OperationCanceledException("Camera is not active.")
-        )
+            compat.applyAsync(exposureIndex, camera, cancelPreviousTask)
+        } ?: run {
+            CameraControl.OperationCanceledException("Camera is not active.").let { cancelResult ->
+                compat.stopRunningTask(cancelResult)
+                createFailureResult(cancelResult)
+            }
+        }
     }
 
     private fun createFailureResult(exception: Exception) = CompletableDeferred<Int>().apply {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FlashControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FlashControl.kt
index 21fe187..e053c73 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FlashControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FlashControl.kt
@@ -17,6 +17,7 @@
 package androidx.camera.camera2.pipe.integration.impl
 
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.integration.adapter.propagateTo
 import androidx.camera.camera2.pipe.integration.config.CameraScope
 import androidx.camera.core.CameraControl
 import androidx.camera.core.ImageCapture
@@ -45,7 +46,7 @@
         get() = _useCaseCamera
         set(value) {
             _useCaseCamera = value
-            setFlashAsync(_flashMode)
+            setFlashAsync(_flashMode, false)
         }
 
     override fun reset() {
@@ -71,7 +72,7 @@
         }
         private set
 
-    fun setFlashAsync(flashMode: Int): Deferred<Unit> {
+    fun setFlashAsync(flashMode: Int, cancelPreviousTask: Boolean = true): Deferred<Unit> {
         val signal = CompletableDeferred<Unit>()
 
         useCaseCamera?.let {
@@ -81,13 +82,18 @@
             _flashMode = flashMode
 
             threads.sequentialScope.launch {
-                stopRunningTask()
+                if (cancelPreviousTask) {
+                    stopRunningTask()
+                } else {
+                    // Propagate the result to the previous updateSignal
+                    _updateSignal?.let { previousUpdateSignal ->
+                        signal.propagateTo(previousUpdateSignal)
+                    }
+                }
 
                 _updateSignal = signal
                 state3AControl.flashMode = flashMode
-                state3AControl.updateSignal?.join()
-
-                signal.complete(Unit)
+                state3AControl.updateSignal?.propagateTo(signal) ?: run { signal.complete(Unit) }
             }
         } ?: run {
             signal.completeExceptionally(
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt
index 0b11ba7..a7c456f 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt
@@ -27,6 +27,8 @@
 import androidx.camera.camera2.pipe.AeMode
 import androidx.camera.camera2.pipe.Result3A
 import androidx.camera.camera2.pipe.integration.adapter.asListenableFuture
+import androidx.camera.camera2.pipe.integration.adapter.propagateTo
+import androidx.camera.camera2.pipe.integration.compat.ZoomCompat
 import androidx.camera.camera2.pipe.integration.config.CameraScope
 import androidx.camera.core.CameraControl.OperationCanceledException
 import androidx.camera.core.FocusMeteringAction
@@ -53,6 +55,7 @@
     private val cameraProperties: CameraProperties,
     private val state3AControl: State3AControl,
     private val threads: UseCaseThreads,
+    private val zoomCompat: ZoomCompat,
 ) : UseCaseCameraControl, UseCaseCamera.RunningUseCasesChangeListener {
     private var _useCaseCamera: UseCaseCamera? = null
 
@@ -80,15 +83,12 @@
         cancelFocusAndMeteringAsync()
     }
 
-    @Volatile
     private var previewAspectRatio: Rational? = null
-    private val sensorRect by lazy {
-        // TODO("b/262225455"): use the actual crop sensor region like in camera-camera2
-        cameraProperties.metadata[CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE]!!
-    }
+    private val cropSensorRegion
+        get() = zoomCompat.getCropSensorRegion()
 
     private val defaultAspectRatio: Rational
-        get() = previewAspectRatio ?: Rational(sensorRect.width(), sensorRect.height())
+        get() = previewAspectRatio ?: Rational(cropSensorRegion.width(), cropSensorRegion.height())
 
     private val maxAfRegionCount =
         cameraProperties.metadata.getOrDefault(CameraCharacteristics.CONTROL_MAX_REGIONS_AF, 0)
@@ -114,19 +114,19 @@
                 val aeRectangles = meteringRegionsFromMeteringPoints(
                     action.meteringPointsAe,
                     maxAeRegionCount,
-                    sensorRect,
+                    cropSensorRegion,
                     defaultAspectRatio
                 )
                 val afRectangles = meteringRegionsFromMeteringPoints(
                     action.meteringPointsAf,
                     maxAfRegionCount,
-                    sensorRect,
+                    cropSensorRegion,
                     defaultAspectRatio
                 )
                 val awbRectangles = meteringRegionsFromMeteringPoints(
                     action.meteringPointsAwb,
                     maxAwbRegionCount,
-                    sensorRect,
+                    cropSensorRegion,
                     defaultAspectRatio
                 )
                 if (aeRectangles.isEmpty() && afRectangles.isEmpty() && awbRectangles.isEmpty()) {
@@ -161,7 +161,7 @@
                     } else {
                         if (isCancelEnabled) {
                             if (signal.isActive) {
-                                cancelFocusAndMeteringNow(useCaseCamera, signal)
+                                cancelFocusAndMeteringNowAsync(useCaseCamera, signal)
                             }
                         } else {
                             signal.complete(FocusMeteringResult.create(false))
@@ -190,19 +190,19 @@
         val rectanglesAe = meteringRegionsFromMeteringPoints(
             action.meteringPointsAe,
             maxAeRegionCount,
-            sensorRect,
+            cropSensorRegion,
             defaultAspectRatio
         )
         val rectanglesAf = meteringRegionsFromMeteringPoints(
             action.meteringPointsAf,
             maxAfRegionCount,
-            sensorRect,
+            cropSensorRegion,
             defaultAspectRatio
         )
         val rectanglesAwb = meteringRegionsFromMeteringPoints(
             action.meteringPointsAwb,
             maxAwbRegionCount,
-            sensorRect,
+            cropSensorRegion,
             defaultAspectRatio
         )
         return rectanglesAe.isNotEmpty() || rectanglesAf.isNotEmpty() || rectanglesAwb.isNotEmpty()
@@ -231,7 +231,7 @@
             threads.sequentialScope.launch {
                 cancelSignal?.setCancelException("Cancelled by another cancelFocusAndMetering()")
                 cancelSignal = signal
-                signal.complete(cancelFocusAndMeteringNow(useCaseCamera, updateSignal))
+                cancelFocusAndMeteringNowAsync(useCaseCamera, updateSignal).propagateTo(signal)
             }
         } ?: run {
             signal.completeExceptionally(OperationCanceledException("Camera is not active."))
@@ -240,13 +240,13 @@
         return signal
     }
 
-    private suspend fun cancelFocusAndMeteringNow(
+    private suspend fun cancelFocusAndMeteringNowAsync(
         useCaseCamera: UseCaseCamera,
         signalToCancel: CompletableDeferred<FocusMeteringResult>?,
-    ): Result3A {
+    ): Deferred<Result3A> {
         signalToCancel?.setCancelException("Cancelled by cancelFocusAndMetering()")
         state3AControl.preferredFocusMode = null
-        return useCaseCamera.requestControl.cancelFocusAndMeteringAsync().await()
+        return useCaseCamera.requestControl.cancelFocusAndMeteringAsync()
     }
 
     private fun <T> CompletableDeferred<T>.setCancelException(message: String) {
@@ -287,8 +287,6 @@
             val cropRegionAspectRatio =
                 Rational(cropSensorRegion.width(), cropSensorRegion.height())
 
-            // TODO(sushilnath@): limit the number of metering regions to what is supported by the
-            // device.
             for (meteringPoint in meteringPoints) {
                 // Only enable at most maxRegionCount.
                 if (meteringRegions.size >= maxRegionCount) {
@@ -297,8 +295,6 @@
                 if (!isValid(meteringPoint)) {
                     continue
                 }
-                // TODO(sushilnath@): Use the zoom based crop region aspect ratio instead of sensor
-                // active array aspect ratio.
                 val adjustedPoint: PointF =
                     getFovAdjustedPoint(meteringPoint, cropRegionAspectRatio, defaultAspectRatio)
                 val meteringRectangle: MeteringRectangle =
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/State3AControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/State3AControl.kt
index dc8aa7e..4c5f71f 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/State3AControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/State3AControl.kt
@@ -19,9 +19,12 @@
 import android.hardware.camera2.CameraCharacteristics
 import android.hardware.camera2.CameraDevice
 import android.hardware.camera2.CaptureRequest
+import androidx.annotation.GuardedBy
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.integration.adapter.SessionConfigAdapter
+import androidx.camera.camera2.pipe.integration.adapter.propagateTo
 import androidx.camera.camera2.pipe.integration.config.CameraScope
+import androidx.camera.core.CameraControl
 import androidx.camera.core.ImageCapture
 import androidx.camera.core.UseCase
 import androidx.camera.core.impl.CaptureConfig
@@ -45,7 +48,16 @@
         set(value) {
             _useCaseCamera = value
             value?.let {
+                val previousSignals = synchronized(lock) {
+                    updateSignal = null
+                    updateSignals.toList()
+                }
+
                 invalidate() // Always apply the settings to the camera.
+
+                synchronized(lock) { updateSignal }?.let { newUpdateSignal ->
+                    previousSignals.forEach { newUpdateSignal.propagateTo(it) }
+                } ?: run { previousSignals.forEach { it.complete(Unit) } }
             }
         }
 
@@ -68,6 +80,12 @@
         intArrayOf(CaptureRequest.CONTROL_AWB_MODE_OFF)
     ).asList()
 
+    private val lock = Any()
+
+    @GuardedBy("lock")
+    private val updateSignals = mutableSetOf<CompletableDeferred<Unit>>()
+
+    @GuardedBy("lock")
     var updateSignal: Deferred<Unit>? = null
         private set
     var flashMode by updateOnPropertyChange(DEFAULT_FLASH_MODE)
@@ -76,6 +94,7 @@
     var preferredFocusMode: Int? by updateOnPropertyChange(null)
 
     override fun reset() {
+        synchronized(lock) { updateSignals.toList() }.cancelAll()
         preferredAeMode = null
         preferredFocusMode = null
         flashMode = DEFAULT_FLASH_MODE
@@ -106,7 +125,7 @@
 
         val preferAfMode = preferredFocusMode ?: getDefaultAfMode()
 
-        updateSignal = useCaseCamera?.requestControl?.addParametersAsync(
+        useCaseCamera?.requestControl?.addParametersAsync(
             values = mapOf(
                 CaptureRequest.CONTROL_AE_MODE to getSupportedAeMode(preferAeMode),
                 CaptureRequest.CONTROL_AF_MODE to getSupportedAfMode(preferAfMode),
@@ -114,7 +133,21 @@
                     CaptureRequest.CONTROL_AWB_MODE_AUTO
                 ),
             )
-        ) ?: CompletableDeferred(null)
+        )?.apply {
+            toCompletableDeferred().also { signal ->
+                synchronized(lock) {
+                    updateSignals.add(signal)
+                    updateSignal = signal
+                    signal.invokeOnCompletion {
+                        synchronized(lock) {
+                            updateSignals.remove(signal)
+                        }
+                    }
+                }
+            }
+        } ?: run {
+            synchronized(lock) { updateSignal = CompletableDeferred(null) }
+        }
     }
 
     private fun getDefaultAfMode(): Int = when (template) {
@@ -189,6 +222,13 @@
         }
     }
 
+    private fun <T> Deferred<T>.toCompletableDeferred() =
+        CompletableDeferred<T>().also { propagateTo(it) }
+
+    private fun <T> Collection<CompletableDeferred<T>>.cancelAll() = forEach {
+        it.completeExceptionally(CameraControl.OperationCanceledException("Camera is not active."))
+    }
+
     @Module
     abstract class Bindings {
         @Binds
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/TorchControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/TorchControl.kt
index 7981dc9..21e752a 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/TorchControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/TorchControl.kt
@@ -19,6 +19,7 @@
 import android.hardware.camera2.CameraCharacteristics
 import android.hardware.camera2.CaptureRequest
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.integration.adapter.propagateTo
 import androidx.camera.camera2.pipe.integration.config.CameraScope
 import androidx.camera.core.CameraControl
 import androidx.camera.core.TorchState
@@ -51,10 +52,11 @@
         set(value) {
             _useCaseCamera = value
             setTorchAsync(
-                when (torchStateLiveData.value) {
+                torch = when (torchStateLiveData.value) {
                     TorchState.ON -> true
                     else -> false
-                }
+                },
+                cancelPreviousTask = false,
             )
         }
 
@@ -77,7 +79,7 @@
 
     private var _updateSignal: CompletableDeferred<Unit>? = null
 
-    fun setTorchAsync(torch: Boolean): Deferred<Unit> {
+    fun setTorchAsync(torch: Boolean, cancelPreviousTask: Boolean = true): Deferred<Unit> {
         val signal = CompletableDeferred<Unit>()
 
         if (!hasFlashUnit) {
@@ -89,7 +91,15 @@
             _torchState.setLiveDataValue(torch)
 
             threads.sequentialScope.launch {
-                stopRunningTaskInternal()
+                if (cancelPreviousTask) {
+                    stopRunningTaskInternal()
+                } else {
+                    // Propagate the result to the previous updateSignal
+                    _updateSignal?.let { previousUpdateSignal ->
+                        signal.propagateTo(previousUpdateSignal)
+                    }
+                }
+
                 _updateSignal = signal
 
                 // TODO(b/209757083), handle the failed result of the setTorchAsync().
@@ -98,9 +108,7 @@
                 // Hold the internal AE mode to ON while the torch is turned ON.
                 state3AControl.preferredAeMode =
                     if (torch) CaptureRequest.CONTROL_AE_MODE_ON else null
-                state3AControl.updateSignal?.join()
-
-                signal.complete(Unit)
+                state3AControl.updateSignal?.propagateTo(signal) ?: run { signal.complete(Unit) }
             }
         } ?: run {
             signal.createFailureResult(
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt
index 698da1b..66fbb27 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt
@@ -21,6 +21,8 @@
 import androidx.camera.camera2.pipe.integration.adapter.asListenableFuture
 import androidx.camera.camera2.pipe.integration.compat.ZoomCompat
 import androidx.camera.camera2.pipe.integration.config.CameraScope
+import androidx.camera.camera2.pipe.integration.internal.ZoomMath.getLinearZoomFromZoomRatio
+import androidx.camera.camera2.pipe.integration.internal.ZoomMath.getZoomRatioFromLinearZoom
 import androidx.camera.core.CameraControl
 import androidx.camera.core.ZoomState
 import androidx.camera.core.impl.utils.futures.Futures
@@ -31,7 +33,6 @@
 import dagger.Module
 import dagger.multibindings.IntoSet
 import javax.inject.Inject
-import kotlin.math.abs
 import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -47,11 +48,11 @@
 ) : UseCaseCameraControl {
     // NOTE: minZoom may be lower than 1.0
     // NOTE: Default zoom ratio is 1.0 (DEFAULT_ZOOM_RATIO)
-    val minZoom: Float = zoomCompat.minZoom
-    val maxZoom: Float = zoomCompat.maxZoom
+    val minZoomRatio: Float = zoomCompat.minZoomRatio
+    val maxZoomRatio: Float = zoomCompat.maxZoomRatio
 
     val defaultZoomState by lazy {
-        ZoomValue(DEFAULT_ZOOM_RATIO, minZoom, maxZoom)
+        ZoomValue(DEFAULT_ZOOM_RATIO, minZoomRatio, maxZoomRatio)
     }
 
     private val _zoomState by lazy {
@@ -62,28 +63,18 @@
         get() = _zoomState
 
     /** Linear zoom is between 0.0f and 1.0f */
-    fun toLinearZoom(zoomRatio: Float): Float {
-        val range = zoomCompat.maxZoom - zoomCompat.minZoom
-        if (range > 0) {
-            return (zoomRatio - zoomCompat.minZoom) / range
-        }
-        return 0.0f
-    }
+    fun toLinearZoom(zoomRatio: Float) = getLinearZoomFromZoomRatio(
+        zoomRatio = zoomRatio,
+        minZoomRatio = minZoomRatio,
+        maxZoomRatio = maxZoomRatio
+    )
 
     /** Zoom ratio is commonly used as the "1x, 2x, 5x" zoom ratio. Zoom ratio may be less than 1 */
-    fun toZoomRatio(linearZoom: Float): Float {
-        val range = zoomCompat.maxZoom - zoomCompat.minZoom
-        if (range > 0) {
-            return linearZoom * range + zoomCompat.minZoom
-        }
-
-        // if minZoom = maxZoom = 2.0f, 2.0f should be returned instead of default 1.0f
-        if (nearZero(range)) {
-            return zoomCompat.minZoom
-        }
-
-        return DEFAULT_ZOOM_RATIO
-    }
+    private fun toZoomRatio(linearZoom: Float) = getZoomRatioFromLinearZoom(
+        linearZoom = linearZoom,
+        minZoomRatio = minZoomRatio,
+        maxZoomRatio = maxZoomRatio
+    )
 
     private var _useCaseCamera: UseCaseCamera? = null
     override var useCaseCamera: UseCaseCamera?
@@ -117,16 +108,46 @@
         }
     }
 
-    fun setZoomRatioAsync(ratio: Float): ListenableFuture<Void> {
+    fun setLinearZoom(linearZoom: Float): ListenableFuture<Void> {
+        if (linearZoom > 1.0f || linearZoom < 0f) {
+            val outOfRangeDesc =
+                "Requested linearZoom $linearZoom is not within valid range [0, 1]"
+            return Futures.immediateFailedFuture(
+                IllegalArgumentException(outOfRangeDesc)
+            )
+        }
+
+        val zoomValue = ZoomValue(
+            ZoomValue.LinearZoom(linearZoom),
+            minZoomRatio,
+            maxZoomRatio,
+        )
+        return setZoomValue(zoomValue)
+    }
+
+    fun setZoomRatio(zoomRatio: Float): ListenableFuture<Void> {
+        if (zoomRatio > maxZoomRatio || zoomRatio < minZoomRatio) {
+            val outOfRangeDesc =
+                "Requested zoomRatio $zoomRatio is not within valid range" +
+                    " [$minZoomRatio, $maxZoomRatio]"
+            return Futures.immediateFailedFuture(
+                IllegalArgumentException(outOfRangeDesc)
+            )
+        }
+
+        val zoomValue = ZoomValue(
+            zoomRatio,
+            minZoomRatio,
+            maxZoomRatio,
+        )
+        return setZoomValue(zoomValue)
+    }
+
+    fun setZoomValue(zoomValue: ZoomValue): ListenableFuture<Void> {
         // TODO: report IllegalArgumentException if ratio not in range
         return Futures.nonCancellationPropagating(
             useCaseCamera?.let {
                 threads.scope.launch(start = CoroutineStart.UNDISPATCHED) {
-                    val zoomValue = ZoomValue(
-                        ratio,
-                        minZoom,
-                        maxZoom
-                    )
                     setZoomState(zoomValue)
                     update()
                 }.asListenableFuture()
@@ -136,10 +157,6 @@
         )
     }
 
-    private fun nearZero(num: Float): Boolean {
-        return abs(num) < 2.0 * Math.ulp(abs(num))
-    }
-
     @Module
     abstract class Bindings {
         @Binds
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/internal/ZoomMath.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/internal/ZoomMath.kt
new file mode 100644
index 0000000..0114d24
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/internal/ZoomMath.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.pipe.integration.internal
+
+import androidx.core.math.MathUtils
+import kotlin.math.abs
+
+/**
+ * This class is used for containing the mathematical calculations for ZoomControl, mainly the
+ * conversions between zoomRatio and linearZoom.
+ *
+ * The linearZoom is the percentage of zoom amount i.e. how much cropWidth is being used,
+ * so linearZoom = 0.5 should represent the middle point of
+ * [minZoomCropWidth, maxZoomCropWidth] range. But that does not mean it should be the same as
+ * (minZoom + maxZoom) / 2. For example, consider the case where
+ * original cropWidth = 10000 for zoomRatio = 1.0f,
+ * minZoomRatio = 1.0f, maxZoomRatio = 10.0f,
+ * zoomRatio = 5.5f may not represent linearZoom = 0.5 i.e. the half zoom amount. Here,
+ * zoomRatio = 1.0f, cropWidth = 10000,
+ * zoomRatio = 5.5f, cropWidth = 1818.18
+ * zoomRatio = 10.0f, cropWidth = 1000
+ * As observed, zoomRatio = 5.5f does not yield cropWidth = 5500 which would be the actual
+ * zooming amount middle point.
+ */
+object ZoomMath {
+    fun getLinearZoomFromZoomRatio(
+        zoomRatio: Float,
+        minZoomRatio: Float,
+        maxZoomRatio: Float
+    ): Float {
+        // if zoom is not supported i.e. minZoomRatio = maxZoomRatio, return 0
+        if (areFloatsEqual(minZoomRatio, maxZoomRatio)) {
+            return 0f
+        }
+
+        if (areFloatsEqual(zoomRatio, maxZoomRatio)) {
+            return 1f
+        } else if (areFloatsEqual(zoomRatio, minZoomRatio)) {
+            return 0f
+        }
+
+        /**
+         * linearZoom should represent the percentage of zoom amount based on how much cropWidth
+         * is visible.
+         *
+         * The original sensor region width is considered as 1.0f here as we only need the
+         * linearZoom ratio, not the actual crop width.
+         */
+        val relativeCropWidth = 1.0f / zoomRatio
+        val relativeCropWidthInMaxZoom = 1.0f / maxZoomRatio
+        val relativeCropWidthInMinZoom = 1.0f / minZoomRatio
+
+        val linearZoom = (relativeCropWidthInMinZoom - relativeCropWidth) /
+            (relativeCropWidthInMinZoom - relativeCropWidthInMaxZoom)
+
+        return MathUtils.clamp(linearZoom, 0f, 1.0f)
+    }
+
+    fun getZoomRatioFromLinearZoom(
+        linearZoom: Float,
+        minZoomRatio: Float,
+        maxZoomRatio: Float
+    ): Float {
+        if (areFloatsEqual(linearZoom, 1.0f)) {
+            return maxZoomRatio
+        } else if (areFloatsEqual(linearZoom, 0f)) {
+            return minZoomRatio
+        }
+
+        /**
+         * This crop width is proportional to the real crop width.
+         * The real crop with = sensorWidth/ zoomRatio,  but we need the ratio only so we can
+         * assume sensorWidth as 1.0f.
+         */
+        val relativeCropWidthInMaxZoom = 1.0f / maxZoomRatio
+        val relativeCropWidthInMinZoom = 1.0f / minZoomRatio
+
+        val cropWidth = relativeCropWidthInMinZoom -
+            (relativeCropWidthInMinZoom - relativeCropWidthInMaxZoom) * linearZoom
+
+        val ratio = 1.0f / cropWidth
+
+        return MathUtils.clamp(ratio, minZoomRatio, maxZoomRatio)
+    }
+
+    private fun areFloatsEqual(num1: Float, num2: Float): Boolean {
+        return nearZero(num1 - num2)
+    }
+
+    private fun nearZero(num: Float): Boolean {
+        return abs(num) < 2.0 * Math.ulp(abs(num))
+    }
+}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControl.kt
index 35d0833..4d669ef 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControl.kt
@@ -69,7 +69,7 @@
             _useCaseCamera?.also {
                 requestListener.removeListener(compat)
                 requestListener.addListener(compat, threads.sequentialExecutor)
-                compat.applyAsync(it)
+                compat.applyAsync(it, false)
             }
         }
 
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt
index fe14c55..685eb31 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt
@@ -98,12 +98,12 @@
         // if useCaseCamera is null, zoom setting operation will be cancelled
         zoomControl.useCaseCamera = FakeUseCaseCamera()
 
-        zoomControl.setZoomRatioAsync(3.0f)[3, TimeUnit.SECONDS]
+        val expectedZoomState = ZoomValue(3.0f, 1.0f, 10.0f)
+        zoomControl.setZoomValue(expectedZoomState)[3, TimeUnit.SECONDS]
 
-        // minZoom and maxZoom will be set as 0 due to FakeZoomCompat using those values
-        assertWithMessage("zoomState did not return default zoom ratio successfully")
+        assertWithMessage("zoomState did not return the correct zoom state successfully")
             .that(currentZoomState)
-            .isEqualTo(ZoomValue(3.0f, zoomControl.minZoom, zoomControl.maxZoom))
+            .isEqualTo(expectedZoomState)
     }
 
     @Test
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CoroutineAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CoroutineAdapterTest.kt
new file mode 100644
index 0000000..87533ee
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CoroutineAdapterTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.pipe.integration.adapter
+
+import android.os.Build
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+
+@RunWith(RobolectricCameraPipeTestRunner::class)
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+@DoNotInstrument
+class CoroutineAdapterTest {
+    @Test
+    fun propagateCompleteResult(): Unit = runBlocking {
+        // Arrange.
+        val resultValue = 123
+        val sourceDeferred = CompletableDeferred<Int>()
+        val resultDeferred = CompletableDeferred<Int>()
+        sourceDeferred.propagateTo(resultDeferred)
+
+        // Act.
+        sourceDeferred.complete(resultValue)
+
+        // Assert.
+        assertThat(resultDeferred.await()).isEqualTo(resultValue)
+    }
+
+    @Test
+    fun propagateCancelResult() {
+        // Arrange.
+        val sourceDeferred = CompletableDeferred<Unit>()
+        val resultDeferred = CompletableDeferred<Unit>()
+        sourceDeferred.propagateTo(resultDeferred)
+
+        // Act.
+        sourceDeferred.cancel()
+
+        // Assert.
+        assertThat(resultDeferred.isCancelled).isTrue()
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun propagateExceptionResult() {
+        // Arrange.
+        val sourceDeferred = CompletableDeferred<Unit>()
+        val resultDeferred = CompletableDeferred<Unit>()
+        sourceDeferred.propagateTo(resultDeferred)
+        val testThrowable = Throwable()
+
+        // Act.
+        sourceDeferred.completeExceptionally(testThrowable)
+
+        // Assert.
+        assertThat(resultDeferred.getCompletionExceptionOrNull()).isSameInstanceAs(testThrowable)
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt
index 157d7a7..d1c277d 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt
@@ -29,6 +29,7 @@
 import android.util.Size
 import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.Result3A
+import androidx.camera.camera2.pipe.integration.compat.ZoomCompat
 import androidx.camera.camera2.pipe.integration.impl.CameraProperties
 import androidx.camera.camera2.pipe.integration.impl.FocusMeteringControl
 import androidx.camera.camera2.pipe.integration.impl.State3AControl
@@ -37,6 +38,7 @@
 import androidx.camera.camera2.pipe.integration.impl.UseCaseThreads
 import androidx.camera.camera2.pipe.integration.testing.FakeCameraProperties
 import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCameraRequestControl
+import androidx.camera.camera2.pipe.integration.testing.FakeZoomCompat
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
 import androidx.camera.camera2.pipe.testing.FakeFrameMetadata
 import androidx.camera.core.CameraControl
@@ -409,6 +411,82 @@
     }
 
     @Test
+    fun cropRegionIsSet_resultBasedOnCropRegion() {
+        val cropWidth = 480
+        val cropHeight = 360
+        val cropRect = Rect(
+            SENSOR_WIDTH / 2 - cropWidth / 2,
+            SENSOR_HEIGHT / 2 - cropHeight / 2,
+            SENSOR_WIDTH / 2 + cropWidth / 2, SENSOR_HEIGHT / 2 + cropHeight / 2
+        )
+
+        focusMeteringControl = initFocusMeteringControl(
+            cameraId = CAMERA_ID_0,
+            zoomCompat = FakeZoomCompat(croppedSensorArea = cropRect),
+        )
+
+        val centerPt = pointFactory.createPoint(0.5f, 0.5f)
+        startFocusMeteringAndAwait(
+            FocusMeteringAction.Builder(centerPt).build()
+        )
+
+        val areaWidth = (MeteringPointFactory.getDefaultPointSize() * cropRect.width()).toInt()
+        val areaHeight = (MeteringPointFactory.getDefaultPointSize() * cropRect.height()).toInt()
+        val adjustedRect = Rect(
+            cropRect.centerX() - areaWidth / 2,
+            cropRect.centerY() - areaHeight / 2,
+            cropRect.centerX() + areaWidth / 2,
+            cropRect.centerY() + areaHeight / 2
+        )
+        with(fakeRequestControl.focusMeteringCalls.last()) {
+            assertWithMessage("Wrong number of AF regions").that(afRegions.size).isEqualTo(1)
+            assertWithMessage("Wrong AF region")
+                .that(afRegions[0].rect).isEqualTo(adjustedRect)
+        }
+    }
+
+    @Test
+    fun cropRegionIsSetTwice_resultAlwaysBasedOnCurrentCropRegion() {
+        val cropWidth = 480
+        val cropHeight = 360
+        val cropRect = Rect(
+            SENSOR_WIDTH / 2 - cropWidth / 2,
+            SENSOR_HEIGHT / 2 - cropHeight / 2,
+            SENSOR_WIDTH / 2 + cropWidth / 2, SENSOR_HEIGHT / 2 + cropHeight / 2
+        )
+
+        val zoomCompat = FakeZoomCompat(croppedSensorArea = Rect(0, 0, 640, 480))
+        focusMeteringControl = initFocusMeteringControl(
+            cameraId = CAMERA_ID_0,
+            zoomCompat = zoomCompat,
+        )
+
+        val centerPt = pointFactory.createPoint(0.5f, 0.5f)
+        startFocusMeteringAndAwait(
+            FocusMeteringAction.Builder(centerPt).build()
+        )
+
+        zoomCompat.croppedSensorArea = cropRect
+        startFocusMeteringAndAwait(
+            FocusMeteringAction.Builder(centerPt).build()
+        )
+
+        val areaWidth = (MeteringPointFactory.getDefaultPointSize() * cropRect.width()).toInt()
+        val areaHeight = (MeteringPointFactory.getDefaultPointSize() * cropRect.height()).toInt()
+        val adjustedRect = Rect(
+            cropRect.centerX() - areaWidth / 2,
+            cropRect.centerY() - areaHeight / 2,
+            cropRect.centerX() + areaWidth / 2,
+            cropRect.centerY() + areaHeight / 2
+        )
+        with(fakeRequestControl.focusMeteringCalls.last()) {
+            assertWithMessage("Wrong number of AF regions").that(afRegions.size).isEqualTo(1)
+            assertWithMessage("Wrong AF region")
+                .that(afRegions[0].rect).isEqualTo(adjustedRect)
+        }
+    }
+
+    @Test
     fun previewFovAdjusted_16by9_to_4by3() {
         // use 16:9 preview aspect ratio with sensor region of 4:3 (camera 0)
         focusMeteringControl = initFocusMeteringControl(
@@ -431,8 +509,9 @@
     fun previewFovAdjusted_4by3_to_16by9() {
         // use 4:3 preview aspect ratio with sensor region of 16:9 (camera 1)
         focusMeteringControl = initFocusMeteringControl(
-            CAMERA_ID_1,
-            setOf(createPreview(Size(640, 480))),
+            cameraId = CAMERA_ID_1,
+            useCases = setOf(createPreview(Size(640, 480))),
+            zoomCompat = FakeZoomCompat(croppedSensorArea = Rect(0, 0, 1920, 1080))
         )
 
         startFocusMeteringAndAwait(
@@ -1031,7 +1110,6 @@
     //  - [b/255679866] triggerAfWithTemplate, triggerAePrecaptureWithTemplate,
     //          cancelAfAeTriggerWithTemplate
     //  - startFocusAndMetering_AfRegionCorrectedByQuirk
-    //  - [b/262225455] cropRegionIsSet_resultBasedOnCropRegion
 
     private fun assertFutureFocusCompleted(
         future: ListenableFuture<FocusMeteringResult>,
@@ -1126,10 +1204,12 @@
         useCases: Set<UseCase> = emptySet(),
         useCaseThreads: UseCaseThreads = fakeUseCaseThreads,
         state3AControl: State3AControl = createState3AControl(cameraId),
+        zoomCompat: ZoomCompat = FakeZoomCompat()
     ) = FocusMeteringControl(
             cameraPropertiesMap[cameraId]!!,
             state3AControl,
-            useCaseThreads
+            useCaseThreads,
+            zoomCompat
         ).apply {
             fakeUseCaseCamera.runningUseCases = useCases
             useCaseCamera = fakeUseCaseCamera
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt
index 59295e2..23571ca 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt
@@ -21,7 +21,10 @@
 import android.hardware.camera2.CameraCharacteristics
 import android.hardware.camera2.CameraManager
 import android.hardware.camera2.params.StreamConfigurationMap
-import android.media.CamcorderProfile
+import android.media.CamcorderProfile.QUALITY_1080P
+import android.media.CamcorderProfile.QUALITY_2160P
+import android.media.CamcorderProfile.QUALITY_480P
+import android.media.CamcorderProfile.QUALITY_720P
 import android.media.MediaRecorder
 import android.os.Build
 import android.util.Pair
@@ -50,8 +53,9 @@
 import androidx.camera.core.Preview
 import androidx.camera.core.SurfaceRequest
 import androidx.camera.core.UseCase
-import androidx.camera.core.impl.CamcorderProfileProxy
 import androidx.camera.core.impl.CameraThreadConfig
+import androidx.camera.core.impl.EncoderProfilesProxy
+import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy
 import androidx.camera.core.impl.MutableStateObservable
 import androidx.camera.core.impl.Observable
 import androidx.camera.core.impl.StreamSpec
@@ -61,16 +65,15 @@
 import androidx.camera.core.impl.UseCaseConfigFactory
 import androidx.camera.core.impl.utils.CompareSizesByArea
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
-import androidx.camera.testing.CamcorderProfileUtil
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.CameraXUtil
 import androidx.camera.testing.Configs
+import androidx.camera.testing.EncoderProfilesUtil
 import androidx.camera.testing.SurfaceTextureProvider
-import androidx.camera.testing.SurfaceTextureProvider.SurfaceTextureCallback
-import androidx.camera.testing.fakes.FakeCamcorderProfileProvider
 import androidx.camera.testing.fakes.FakeCamera
 import androidx.camera.testing.fakes.FakeCameraFactory
 import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import androidx.camera.testing.fakes.FakeEncoderProfilesProvider
 import androidx.camera.testing.fakes.FakeUseCaseConfig
 import androidx.camera.video.FallbackStrategy
 import androidx.camera.video.MediaSpec
@@ -125,20 +128,17 @@
     private val legacyVideoMaximumVideoSize = Size(1920, 1080)
     private val mod16Size = Size(960, 544)
     private val mod16SizeStreamSpec = StreamSpec.builder(mod16Size).build()
-    private val profileUhd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_2160P, recordSize.width, recordSize
-            .height
+    private val profileUhd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        recordSize.width, recordSize.height
     )
-    private val profileFhd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_1080P, 1920, 1080
+    private val profileFhd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        1920, 1080
     )
-    private val profileHd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_720P, previewSize.width, previewSize
-            .height
+    private val profileHd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        previewSize.width, previewSize.height
     )
-    private val profileSd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_480P, vgaSize.width,
-        vgaSize.height
+    private val profileSd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        vgaSize.width, vgaSize.height
     )
     private val supportedSizes = arrayOf(
         Size(4032, 3024), // 4:3
@@ -161,8 +161,9 @@
     private lateinit var fakeCameraMetadata: FakeCameraMetadata
 
     private val mockCameraAppComponent: CameraAppComponent = mock()
-    private val mockCamcorderProfileAdapter: CamcorderProfileProviderAdapter = mock()
-    private val mockCamcorderProxy: CamcorderProfileProxy = mock()
+    private val mockEncoderProfilesAdapter: EncoderProfilesProviderAdapter = mock()
+    private val mockEncoderProfilesProxy: EncoderProfilesProxy = mock()
+    private val mockVideoProfileProxy: VideoProfileProxy = mock()
 
     @Before
     fun setUp() {
@@ -172,12 +173,12 @@
             displaySize
                 .height
         )
-        whenever(mockCamcorderProfileAdapter.hasProfile(ArgumentMatchers.anyInt()))
-            .thenReturn(true)
-        whenever(mockCamcorderProxy.videoFrameWidth).thenReturn(3840)
-        whenever(mockCamcorderProxy.videoFrameHeight).thenReturn(2160)
-        whenever(mockCamcorderProfileAdapter[ArgumentMatchers.anyInt()])
-            .thenReturn(mockCamcorderProxy)
+        whenever(mockEncoderProfilesAdapter.hasProfile(ArgumentMatchers.anyInt())).thenReturn(true)
+        whenever(mockVideoProfileProxy.width).thenReturn(3840)
+        whenever(mockVideoProfileProxy.height).thenReturn(2160)
+        whenever(mockEncoderProfilesProxy.videoProfiles).thenReturn(listOf(mockVideoProfileProxy))
+        whenever(mockEncoderProfilesAdapter.getAll(ArgumentMatchers.anyInt()))
+            .thenReturn(mockEncoderProfilesProxy)
     }
 
     @After
@@ -190,7 +191,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLegacySupportedCombinationList()
         for (combination in combinationList) {
@@ -205,7 +206,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLegacySupportedCombinationList()
         val isSupported = isAllSubConfigListSupported(supportedSurfaceCombination, combinationList)
@@ -217,7 +218,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLimitedSupportedCombinationList()
         for (combination in combinationList) {
@@ -232,7 +233,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getFullSupportedCombinationList()
         for (combination in combinationList) {
@@ -247,7 +248,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLevel3SupportedCombinationList()
         for (combination in combinationList) {
@@ -262,7 +263,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLimitedSupportedCombinationList()
         for (combination in combinationList) {
@@ -277,7 +278,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLimitedSupportedCombinationList()
         val isSupported = isAllSubConfigListSupported(supportedSurfaceCombination, combinationList)
@@ -289,7 +290,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getFullSupportedCombinationList()
         for (combination in combinationList) {
@@ -304,7 +305,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLevel3SupportedCombinationList()
         for (combination in combinationList) {
@@ -319,7 +320,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getFullSupportedCombinationList()
         for (combination in combinationList) {
@@ -334,7 +335,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getFullSupportedCombinationList()
         val isSupported = isAllSubConfigListSupported(supportedSurfaceCombination, combinationList)
@@ -346,7 +347,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLevel3SupportedCombinationList()
         for (combination in combinationList) {
@@ -365,7 +366,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLimitedSupportedCombinationList()
         for (combination in combinationList) {
@@ -384,7 +385,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLegacySupportedCombinationList()
         for (combination in combinationList) {
@@ -403,7 +404,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getFullSupportedCombinationList()
         for (combination in combinationList) {
@@ -422,7 +423,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getRAWSupportedCombinationList()
         for (combination in combinationList) {
@@ -437,7 +438,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLevel3SupportedCombinationList()
         for (combination in combinationList) {
@@ -452,7 +453,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val combinationList = getLevel3SupportedCombinationList()
         val isSupported = isAllSubConfigListSupported(supportedSurfaceCombination, combinationList)
@@ -464,7 +465,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val fakeUseCase = FakeUseCaseConfig.Builder()
             .setTargetAspectRatio(AspectRatio.RATIO_16_9)
@@ -499,7 +500,7 @@
             .build()
         preview.setSurfaceProvider(
             CameraXExecutors.directExecutor(),
-            SurfaceTextureProvider.createSurfaceTextureProvider(mock<SurfaceTextureCallback>())
+            SurfaceTextureProvider.createSurfaceTextureProvider(mock())
         )
         val imageCapture = ImageCapture.Builder()
             .setTargetAspectRatio(AspectRatio.RATIO_16_9)
@@ -540,12 +541,12 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val preview = Preview.Builder().build()
         preview.setSurfaceProvider(
             CameraXExecutors.directExecutor(),
-            SurfaceTextureProvider.createSurfaceTextureProvider(mock<SurfaceTextureCallback>())
+            SurfaceTextureProvider.createSurfaceTextureProvider(mock())
         )
         val imageCapture = ImageCapture.Builder().build()
         val imageAnalysis = ImageAnalysis.Builder().build()
@@ -610,7 +611,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         /* This test case is for b/139018208 that get small resolution 144x256 with below
@@ -658,7 +659,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         // Sets each of mSupportedSizes as target resolution and also sets target rotation as
@@ -685,7 +686,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         // Sets target resolution as 1280x640, all supported resolutions will be put into aspect
@@ -709,7 +710,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val imageCapture = ImageCapture.Builder()
             .setTargetAspectRatio(AspectRatio.RATIO_16_9)
@@ -740,7 +741,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         // Legacy camera only support (PRIV, PREVIEW) + (PRIV, PREVIEW)
@@ -774,7 +775,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val imageCapture = ImageCapture.Builder()
             .setTargetAspectRatio(AspectRatio.RATIO_16_9)
@@ -818,7 +819,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val imageCapture = ImageCapture.Builder()
             .setTargetAspectRatio(AspectRatio.RATIO_16_9)
@@ -869,7 +870,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val imageCapture = ImageCapture.Builder()
             .setTargetAspectRatio(AspectRatio.RATIO_4_3) // mMaximumSize(4032x3024) is 4:3
@@ -919,7 +920,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         /* This test case is for b/132603284 that divide by zero issue crash happened in below
@@ -1007,7 +1008,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val formatResolutionsPairList: MutableList<Pair<Int, Array<Size>>> = ArrayList()
         formatResolutionsPairList.add(Pair.create(ImageFormat.JPEG, arrayOf(vgaSize)))
@@ -1059,7 +1060,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.YUV_420_888, vgaSize
@@ -1074,7 +1075,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.YUV_420_888, previewSize
@@ -1089,7 +1090,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.YUV_420_888, recordSize
@@ -1104,7 +1105,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.YUV_420_888, maximumSize
@@ -1119,7 +1120,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.JPEG, vgaSize
@@ -1134,7 +1135,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.JPEG, previewSize
@@ -1149,7 +1150,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.JPEG, recordSize
@@ -1164,7 +1165,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val surfaceConfig = supportedSurfaceCombination.transformSurfaceConfig(
             ImageFormat.JPEG, maximumSize
@@ -1179,7 +1180,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val maximumYUVSize =
             supportedSurfaceCombination.getMaxOutputSizeByFormat(ImageFormat.YUV_420_888)
@@ -1194,7 +1195,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val preview = Preview.Builder()
             .setTargetAspectRatio(AspectRatio.RATIO_16_9)
@@ -1256,7 +1257,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().build()
 
@@ -1285,7 +1286,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetAspectRatio(AspectRatio.RATIO_4_3)
             .build()
@@ -1319,7 +1320,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetAspectRatio(
             AspectRatio.RATIO_16_9
@@ -1354,7 +1355,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetResolution(
             Size(1080, 1920)
@@ -1391,7 +1392,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetRotation(
             Surface.ROTATION_90
@@ -1427,7 +1428,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetRotation(
             Surface.ROTATION_90
@@ -1458,7 +1459,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetRotation(
             Surface.ROTATION_90
@@ -1491,7 +1492,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetResolution(
             Size(1280, 600)
@@ -1521,7 +1522,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setMaxResolution(Size(1280, 720)).build()
 
@@ -1545,7 +1546,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val customOrderedResolutions = listOf(
             Size(640, 480),
@@ -1583,7 +1584,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setDefaultResolution(
             Size(
@@ -1613,7 +1614,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setDefaultResolution(
             Size(1280, 720)
@@ -1657,7 +1658,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetResolution(
             Size(1920, 1080)
@@ -1685,7 +1686,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setMaxResolution(
             Size(320, 240)
@@ -1718,7 +1719,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setMaxResolution(
             Size(320, 180)
@@ -1753,7 +1754,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setMaxResolution(
             Size(320, 240)
@@ -1782,7 +1783,7 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setMaxResolution(
             Size(1920, 1080)
@@ -1826,7 +1827,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setMaxResolution(
             Size(320, 200)
@@ -1861,7 +1862,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetResolution(
             Size(192, 144)
@@ -1893,7 +1894,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setMaxResolution(
             Size(192, 144)
@@ -1919,7 +1920,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetResolution(
             Size(185, 90)
@@ -1959,7 +1960,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetResolution(
             Size(1080, 2016)
@@ -2000,7 +2001,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetAspectRatio(
             AspectRatio.RATIO_16_9
@@ -2050,7 +2051,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetAspectRatio(
             AspectRatio.RATIO_16_9
@@ -2087,7 +2088,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetAspectRatio(
             AspectRatio.RATIO_16_9
@@ -2135,7 +2136,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val useCase = FakeUseCaseConfig.Builder().setTargetAspectRatio(
             AspectRatio.RATIO_16_9
@@ -2172,7 +2173,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         // Checks the determined RECORD size
@@ -2201,7 +2202,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         // Sets the target resolution as 640x480 with target rotation as ROTATION_90 because the
@@ -2229,7 +2230,7 @@
         )
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
 
         // Sets the max resolution as 720x1280
@@ -2250,13 +2251,13 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val preview = Preview.Builder().build()
         preview.setSurfaceProvider(
             CameraXExecutors.directExecutor(),
             SurfaceTextureProvider.createSurfaceTextureProvider(
-                mock<SurfaceTextureCallback>()
+                mock()
             )
         )
 
@@ -2299,13 +2300,13 @@
         setupCamera(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
         val supportedSurfaceCombination = SupportedSurfaceCombination(
             context, fakeCameraMetadata,
-            mockCamcorderProfileAdapter
+            mockEncoderProfilesAdapter
         )
         val preview = Preview.Builder().build()
         preview.setSurfaceProvider(
             CameraXExecutors.directExecutor(),
             SurfaceTextureProvider.createSurfaceTextureProvider(
-                mock<SurfaceTextureCallback>()
+                mock()
             )
         )
 
@@ -2428,15 +2429,12 @@
             CameraCharacteristics.LENS_FACING_BACK
         )
         val cameraInfo = FakeCameraInfoInternal(fakeCameraMetadata.camera.value)
-        cameraInfo.camcorderProfileProvider = FakeCamcorderProfileProvider.Builder()
-            .addProfile(
-                CamcorderProfileUtil.asHighQuality(profileUhd),
-                profileUhd,
-                profileFhd,
-                profileHd,
-                profileSd,
-                CamcorderProfileUtil.asLowQuality(profileSd)
-            ).build()
+        cameraInfo.encoderProfilesProvider = FakeEncoderProfilesProvider.Builder()
+            .add(QUALITY_2160P, profileUhd)
+            .add(QUALITY_1080P, profileFhd)
+            .add(QUALITY_720P, profileHd)
+            .add(QUALITY_480P, profileSd)
+            .build()
         cameraFactory!!.insertCamera(
             lensFacingEnum, fakeCameraMetadata.camera.value
         ) { FakeCamera(fakeCameraMetadata.camera.value, null, cameraInfo) }
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/EvCompControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/EvCompControlTest.kt
index d1c5f1c..59d5f6e 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/EvCompControlTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/EvCompControlTest.kt
@@ -17,17 +17,26 @@
 package androidx.camera.camera2.pipe.integration.impl
 
 import android.hardware.camera2.CameraCharacteristics
+import android.hardware.camera2.CaptureRequest
+import android.hardware.camera2.CaptureResult
 import android.os.Build
 import android.util.Range
 import android.util.Rational
+import androidx.camera.camera2.pipe.FrameNumber
+import androidx.camera.camera2.pipe.RequestNumber
 import androidx.camera.camera2.pipe.integration.adapter.RobolectricCameraPipeTestRunner
 import androidx.camera.camera2.pipe.integration.compat.EvCompImpl
 import androidx.camera.camera2.pipe.integration.testing.FakeCameraProperties
 import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCamera
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
+import androidx.camera.camera2.pipe.testing.FakeFrameInfo
+import androidx.camera.camera2.pipe.testing.FakeFrameMetadata
+import androidx.camera.camera2.pipe.testing.FakeRequestMetadata
 import androidx.camera.core.CameraControl
 import androidx.testutils.assertThrows
 import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.Job
@@ -39,8 +48,6 @@
 import org.junit.runner.RunWith
 import org.robolectric.annotation.Config
 import org.robolectric.annotation.internal.DoNotInstrument
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
 
 @RunWith(RobolectricCameraPipeTestRunner::class)
 @DoNotInstrument
@@ -146,9 +153,68 @@
         }
     }
 
+    @Test
+    fun useCaseCameraUpdated_setExposureResultShouldPropagate(): Unit = runBlocking {
+        val targetEv = 1
+        val deferred = exposureControl.updateAsync(targetEv)
+
+        // Act. Simulate the UseCaseCamera is recreated.
+        exposureControl.useCaseCamera = FakeUseCaseCamera()
+        comboRequestListener.simulateAeConverge(exposureValue = targetEv)
+
+        // Assert. The setEV task should be completed.
+        assertThat(deferred.awaitWithTimeout()).isEqualTo(targetEv)
+    }
+
+    @Test
+    fun useCaseCameraUpdated_onlyCompleteLatestRequest(): Unit = runBlocking {
+        val targetEv = 2
+        val deferred = exposureControl.updateAsync(1)
+
+        // Act. Simulate the UseCaseCamera is recreated,
+        exposureControl.useCaseCamera = FakeUseCaseCamera()
+        // Act. Submits a new EV value.
+        val deferred2 = exposureControl.updateAsync(targetEv)
+        comboRequestListener.simulateAeConverge(exposureValue = targetEv)
+
+        // Assert. The previous setEV task should be cancelled
+        assertThrows<CameraControl.OperationCanceledException> {
+            deferred.awaitWithTimeout()
+        }
+        // Assert. The latest setEV task should be completed.
+        assertThat(deferred2.awaitWithTimeout()).isEqualTo(targetEv)
+    }
+
     private suspend fun Deferred<Int>.awaitWithTimeout(
         timeMillis: Long = TimeUnit.SECONDS.toMillis(5)
     ) = withTimeout(timeMillis) {
         await()
     }
+
+    private fun ComboRequestListener.simulateAeConverge(
+        exposureValue: Int,
+        frameNumber: FrameNumber = FrameNumber(101L),
+    ) {
+        val requestMetadata = FakeRequestMetadata(
+            requestParameters = mapOf(
+                CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION to exposureValue
+            ),
+            requestNumber = RequestNumber(1)
+        )
+        val resultMetaData = FakeFrameMetadata(
+            resultMetadata = mapOf(
+                CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION to exposureValue,
+                CaptureResult.CONTROL_AE_STATE to CaptureResult.CONTROL_AE_STATE_CONVERGED,
+            ),
+            frameNumber = frameNumber,
+        )
+        fakeUseCaseThreads.sequentialExecutor.execute {
+            onComplete(
+                requestMetadata, frameNumber, FakeFrameInfo(
+                    metadata = resultMetaData,
+                    requestMetadata = requestMetadata,
+                )
+            )
+        }
+    }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/FlashControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/FlashControlTest.kt
new file mode 100644
index 0000000..e3559f1
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/FlashControlTest.kt
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.pipe.integration.impl
+
+import android.hardware.camera2.CameraCharacteristics
+import android.hardware.camera2.CaptureRequest
+import android.os.Build
+import androidx.camera.camera2.pipe.integration.adapter.RobolectricCameraPipeTestRunner
+import androidx.camera.camera2.pipe.integration.testing.FakeCameraProperties
+import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCamera
+import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCameraRequestControl
+import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
+import androidx.camera.core.CameraControl
+import androidx.camera.core.ImageCapture
+import androidx.testutils.assertThrows
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.MoreExecutors
+import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeout
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+
+@RunWith(RobolectricCameraPipeTestRunner::class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+class FlashControlTest {
+    private val fakeUseCaseThreads by lazy {
+        val executor = MoreExecutors.directExecutor()
+        val dispatcher = executor.asCoroutineDispatcher()
+        val cameraScope = CoroutineScope(Job() + dispatcher)
+
+        UseCaseThreads(
+            cameraScope,
+            executor,
+            dispatcher,
+        )
+    }
+    private val metadata = FakeCameraMetadata(
+        mapOf(
+            CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES to intArrayOf(
+                CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH,
+                CaptureRequest.CONTROL_AE_MODE_ON,
+                CaptureRequest.CONTROL_AE_MODE_OFF,
+                CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH
+            ),
+        ),
+    )
+    private val fakeRequestControl = FakeUseCaseCameraRequestControl()
+    private val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+    private val state3AControl = State3AControl(FakeCameraProperties(metadata)).apply {
+        useCaseCamera = fakeUseCaseCamera
+    }
+    private lateinit var flashControl: FlashControl
+
+    @Before
+    fun setUp() {
+        flashControl = FlashControl(
+            state3AControl = state3AControl,
+            threads = fakeUseCaseThreads,
+        )
+        flashControl.useCaseCamera = fakeUseCaseCamera
+    }
+
+    @Test
+    fun setFlash_whenInactive(): Unit = runBlocking {
+        val fakeUseCaseCamera = FakeUseCaseCamera()
+        val fakeCameraProperties = FakeCameraProperties()
+
+        val flashControl = FlashControl(
+            State3AControl(fakeCameraProperties).apply {
+                useCaseCamera = fakeUseCaseCamera
+            },
+            fakeUseCaseThreads,
+        )
+
+        assertThrows<CameraControl.OperationCanceledException> {
+            flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON).awaitWithTimeout()
+        }
+    }
+
+    @Test
+    fun setFlash_flashModeOn(): Unit = runBlocking {
+        // Arrange, clear data of the initial invocations.
+        fakeRequestControl.addParameterCalls.clear()
+
+        // Act.
+        flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON).awaitWithTimeout()
+
+        // Assert. AE mode should change accordingly.
+        assertThat(fakeRequestControl.addParameterCalls).hasSize(1)
+        assertThat(fakeRequestControl.addParameterCalls[0]).containsAtLeastEntriesIn(
+            mapOf(CaptureRequest.CONTROL_AE_MODE to CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH)
+        )
+    }
+
+    @Test
+    fun setFlash_flashModeAuto(): Unit = runBlocking {
+        // Arrange, clear data of the initial invocations.
+        fakeRequestControl.addParameterCalls.clear()
+
+        // Act.
+        flashControl.setFlashAsync(ImageCapture.FLASH_MODE_AUTO).awaitWithTimeout()
+
+        // Assert. AE mode should change accordingly.
+        assertThat(fakeRequestControl.addParameterCalls).hasSize(1)
+        assertThat(fakeRequestControl.addParameterCalls[0]).containsAtLeastEntriesIn(
+            mapOf(CaptureRequest.CONTROL_AE_MODE to CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)
+        )
+    }
+
+    @Test
+    fun setFlash_flashModeOnThenOff(): Unit = runBlocking {
+        // Arrange, clear data of the initial invocations.
+        fakeRequestControl.addParameterCalls.clear()
+
+        // Act.
+        flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON).awaitWithTimeout()
+        flashControl.setFlashAsync(ImageCapture.FLASH_MODE_OFF).awaitWithTimeout()
+
+        // Assert. AE mode should change accordingly.
+        assertThat(fakeRequestControl.addParameterCalls).hasSize(2)
+        assertThat(fakeRequestControl.addParameterCalls[0]).containsAtLeastEntriesIn(
+            mapOf(CaptureRequest.CONTROL_AE_MODE to CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH)
+        )
+        assertThat(fakeRequestControl.addParameterCalls[1]).containsAtLeastEntriesIn(
+            mapOf(CaptureRequest.CONTROL_AE_MODE to CaptureRequest.CONTROL_AE_MODE_ON)
+        )
+    }
+
+    @Test
+    fun setFlashTwice_cancelPreviousFuture(): Unit = runBlocking {
+        // Arrange. Set a never complete deferred.
+        fakeRequestControl.addParameterResult = CompletableDeferred()
+
+        // Act. call setFlashAsync twice.
+        val deferred = flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON)
+        flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON)
+
+        assertThrows<CameraControl.OperationCanceledException> {
+            deferred.awaitWithTimeout()
+        }
+    }
+
+    @Test
+    fun setInActive_cancelPreviousFuture(): Unit = runBlocking {
+        // Arrange. Set a never complete deferred.
+        fakeRequestControl.addParameterResult = CompletableDeferred()
+        val deferred = flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON)
+
+        // Act. call reset & clear the UseCaseCamera.
+        flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON)
+        flashControl.reset()
+        flashControl.useCaseCamera = null
+
+        assertThrows<CameraControl.OperationCanceledException> {
+            deferred.awaitWithTimeout()
+        }
+    }
+
+    @Test
+    fun useCaseCameraUpdated_setFlashResultShouldPropagate(): Unit = runBlocking {
+        // Arrange.
+        fakeRequestControl.addParameterResult = CompletableDeferred()
+
+        val deferred = flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON)
+        val fakeRequestControl = FakeUseCaseCameraRequestControl().apply {
+            addParameterResult = CompletableDeferred()
+        }
+        val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+
+        // Act. Simulate the UseCaseCamera is recreated.
+        flashControl.useCaseCamera = fakeUseCaseCamera
+        state3AControl.useCaseCamera = fakeUseCaseCamera
+
+        // Simulate setFlash is completed on the recreated UseCaseCamera
+        fakeRequestControl.addParameterResult.complete(Unit)
+
+        // Assert. The setFlash task should be completed.
+        assertThat(deferred.awaitWithTimeout()).isNotNull()
+    }
+
+    @Test
+    fun useCaseCameraUpdated_onlyCompleteLatestRequest(): Unit = runBlocking {
+        // Arrange.
+        fakeRequestControl.addParameterResult = CompletableDeferred()
+
+        val deferred = flashControl.setFlashAsync(ImageCapture.FLASH_MODE_ON)
+        val fakeRequestControl = FakeUseCaseCameraRequestControl().apply {
+            addParameterResult = CompletableDeferred()
+        }
+        val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+
+        // Act. Simulate the UseCaseCamera is recreated.
+        flashControl.useCaseCamera = fakeUseCaseCamera
+        state3AControl.useCaseCamera = fakeUseCaseCamera
+        // Act. Submits a new Flash mode.
+        val deferred2 = flashControl.setFlashAsync(ImageCapture.FLASH_MODE_AUTO)
+        // Simulate setFlash is completed on the recreated UseCaseCamera
+        fakeRequestControl.addParameterResult.complete(Unit)
+
+        // Assert. The previous set Flash mode task should be cancelled
+        assertThrows<CameraControl.OperationCanceledException> {
+            deferred.awaitWithTimeout()
+        }
+        // Assert. The latest set Flash mode task should be completed.
+        assertThat(deferred2.awaitWithTimeout()).isNotNull()
+    }
+
+    private suspend fun <T> Deferred<T>.awaitWithTimeout(
+        timeMillis: Long = TimeUnit.SECONDS.toMillis(5)
+    ) = withTimeout(timeMillis) {
+        await()
+    }
+}
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/TorchControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/TorchControlTest.kt
index 6b24bc2..8aeaf43 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/TorchControlTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/TorchControlTest.kt
@@ -17,29 +17,23 @@
 package androidx.camera.camera2.pipe.integration.impl
 
 import android.hardware.camera2.CameraCharacteristics
-import android.hardware.camera2.CaptureRequest
-import android.hardware.camera2.params.MeteringRectangle
 import android.os.Build
-import androidx.camera.camera2.pipe.AeMode
-import androidx.camera.camera2.pipe.Request
-import androidx.camera.camera2.pipe.RequestTemplate
 import androidx.camera.camera2.pipe.Result3A
-import androidx.camera.camera2.pipe.StreamId
 import androidx.camera.camera2.pipe.integration.adapter.RobolectricCameraPipeTestRunner
 import androidx.camera.camera2.pipe.integration.testing.FakeCameraProperties
 import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCamera
+import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCameraRequestControl
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
 import androidx.camera.core.CameraControl
 import androidx.camera.core.TorchState
-import androidx.camera.core.impl.CaptureConfig
-import androidx.camera.core.impl.SessionConfig
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.Observer
 import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.testutils.assertThrows
 import com.google.common.truth.Truth
+import com.google.common.util.concurrent.MoreExecutors
 import java.util.Objects
-import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Deferred
@@ -48,7 +42,7 @@
 import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import org.junit.AfterClass
+import kotlinx.coroutines.withTimeout
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -62,7 +56,7 @@
 class TorchControlTest {
 
     companion object {
-        private val executor = Executors.newSingleThreadExecutor()
+        private val executor = MoreExecutors.directExecutor()
         private val fakeUseCaseThreads by lazy {
             val dispatcher = executor.asCoroutineDispatcher()
             val cameraScope = CoroutineScope(Job() + dispatcher)
@@ -73,12 +67,6 @@
                 dispatcher
             )
         }
-
-        @JvmStatic
-        @AfterClass
-        fun close() {
-            executor.shutdown()
-        }
     }
 
     private val metadata = FakeCameraMetadata(
@@ -87,60 +75,9 @@
         ),
     )
 
-    private val neverCompleteTorchRequestControl = object : UseCaseCameraRequestControl {
-        override fun addParametersAsync(
-            type: UseCaseCameraRequestControl.Type,
-            values: Map<CaptureRequest.Key<*>, Any>,
-            optionPriority: androidx.camera.core.impl.Config.OptionPriority,
-            tags: Map<String, Any>,
-            streams: Set<StreamId>?,
-            template: RequestTemplate?,
-            listeners: Set<Request.Listener>
-        ): Deferred<Unit> {
-            return CompletableDeferred(Unit)
-        }
-
-        override fun setConfigAsync(
-            type: UseCaseCameraRequestControl.Type,
-            config: androidx.camera.core.impl.Config?,
-            tags: Map<String, Any>,
-            streams: Set<StreamId>?,
-            template: RequestTemplate?,
-            listeners: Set<Request.Listener>
-        ): Deferred<Unit> {
-            return CompletableDeferred(Unit)
-        }
-
-        override fun setSessionConfigAsync(sessionConfig: SessionConfig): Deferred<Unit> {
-            return CompletableDeferred(Unit)
-        }
-
-        override suspend fun setTorchAsync(enabled: Boolean): Deferred<Result3A> {
-            // Return a CompletableDeferred without set it to completed.
-            return CompletableDeferred()
-        }
-
-        override suspend fun startFocusAndMeteringAsync(
-            aeRegions: List<MeteringRectangle>,
-            afRegions: List<MeteringRectangle>,
-            awbRegions: List<MeteringRectangle>,
-            afTriggerStartAeMode: AeMode?
-        ): Deferred<Result3A> {
-            return CompletableDeferred(Result3A(status = Result3A.Status.OK))
-        }
-
-        override suspend fun cancelFocusAndMeteringAsync(): Deferred<Result3A> {
-            return CompletableDeferred(Result3A(status = Result3A.Status.OK))
-        }
-
-        override suspend fun issueSingleCaptureAsync(
-            captureSequence: List<CaptureConfig>,
-            captureMode: Int,
-            flashType: Int,
-            flashMode: Int,
-        ): List<Deferred<Void?>> {
-            return listOf(CompletableDeferred(null))
-        }
+    private val neverCompleteTorchRequestControl = FakeUseCaseCameraRequestControl().apply {
+        // Set a CompletableDeferred without set it to completed.
+        setTorchResult = CompletableDeferred()
     }
 
     private lateinit var torchControl: TorchControl
@@ -309,4 +246,59 @@
         Truth.assertThat(receivedTorchState[1]).isEqualTo(TorchState.ON) // by setTorchAsync(true)
         Truth.assertThat(receivedTorchState[2]).isEqualTo(TorchState.OFF) // by setTorchAsync(false)
     }
+
+    @Test
+    fun useCaseCameraUpdated_setTorchResultShouldPropagate(): Unit = runBlocking {
+        // Arrange.
+        torchControl.useCaseCamera =
+            FakeUseCaseCamera(requestControl = neverCompleteTorchRequestControl)
+
+        val deferred = torchControl.setTorchAsync(true)
+        val fakeRequestControl = FakeUseCaseCameraRequestControl().apply {
+            setTorchResult = CompletableDeferred<Result3A>()
+        }
+        val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+
+        // Act. Simulate the UseCaseCamera is recreated.
+        torchControl.useCaseCamera = fakeUseCaseCamera
+
+        // Simulate setTorch is completed in the recreated UseCaseCamera
+        fakeRequestControl.setTorchResult.complete(Result3A(status = Result3A.Status.OK))
+
+        // Assert. The setTorch task should be completed.
+        Truth.assertThat(deferred.awaitWithTimeout()).isNotNull()
+    }
+
+    @Test
+    fun useCaseCameraUpdated_onlyCompleteLatestRequest(): Unit = runBlocking {
+        // Arrange.
+        torchControl.useCaseCamera =
+            FakeUseCaseCamera(requestControl = neverCompleteTorchRequestControl)
+
+        val deferred = torchControl.setTorchAsync(true)
+        val fakeRequestControl = FakeUseCaseCameraRequestControl().apply {
+            setTorchResult = CompletableDeferred()
+        }
+        val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+
+        // Act. Simulate the UseCaseCamera is recreated.
+        torchControl.useCaseCamera = fakeUseCaseCamera
+        // Act. Set Torch mode again.
+        val deferred2 = torchControl.setTorchAsync(false)
+        // Simulate setTorch is completed in the recreated UseCaseCamera
+        fakeRequestControl.setTorchResult.complete(Result3A(status = Result3A.Status.OK))
+
+        // Assert. The previous setTorch task should be cancelled
+        assertThrows<CameraControl.OperationCanceledException> {
+            deferred.awaitWithTimeout()
+        }
+        // Assert. The latest setTorch task should be completed.
+        Truth.assertThat(deferred2.awaitWithTimeout()).isNotNull()
+    }
+
+    private suspend fun <T> Deferred<T>.awaitWithTimeout(
+        timeMillis: Long = TimeUnit.SECONDS.toMillis(5)
+    ) = withTimeout(timeMillis) {
+        await()
+    }
 }
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/ZoomControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/ZoomControlTest.kt
index 600f8ab..1abf1d4 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/ZoomControlTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/ZoomControlTest.kt
@@ -54,7 +54,7 @@
         )
     }
 
-    private val zoomCompat = FakeZoomCompat()
+    private val zoomCompat = FakeZoomCompat(1.0f, 5.0f)
     private lateinit var zoomControl: ZoomControl
 
     @Before
@@ -66,9 +66,9 @@
 
     @Test
     fun canUpdateZoomRatioInCompat() {
-        zoomControl.setZoomRatioAsync(3.0f)[3, TimeUnit.SECONDS]
+        zoomControl.setZoomRatio(3.0f)[3, TimeUnit.SECONDS]
 
-        Truth.assertWithMessage("zoomState did not return default zoom state successfully")
+        Truth.assertWithMessage("zoomCompat not updated with correct zoom ratio")
             .that(zoomCompat.zoomRatio)
             .isEqualTo(3.0f)
     }
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/internal/ZoomMathTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/internal/ZoomMathTest.kt
new file mode 100644
index 0000000..f2fe667
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/internal/ZoomMathTest.kt
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.pipe.integration.internal
+
+import androidx.camera.camera2.pipe.integration.internal.ZoomMath.getLinearZoomFromZoomRatio
+import androidx.camera.camera2.pipe.integration.internal.ZoomMath.getZoomRatioFromLinearZoom
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+private const val CROP_REGION_TOLERANCE = 5f
+class ZoomMathTest {
+    private val minZoomRatio = 0.6f
+    private val maxZoomRatio = 8f
+
+    @Test
+    fun getLinearZoomFromZoomRatio_zoomRatioIsMin_linearZoomIs0() {
+        val linearZoom = getLinearZoomFromZoomRatio(
+            zoomRatio = minZoomRatio,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        )
+
+        assertThat(linearZoom).isEqualTo(0f)
+    }
+
+    @Test
+    fun getLinearZoomFromZoomRatio_zoomRatioIsMax_linearZoomIs1() {
+        val linearZoom = getLinearZoomFromZoomRatio(
+            zoomRatio = maxZoomRatio,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        )
+
+        assertThat(linearZoom).isEqualTo(1f)
+    }
+
+    @Test
+    fun getLinearZoomFromZoomRatio_zoomUnsupported_linearZoomIs0() {
+        // zoom unsupported means minZoomRatio = maxZoomRatio
+        val linearZoom = getLinearZoomFromZoomRatio(
+            zoomRatio = 1.0f,
+            minZoomRatio = 1.0f,
+            maxZoomRatio = 1.0f
+        )
+
+        assertThat(linearZoom).isEqualTo(0f)
+    }
+
+    @Test
+    fun getZoomRatioFromLinearZoom_linearZoomIs0_zoomRatioIsMin() {
+        val zoomRatio = getZoomRatioFromLinearZoom(
+            linearZoom = 0f,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        )
+
+        assertThat(zoomRatio).isEqualTo(minZoomRatio)
+    }
+
+    @Test
+    fun getZoomRatioFromLinearZoom_linearZoomIs1_zoomRatioIsMax() {
+        val zoomRatio = getZoomRatioFromLinearZoom(
+            linearZoom = 1.0f,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        )
+
+        assertThat(zoomRatio).isEqualTo(maxZoomRatio)
+    }
+
+    @Test
+    fun getZoomRatioFromLinearZoom_zoomUnsupportedAndLinearZoom0_zoomRatioIsTheAllowedValue() {
+        // zoom unsupported means minZoomRatio = maxZoomRatio
+        val zoomRatio = getZoomRatioFromLinearZoom(
+            linearZoom = 0f,
+            minZoomRatio = 1.0f,
+            maxZoomRatio = 1.0f
+        )
+
+        assertThat(zoomRatio).isEqualTo(1.0f)
+    }
+
+    @Test
+    fun getZoomRatioFromLinearZoom_zoomUnsupportedAndLinearZoom0_5f_zoomRatioIsTheAllowedValue() {
+        // zoom unsupported means minZoomRatio = maxZoomRatio
+        val zoomRatio = getZoomRatioFromLinearZoom(
+            linearZoom = 0.5f,
+            minZoomRatio = 1.0f,
+            maxZoomRatio = 1.0f
+        )
+
+        assertThat(zoomRatio).isEqualTo(1.0f)
+    }
+
+    @Test
+    fun getZoomRatioFromLinearZoom_zoomUnsupportedAndLinearZoom1_zoomRatioIsTheAllowedValue() {
+        // zoom unsupported means minZoomRatio = maxZoomRatio
+        val zoomRatio = getZoomRatioFromLinearZoom(
+            linearZoom = 1.0f,
+            minZoomRatio = 1.0f,
+            maxZoomRatio = 1.0f
+        )
+
+        assertThat(zoomRatio).isEqualTo(1.0f)
+    }
+
+    @Test
+    fun getLinearZoomFromZoomRatio_getZoomRatioFromLinearZoomReturnsSameRatio() {
+        val linearZoom = getLinearZoomFromZoomRatio(
+            zoomRatio = 2f,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        )
+
+        val zoomRatio = getZoomRatioFromLinearZoom(
+            linearZoom = linearZoom,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        )
+
+        assertThat(zoomRatio).isEqualTo(2f)
+    }
+
+    @Test
+    fun linearZoomIs0_5f_cropWidthIsHalf() {
+        val sensorRegionWidth = 10000f
+        val minZoomCropWidth = sensorRegionWidth / minZoomRatio
+        val maxZoomCropWidth = sensorRegionWidth / maxZoomRatio
+
+        val zoomRatio = getZoomRatioFromLinearZoom(
+            linearZoom = 0.5f,
+            minZoomRatio = minZoomRatio,
+            maxZoomRatio = maxZoomRatio
+        )
+        val cropWidth = sensorRegionWidth / zoomRatio
+
+        assertThat(cropWidth)
+            .isWithin(CROP_REGION_TOLERANCE)
+            .of((minZoomCropWidth + maxZoomCropWidth) / 2)
+    }
+
+    @Test
+    fun linearZoomIsIncreasedProgressively_cropWidthIsChangedLinearly() {
+        val sensorRegionWidth = 10000f
+        var previousCropWidth = sensorRegionWidth / minZoomRatio
+        var previousCropWidthDiff = Float.NaN
+
+        var linearZoom = 0.1f
+
+        while (linearZoom < 1f) {
+            val zoomRatio = getZoomRatioFromLinearZoom(
+                linearZoom = linearZoom,
+                minZoomRatio = minZoomRatio,
+                maxZoomRatio = maxZoomRatio
+            )
+
+            val cropWidth = sensorRegionWidth / zoomRatio
+            val cropWidthDiff = previousCropWidth - cropWidth
+
+            if (!previousCropWidthDiff.isNaN()) {
+                assertThat(cropWidthDiff)
+                    .isWithin(CROP_REGION_TOLERANCE)
+                    .of(previousCropWidthDiff)
+            }
+
+            previousCropWidthDiff = cropWidthDiff
+            previousCropWidth = cropWidth
+            linearZoom += 0.1f
+        }
+    }
+}
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControlTest.kt
index 5bcde30..efeb07f 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControlTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraControlTest.kt
@@ -16,9 +16,36 @@
 
 package androidx.camera.camera2.pipe.integration.interop
 
+import android.hardware.camera2.CaptureRequest
+import android.hardware.camera2.CaptureResult
 import android.os.Build
+import androidx.camera.camera2.pipe.FrameNumber
+import androidx.camera.camera2.pipe.RequestNumber
 import androidx.camera.camera2.pipe.integration.adapter.RobolectricCameraPipeTestRunner
+import androidx.camera.camera2.pipe.integration.compat.Camera2CameraControlCompatImpl
+import androidx.camera.camera2.pipe.integration.impl.CAMERAX_TAG_BUNDLE
+import androidx.camera.camera2.pipe.integration.impl.ComboRequestListener
+import androidx.camera.camera2.pipe.integration.impl.UseCaseCameraRequestControl
+import androidx.camera.camera2.pipe.integration.impl.UseCaseThreads
+import androidx.camera.camera2.pipe.integration.impl.toParameters
+import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCamera
+import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCameraRequestControl
+import androidx.camera.camera2.pipe.testing.FakeFrameInfo
+import androidx.camera.camera2.pipe.testing.FakeFrameMetadata
+import androidx.camera.camera2.pipe.testing.FakeRequestMetadata
 import androidx.camera.core.impl.CameraControlInternal
+import androidx.camera.core.impl.MutableTagBundle
+import androidx.testutils.assertThrows
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.MoreExecutors
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.runBlocking
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.robolectric.annotation.Config
@@ -28,10 +55,147 @@
 @OptIn(ExperimentalCamera2Interop::class)
 class Camera2CameraControlTest {
 
+    private val fakeUseCaseThreads by lazy {
+        val executor = MoreExecutors.directExecutor()
+        val dispatcher = executor.asCoroutineDispatcher()
+        val cameraScope = CoroutineScope(Job() + dispatcher)
+
+        UseCaseThreads(
+            cameraScope,
+            executor,
+            dispatcher,
+        )
+    }
+    private val comboRequestListener = ComboRequestListener()
+    private val fakeRequestControl = FakeUseCaseCameraRequestControl()
+    private val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+    private val camera2CameraControlCompatImpl = Camera2CameraControlCompatImpl(fakeUseCaseThreads)
+    private lateinit var camera2CameraControl: Camera2CameraControl
+
+    @Before
+    fun setUp() {
+        camera2CameraControl = Camera2CameraControl.create(
+            compat = camera2CameraControlCompatImpl,
+            threads = fakeUseCaseThreads,
+            requestListener = comboRequestListener,
+        )
+        camera2CameraControl.useCaseCamera = fakeUseCaseCamera
+    }
+
+    @Test
+    fun useCaseCameraUpdated_setRequestOptionResultShouldPropagate(): Unit = runBlocking {
+        // Arrange.
+        val completeDeferred = CompletableDeferred<Unit>()
+        val fakeRequestControl = FakeUseCaseCameraRequestControl().apply {
+            setConfigResult = completeDeferred
+        }
+        val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+
+        val resultFuture = camera2CameraControl.setCaptureRequestOptions(
+            CaptureRequestOptions.Builder().setCaptureRequestOption(
+                CaptureRequest.CONTROL_AE_MODE,
+                CaptureRequest.CONTROL_AE_MODE_OFF
+            ).build()
+        )
+
+        // Act. Simulate the UseCaseCamera is recreated.
+        camera2CameraControl.useCaseCamera = fakeUseCaseCamera
+        // Simulate setRequestOption is completed in the recreated UseCaseCamera
+        completeDeferred.complete(Unit)
+        val requestsToCamera = fakeRequestControl.setConfigCalls.filter {
+            it.type == UseCaseCameraRequestControl.Type.CAMERA2_CAMERA_CONTROL
+        }.onEach { request ->
+            comboRequestListener.simulateRepeatingResult(
+                requests = request.config?.toParameters() ?: emptyMap(),
+                tags = request.tags,
+            )
+        }
+
+        // Assert. The setRequestOption task should be completed.
+        assertThat(requestsToCamera).isNotEmpty()
+        assertThat(resultFuture.get(3, TimeUnit.SECONDS)).isNull()
+    }
+
+    @Test
+    fun useCaseCameraUpdated_onlyCompleteLatestRequest(): Unit = runBlocking {
+        // Arrange.
+        val completeDeferred = CompletableDeferred<Unit>()
+        val fakeRequestControl = FakeUseCaseCameraRequestControl().apply {
+            setConfigResult = completeDeferred
+        }
+        val fakeUseCaseCamera = FakeUseCaseCamera(requestControl = fakeRequestControl)
+
+        val resultFuture = camera2CameraControl.setCaptureRequestOptions(
+            CaptureRequestOptions.Builder().setCaptureRequestOption(
+                CaptureRequest.CONTROL_AE_MODE,
+                CaptureRequest.CONTROL_AE_MODE_OFF
+            ).build()
+        )
+
+        // Act. Simulate the UseCaseCamera is recreated.
+        camera2CameraControl.useCaseCamera = fakeUseCaseCamera
+        // Act. Submit a new request option.
+        val resultFuture2 = camera2CameraControl.setCaptureRequestOptions(
+            CaptureRequestOptions.Builder().setCaptureRequestOption(
+                CaptureRequest.CONTROL_AE_MODE,
+                CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH
+            ).build()
+        )
+        // Simulate setRequestOption is completed in the recreated UseCaseCamera
+        completeDeferred.complete(Unit)
+        val requestsToCamera = fakeRequestControl.setConfigCalls.filter {
+            it.type == UseCaseCameraRequestControl.Type.CAMERA2_CAMERA_CONTROL
+        }.onEach { request ->
+            comboRequestListener.simulateRepeatingResult(
+                requests = request.config?.toParameters() ?: emptyMap(),
+                tags = request.tags,
+            )
+        }
+
+        // Assert. The first request should be cancelled., the latest setRequestOption
+        // task should be completed.
+        assertThat(requestsToCamera).isNotEmpty()
+        assertThrows<ExecutionException> {
+            resultFuture.get(3, TimeUnit.SECONDS)
+        }
+        assertThat(resultFuture2.get(3, TimeUnit.SECONDS)).isNull()
+    }
+
     @Test(expected = IllegalArgumentException::class)
     fun fromCameraControlThrows_whenNotCamera2Impl() {
         val wrongCameraControl =
             CameraControlInternal.DEFAULT_EMPTY_INSTANCE
         Camera2CameraControl.from(wrongCameraControl)
     }
+
+    private fun ComboRequestListener.simulateRepeatingResult(
+        requests: Map<CaptureRequest.Key<*>, Any> = emptyMap(),
+        tags: Map<String, Any> = emptyMap(),
+        results: Map<CaptureResult.Key<*>, Any> = emptyMap(),
+        frameNumber: FrameNumber = FrameNumber(101L),
+    ) {
+        val requestMetadata = FakeRequestMetadata(
+            requestParameters = requests,
+            metadata = mapOf(
+                CAMERAX_TAG_BUNDLE to MutableTagBundle.create().also { tagBundle ->
+                    tags.forEach { (tagKey, tagValue) ->
+                        tagBundle.putTag(tagKey, tagValue)
+                    }
+                }
+            ),
+            requestNumber = RequestNumber(1)
+        )
+        val resultMetaData = FakeFrameMetadata(
+            resultMetadata = results,
+            frameNumber = frameNumber,
+        )
+        fakeUseCaseThreads.sequentialExecutor.execute {
+            onComplete(
+                requestMetadata, frameNumber, FakeFrameInfo(
+                    metadata = resultMetaData,
+                    requestMetadata = requestMetadata,
+                )
+            )
+        }
+    }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraInfoTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraInfoTest.kt
index aab5b2d..d2f18b7 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraInfoTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/interop/Camera2CameraInfoTest.kt
@@ -28,9 +28,9 @@
 import androidx.camera.core.CameraState
 import androidx.camera.core.ExposureState
 import androidx.camera.core.ZoomState
-import androidx.camera.core.impl.CamcorderProfileProvider
 import androidx.camera.core.impl.CameraCaptureCallback
 import androidx.camera.core.impl.CameraInfoInternal
+import androidx.camera.core.impl.EncoderProfilesProvider
 import androidx.camera.core.impl.Quirks
 import androidx.camera.core.impl.Timebase
 import androidx.lifecycle.LiveData
@@ -153,7 +153,7 @@
                 throw NotImplementedError("Not used in testing")
             }
 
-            override fun getCamcorderProfileProvider(): CamcorderProfileProvider {
+            override fun getEncoderProfilesProvider(): EncoderProfilesProvider {
                 throw NotImplementedError("Not used in testing")
             }
 
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCamera2CameraControlCompat.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCamera2CameraControlCompat.kt
index 79e9e2c..13cc26d 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCamera2CameraControlCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCamera2CameraControlCompat.kt
@@ -41,7 +41,7 @@
         // No-op
     }
 
-    override fun applyAsync(camera: UseCaseCamera?): Deferred<Void?> {
+    override fun applyAsync(camera: UseCaseCamera?, cancelPreviousTask: Boolean): Deferred<Void?> {
         return CompletableDeferred(null)
     }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraInfoAdapterCreator.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraInfoAdapterCreator.kt
index e98ffc8..1a796be 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraInfoAdapterCreator.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraInfoAdapterCreator.kt
@@ -98,7 +98,8 @@
             FocusMeteringControl(
                 cameraProperties,
                 state3AControl,
-                useCaseThreads
+                useCaseThreads,
+                FakeZoomCompat(),
             ).apply {
                 useCaseCamera = fakeUseCaseCamera
             }
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeEvCompCompat.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeEvCompCompat.kt
index a8d73d5..afd3de9 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeEvCompCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeEvCompCompat.kt
@@ -25,13 +25,17 @@
 class FakeEvCompCompat constructor(
     override val supported: Boolean = false,
     override val range: Range<Int> = Range(0, 0),
-    override val step: Rational = Rational.ZERO
+    override val step: Rational = Rational.ZERO,
 ) : EvCompCompat {
-    override fun stopRunningTask() {
+    override fun stopRunningTask(throwable: Throwable) {
         TODO("Not yet implemented")
     }
 
-    override fun applyAsync(evCompIndex: Int, camera: UseCaseCamera): Deferred<Int> {
+    override fun applyAsync(
+        evCompIndex: Int,
+        camera: UseCaseCamera,
+        cancelPreviousTask: Boolean,
+    ): Deferred<Int> {
         TODO("Not yet implemented")
     }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt
index 9ec74a1..d98a07d 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeUseCaseCamera.kt
@@ -59,6 +59,13 @@
 
 // TODO: Further implement the methods in this class as needed
 open class FakeUseCaseCameraRequestControl : UseCaseCameraRequestControl {
+
+    val addParameterCalls = mutableListOf<Map<CaptureRequest.Key<*>, Any>>()
+    var addParameterResult = CompletableDeferred(Unit)
+    var setConfigCalls = mutableListOf<RequestParameters>()
+    var setConfigResult = CompletableDeferred(Unit)
+    var setTorchResult = CompletableDeferred(Result3A(status = Result3A.Status.OK))
+
     override fun addParametersAsync(
         type: UseCaseCameraRequestControl.Type,
         values: Map<CaptureRequest.Key<*>, Any>,
@@ -68,7 +75,8 @@
         template: RequestTemplate?,
         listeners: Set<Request.Listener>
     ): Deferred<Unit> {
-        return CompletableDeferred(Unit)
+        addParameterCalls.add(values)
+        return addParameterResult
     }
 
     override fun setConfigAsync(
@@ -79,6 +87,7 @@
         template: RequestTemplate?,
         listeners: Set<Request.Listener>
     ): Deferred<Unit> {
+        setConfigCalls.add(RequestParameters(type, config, tags))
         return CompletableDeferred(Unit)
     }
 
@@ -87,7 +96,7 @@
     }
 
     override suspend fun setTorchAsync(enabled: Boolean): Deferred<Result3A> {
-        return CompletableDeferred(Result3A(status = Result3A.Status.OK))
+        return setTorchResult
     }
 
     val focusMeteringCalls = mutableListOf<FocusMeteringParams>()
@@ -127,6 +136,12 @@
         val awbRegions: List<MeteringRectangle> = emptyList(),
         val afTriggerStartAeMode: AeMode? = null
     )
+
+    data class RequestParameters(
+        val type: UseCaseCameraRequestControl.Type,
+        val config: Config?,
+        val tags: Map<String, Any> = emptyMap(),
+    )
 }
 
 // TODO: Further implement the methods in this class as needed
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeZoomCompat.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeZoomCompat.kt
index cabac1a..e48a1d9 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeZoomCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeZoomCompat.kt
@@ -16,16 +16,20 @@
 
 package androidx.camera.camera2.pipe.integration.testing
 
+import android.graphics.Rect
 import androidx.camera.camera2.pipe.integration.compat.ZoomCompat
 import androidx.camera.camera2.pipe.integration.impl.UseCaseCamera
 
 class FakeZoomCompat constructor(
-    override val minZoom: Float = 0f,
-    override val maxZoom: Float = 0f,
+    override val minZoomRatio: Float = 0f,
+    override val maxZoomRatio: Float = 0f,
+    var croppedSensorArea: Rect = Rect(0, 0, 640, 480),
 ) : ZoomCompat {
     var zoomRatio = 0f
 
     override fun apply(zoomRatio: Float, camera: UseCaseCamera) {
         this.zoomRatio = zoomRatio
     }
+
+    override fun getCropSensorRegion() = croppedSensorArea
 }
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt
index 26cbb85..6f6f637 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt
@@ -21,6 +21,7 @@
 import androidx.camera.camera2.pipe.CameraContext
 import androidx.camera.camera2.pipe.CameraController
 import androidx.camera.camera2.pipe.CameraGraph
+import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.GraphState.GraphStateError
 import androidx.camera.camera2.pipe.StreamGraph
 import androidx.camera.camera2.pipe.StreamId
@@ -45,6 +46,9 @@
     private val graphListener: GraphListener,
     private val streamGraph: StreamGraph
 ) : CameraController {
+    override val cameraId: CameraId
+        get() = graphConfig.camera
+
     private val lock = Any()
     private var currentSurfaceMap: Map<StreamId, Surface> = emptyMap()
     private var currentGraphRequestProcessor: GraphRequestProcessor? = null
@@ -152,10 +156,23 @@
 
     override fun stop() {
         synchronized(lock) {
+            check(!closed) {
+                "Attempted to invoke stop after close."
+            }
             started = false
         }
     }
 
+    override fun tryRestart() {
+        synchronized(lock) {
+            check(!closed) {
+                "Attempted to invoke restart after close."
+            }
+            stop()
+            start()
+        }
+    }
+
     override fun close() {
         synchronized(lock) {
             closed = true
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt
index eaaa2eb..1e1f6a3 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt
@@ -24,10 +24,13 @@
 import androidx.camera.camera2.pipe.CameraGraph
 import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.CameraMetadata
+import androidx.camera.camera2.pipe.CameraStatusMonitor
 import androidx.camera.camera2.pipe.StreamGraph
 import androidx.camera.camera2.pipe.graph.GraphListener
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
 
 /**
  * The FakeCameraBackend implements [CameraBackend] and creates [CameraControllerSimulator]s.
@@ -43,6 +46,8 @@
 
     override val id: CameraBackendId
         get() = FAKE_CAMERA_BACKEND_ID
+    override val cameraStatus: Flow<CameraStatusMonitor.CameraStatus>
+        get() = MutableSharedFlow()
 
     override fun awaitCameraIds(): List<CameraId> = fakeCameraIds
 
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt
index 4f9485d..66cbd6f 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt
@@ -17,12 +17,28 @@
 
 import androidx.camera.camera2.pipe.graph.GraphListener
 import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.flow.Flow
 
 /** This is used to uniquely identify a specific backend implementation. */
 @JvmInline
 value class CameraBackendId(val value: String)
 
 /**
+ * A CameraStatusMonitors monitors the status of the cameras, and emits updates when the status of
+ * cameras changes, for instance when the camera access priorities have changed or when a particular
+ * camera has become available.
+ */
+interface CameraStatusMonitor {
+    val cameraStatus: Flow<CameraStatus>
+
+    abstract class CameraStatus internal constructor() {
+        object CameraPrioritiesChanged : CameraStatus()
+
+        class CameraAvailable(val cameraId: CameraId) : CameraStatus()
+    }
+}
+
+/**
  * A CameraBackend is used by [CameraPipe] to abstract out the lifecycle, state, and interactions
  * with a set of camera devices in a standard way.
  *
@@ -38,6 +54,12 @@
     val id: CameraBackendId
 
     /**
+     * A flow of camera statuses that provide camera status updates such as when the camera access
+     * priorities have changed, or a certain camera has become available.
+     */
+    val cameraStatus: Flow<CameraStatusMonitor.CameraStatus>
+
+    /**
      * Read out a list of _openable_ [CameraId]s for this backend. The backend may be able to report
      * Metadata for non-openable cameras. However, these cameras should not appear the list of
      * cameras returned by [getCameraIds].
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt
index 0eacef9..29dee61 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt
@@ -17,6 +17,7 @@
 package androidx.camera.camera2.pipe
 
 import android.view.Surface
+import androidx.camera.camera2.pipe.CameraController.ControllerState.CLOSED
 import androidx.camera.camera2.pipe.graph.GraphListener
 
 /**
@@ -35,8 +36,10 @@
  * Once [close] is invoked, this instance should not respond to any additional events.
  */
 interface CameraController {
+    val cameraId: CameraId
+
     /**
-     * Connect and start the underlying camera.This may be called on the main thread and should not
+     * Connect and start the underlying camera. This may be called on the main thread and should not
      * make long blocking calls. This may be called opportunistically (eg, whenever a lifecycle
      * indicates the camera should be in a running state)
      */
@@ -49,6 +52,13 @@
     fun stop()
 
     /**
+     * Restart the current session. This should basically perform stop() then start(). However, the
+     * implementation should handle its internal states correctly, and only restart when the
+     * conditions are appropriate.
+     */
+    fun tryRestart()
+
+    /**
      * Close this instance. [start] and [stop] should not be invoked, and any additional calls will
      * be ignored once this method returns. Depending on implementation the underlying camera
      * connection may not be terminated immediately, depending on the [CameraBackend]
@@ -61,4 +71,40 @@
      * missing from the [StreamGraph] that was used to create this [CameraController].
      */
     fun updateSurfaceMap(surfaceMap: Map<StreamId, Surface>)
+
+    /**
+     * ControllerState indicates the internal state of a [CameraController]. These states are needed
+     * to make sure we only invoke [CameraController] methods under the right conditions.
+     *
+     * The following diagram illustrates the state transitions (all states also have a permissible
+     * transition to [CLOSED]).
+     *
+     *   ```
+     *   [STOPPED] --> [STARTED] --> [STOPPING] ---------.--------.
+     *      ^              ^             |               |        |
+     *      |              |             V               V        |
+     *      |              '---------[DISCONNECTED]   [ERROR]     |
+     *      |                                                     |
+     *      '-----------------------------------------------------'
+     *   ```
+     */
+    abstract class ControllerState internal constructor() {
+        /** When the CameraController is started. This is set immediately as start() is called. */
+        object STARTED : ControllerState()
+
+        /** When the CameraController is stopping. This is set immediately as stop() is called. */
+        object STOPPING : ControllerState()
+
+        /** When the camera is stopped normally. */
+        object STOPPED : ControllerState()
+
+        /** When the camera is disconnected and can be later "reconnected". */
+        object DISCONNECTED : ControllerState()
+
+        /** When the camera shuts down with an unrecoverable error. */
+        object ERROR : ControllerState()
+
+        /** When the CameraController is closed, and no further operations can done on it. */
+        object CLOSED : ControllerState()
+    }
 }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt
index 343a8cb..f78fd57 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt
@@ -24,6 +24,7 @@
 import androidx.camera.camera2.pipe.CameraGraph
 import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.CameraMetadata
+import androidx.camera.camera2.pipe.CameraStatusMonitor.CameraStatus
 import androidx.camera.camera2.pipe.StreamGraph
 import androidx.camera.camera2.pipe.config.Camera2ControllerComponent
 import androidx.camera.camera2.pipe.config.Camera2ControllerConfig
@@ -33,6 +34,7 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.flow.Flow
 
 /** This is the default [CameraBackend] implementation for CameraPipe based on Camera2. */
 @RequiresApi(21)
@@ -44,9 +46,12 @@
     private val camera2MetadataCache: Camera2MetadataCache,
     private val virtualCameraManager: VirtualCameraManager,
     private val camera2CameraControllerComponent: Camera2ControllerComponent.Builder,
+    private val camera2CameraStatusMonitor: Camera2CameraStatusMonitor,
 ) : CameraBackend {
     override val id: CameraBackendId
         get() = CameraBackendId("CXCP-Camera2")
+    override val cameraStatus: Flow<CameraStatus>
+        get() = camera2CameraStatusMonitor.cameraStatus
 
     override suspend fun getCameraIds(): List<CameraId>? = camera2DeviceCache.getCameraIds()
 
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
index 4b48fbc..5ddaf29 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
@@ -17,16 +17,22 @@
 package androidx.camera.camera2.pipe.compat
 
 import android.view.Surface
+import androidx.annotation.GuardedBy
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.CameraController
+import androidx.camera.camera2.pipe.CameraController.ControllerState
+import androidx.camera.camera2.pipe.CameraError
 import androidx.camera.camera2.pipe.CameraGraph
+import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.CameraSurfaceManager
 import androidx.camera.camera2.pipe.StreamId
 import androidx.camera.camera2.pipe.config.Camera2ControllerScope
+import androidx.camera.camera2.pipe.core.Log
 import androidx.camera.camera2.pipe.core.TimeSource
 import androidx.camera.camera2.pipe.graph.GraphListener
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 
 /**
@@ -52,79 +58,104 @@
     private val cameraSurfaceManager: CameraSurfaceManager,
     private val timeSource: TimeSource
 ) : CameraController {
-    private var closed = false
+    override val cameraId: CameraId
+        get() = config.camera
+
+    private val lock = Any()
+
+    @GuardedBy("lock")
+    private var controllerState: ControllerState = ControllerState.STOPPED
+
     private var currentCamera: VirtualCamera? = null
     private var currentSession: CaptureSessionState? = null
     private var currentSurfaceMap: Map<StreamId, Surface>? = null
 
-    override fun start() {
-        val camera =
-            virtualCameraManager.open(
-                config.camera, config.flags.allowMultipleActiveCameras, graphListener
-            )
-        synchronized(this) {
-            if (closed) {
-                return
-            }
+    private var currentCameraStateJob: Job? = null
 
-            check(currentCamera == null)
-            check(currentSession == null)
-
-            currentCamera = camera
-            val session =
-                CaptureSessionState(
-                    graphListener,
-                    captureSessionFactory,
-                    captureSequenceProcessorFactory,
-                    cameraSurfaceManager,
-                    timeSource,
-                    scope
-                )
-            currentSession = session
-
-            val surfaces: Map<StreamId, Surface>? = currentSurfaceMap
-            if (surfaces != null) {
-                session.configureSurfaceMap(surfaces)
-            }
+    override fun start(): Unit = synchronized(lock) {
+        if (controllerState == ControllerState.CLOSED) {
+            Log.info { "Ignoring start(): Camera2CameraController is already closed" }
+            return
+        } else if (controllerState == ControllerState.STARTED) {
+            Log.warn { "Ignoring start(): Camera2CameraController is already started" }
+            return
         }
-        scope.launch { bindSessionToCamera() }
+        val camera = virtualCameraManager.open(
+            config.camera,
+            config.flags.allowMultipleActiveCameras,
+            graphListener
+        )
+
+        check(currentCamera == null)
+        check(currentSession == null)
+
+        currentCamera = camera
+        val session = CaptureSessionState(
+            graphListener,
+            captureSessionFactory,
+            captureSequenceProcessorFactory,
+            cameraSurfaceManager,
+            timeSource,
+            scope
+        )
+        currentSession = session
+
+        val surfaces: Map<StreamId, Surface>? = currentSurfaceMap
+        if (surfaces != null) {
+            session.configureSurfaceMap(surfaces)
+        }
+
+        controllerState = ControllerState.STARTED
+        Log.debug { "Started Camera2CameraController" }
+        currentCameraStateJob = scope.launch { bindSessionToCamera() }
     }
 
-    override fun stop() {
-        val camera: VirtualCamera?
-        val session: CaptureSessionState?
-        synchronized(this) {
-            if (closed) {
-                return
-            }
-
-            camera = currentCamera
-            session = currentSession
-
-            currentCamera = null
-            currentSession = null
+    override fun stop(): Unit = synchronized(lock) {
+        if (controllerState == ControllerState.CLOSED) {
+            Log.warn { "Ignoring stop(): Camera2CameraController is already closed" }
+            return
+        } else if (controllerState == ControllerState.STOPPING ||
+            controllerState == ControllerState.STOPPED
+        ) {
+            Log.warn { "Ignoring stop(): CameraController already stopping or stopped" }
+            return
         }
 
+        val camera = currentCamera
+        val session = currentSession
+
+        currentCamera = null
+        currentSession = null
+
+        controllerState = ControllerState.STOPPING
+        Log.debug { "Stopping Camera2CameraController" }
         scope.launch {
             session?.disconnect()
             camera?.disconnect()
         }
     }
 
-    override fun close() {
-        val camera: VirtualCamera?
-        val session: CaptureSessionState?
-        synchronized(this) {
-            if (closed) {
-                return
-            }
-            closed = true
-            camera = currentCamera
-            session = currentSession
-
-            currentCamera = null
-            currentSession = null
+    override fun tryRestart(): Unit = synchronized(lock) {
+        if (controllerState != ControllerState.DISCONNECTED) {
+            Log.debug { "Ignoring restart(): CameraController is $controllerState" }
+            return
         }
+        stop()
+        start()
+    }
+
+    override fun close(): Unit = synchronized(lock) {
+        if (controllerState == ControllerState.CLOSED) {
+            return
+        }
+        controllerState = ControllerState.CLOSED
+        Log.debug { "Closed Camera2CameraController" }
+
+        val camera = currentCamera
+        val session = currentSession
+
+        currentCamera = null
+        currentSession = null
 
         scope.launch {
             session?.disconnect()
@@ -134,33 +165,67 @@
 
     override fun updateSurfaceMap(surfaceMap: Map<StreamId, Surface>) {
         // TODO: Add logic to decide if / when to re-configure the Camera2 CaptureSession.
-        synchronized(this) {
-            if (closed) {
+        synchronized(lock) {
+            if (controllerState == ControllerState.CLOSED) {
                 return
             }
             currentSurfaceMap = surfaceMap
             currentSession
-        }
-            ?.configureSurfaceMap(surfaceMap)
+        }?.configureSurfaceMap(surfaceMap)
     }
 
     private suspend fun bindSessionToCamera() {
         val camera: VirtualCamera?
         val session: CaptureSessionState?
 
-        synchronized(this) {
+        synchronized(lock) {
             camera = currentCamera
             session = currentSession
         }
 
         if (camera != null && session != null) {
-            camera.state.collect {
-                if (it is CameraStateOpen) {
-                    session.cameraDevice = it.cameraDevice
-                } else if (it is CameraStateClosing || it is CameraStateClosed) {
-                    session.disconnect()
+            camera.state.collect { cameraState ->
+                when (cameraState) {
+                    is CameraStateOpen -> {
+                        session.cameraDevice = cameraState.cameraDevice
+                    }
+
+                    is CameraStateClosing -> {
+                        session.disconnect()
+                    }
+
+                    is CameraStateClosed -> {
+                        session.disconnect()
+                        onStateClosed(cameraState)
+                    }
+
+                    else -> {
+                        // Do nothing
+                    }
                 }
             }
         }
     }
+
+    private fun onStateClosed(cameraState: CameraStateClosed) = synchronized(lock) {
+        if (cameraState.cameraErrorCode != null) {
+            if (cameraState.cameraErrorCode == CameraError.ERROR_CAMERA_DISCONNECTED ||
+                cameraState.cameraErrorCode == CameraError.ERROR_CAMERA_IN_USE ||
+                cameraState.cameraErrorCode == CameraError.ERROR_CAMERA_LIMIT_EXCEEDED
+            ) {
+                controllerState = ControllerState.DISCONNECTED
+                Log.debug { "Camera2CameraController is disconnected" }
+            } else {
+                controllerState = ControllerState.ERROR
+                Log.debug {
+                    "Camera2CameraController encountered an " +
+                        "unrecoverable error: ${cameraState.cameraErrorCode}"
+                }
+            }
+        } else {
+            controllerState = ControllerState.STOPPED
+        }
+        currentCameraStateJob?.cancel()
+        currentCameraStateJob = null
+    }
 }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraStatusMonitor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraStatusMonitor.kt
new file mode 100644
index 0000000..0ab7e59
--- /dev/null
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraStatusMonitor.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2022 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 androidx.camera.camera2.pipe.compat
+
+import android.hardware.camera2.CameraManager
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.CameraStatusMonitor
+import androidx.camera.camera2.pipe.CameraStatusMonitor.CameraStatus
+import androidx.camera.camera2.pipe.core.Log
+import androidx.camera.camera2.pipe.core.Threads
+import javax.inject.Inject
+import javax.inject.Provider
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.channels.onFailure
+import kotlinx.coroutines.channels.trySendBlocking
+import kotlinx.coroutines.flow.callbackFlow
+
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+internal class Camera2CameraStatusMonitor @Inject constructor(
+    cameraManager: Provider<CameraManager>,
+    threads: Threads
+) : CameraStatusMonitor {
+    override val cameraStatus = callbackFlow {
+        val manager = cameraManager.get()
+        val availabilityCallback = object : CameraManager.AvailabilityCallback() {
+            override fun onCameraAccessPrioritiesChanged() {
+                Log.debug { "Camera access priorities have changed" }
+                trySendBlocking(CameraStatus.CameraPrioritiesChanged)
+                    .onFailure {
+                        Log.warn { "Failed to emit CameraPrioritiesChanged" }
+                    }
+            }
+
+            override fun onCameraAvailable(cameraId: String) {
+                Log.debug { "Camera $cameraId has become available" }
+                trySendBlocking(CameraStatus.CameraAvailable(CameraId.fromCamera2Id(cameraId)))
+                    .onFailure {
+                        Log.warn { "Failed to emit CameraAvailable($cameraId)" }
+                    }
+            }
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            Api28Compat.registerAvailabilityCallback(
+                manager,
+                threads.lightweightExecutor,
+                availabilityCallback
+            )
+        } else {
+            manager.registerAvailabilityCallback(
+                availabilityCallback,
+                threads.camera2Handler
+            )
+        }
+
+        awaitClose { manager.unregisterAvailabilityCallback(availabilityCallback) }
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
index 564a5bc..2698852 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
@@ -18,6 +18,8 @@
 
 package androidx.camera.camera2.pipe.compat
 
+import android.hardware.camera2.CameraAccessException
+import android.hardware.camera2.CameraAccessException.CAMERA_ERROR
 import android.hardware.camera2.CameraCaptureSession
 import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession
 import android.hardware.camera2.CaptureRequest
@@ -354,10 +356,23 @@
                 "succeed."
         }
 
-        rethrowCamera2Exceptions {
+        var exceptionToThrow: Throwable? = null
+        try {
             Api26Compat.finalizeOutputConfigurations(
-                cameraCaptureSession, outputConfigs.map { it.unwrapAs(OutputConfiguration::class) })
+                cameraCaptureSession,
+                outputConfigs.map { it.unwrapAs(OutputConfiguration::class) })
+        } catch (e: CameraAccessException) {
+            // TODO(b/266734799): There is a possibility that we might finalize output
+            //  configurations on a camera that's been disconnected. In such cases, we'll receive
+            //  CameraAccessException.CAMERA_ERROR. Catch it for now, until we properly report and
+            //  handle capture session errors.
+            if (e.reason != CAMERA_ERROR) {
+                exceptionToThrow = e
+            }
+        } catch (e: Throwable) {
+            exceptionToThrow = e
         }
+        exceptionToThrow?.let { rethrowCamera2Exceptions { throw it } }
     }
 
     @Suppress("UNCHECKED_CAST")
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
index 8988b2b..151d702 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
@@ -50,6 +50,9 @@
         GraphRequestProcessor.from(sequenceProcessor)
     private var started = atomic(false)
 
+    override val cameraId: CameraId
+        get() = graphConfig.camera
+
     override fun start() {
         if (started.compareAndSet(expect = false, update = true)) {
             graphListener.onGraphStarted(graphProcessor)
@@ -62,6 +65,11 @@
         }
     }
 
+    override fun tryRestart() {
+        // This is intentionally made a no-op for now as CameraPipe external doesn't support
+        // camera status monitoring and camera controller restart.
+    }
+
     override fun close() {
         graphProcessor.close()
     }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
index b870809..fe27798 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
@@ -21,6 +21,7 @@
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.CameraError
 import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.core.Log
 import androidx.camera.camera2.pipe.core.Permissions
 import androidx.camera.camera2.pipe.core.Threads
 import androidx.camera.camera2.pipe.core.WakeLock
@@ -206,6 +207,7 @@
         //   causing the application process to restart.
         check(permissions.hasCameraPermission) { "Missing camera permissions!" }
 
+        Log.debug { "Opening $cameraId with retries..." }
         val result = retryingCameraStateOpener.openCameraWithRetry(cameraId, graphListener)
         if (result.cameraState == null) {
             return OpenVirtualCameraResult(lastCameraError = result.errorCode)
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt
index c7b6b1e..57d38e5 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt
@@ -20,11 +20,13 @@
 import androidx.camera.camera2.pipe.CameraBackend
 import androidx.camera.camera2.pipe.CameraController
 import androidx.camera.camera2.pipe.CameraGraph
+import androidx.camera.camera2.pipe.CameraStatusMonitor
 import androidx.camera.camera2.pipe.StreamGraph
 import androidx.camera.camera2.pipe.compat.Camera2Backend
 import androidx.camera.camera2.pipe.compat.Camera2CameraAvailabilityMonitor
 import androidx.camera.camera2.pipe.compat.Camera2CameraController
 import androidx.camera.camera2.pipe.compat.Camera2CameraOpener
+import androidx.camera.camera2.pipe.compat.Camera2CameraStatusMonitor
 import androidx.camera.camera2.pipe.compat.Camera2CaptureSequenceProcessorFactory
 import androidx.camera.camera2.pipe.compat.Camera2CaptureSessionsModule
 import androidx.camera.camera2.pipe.compat.Camera2MetadataCache
@@ -62,6 +64,11 @@
     abstract fun bindCameraAvailabilityMonitor(
         camera2CameraAvailabilityMonitor: Camera2CameraAvailabilityMonitor
     ): CameraAvailabilityMonitor
+
+    @Binds
+    abstract fun bindCameraStatusMonitor(
+        camera2CameraStatusMonitor: Camera2CameraStatusMonitor
+    ): CameraStatusMonitor
 }
 
 @Scope
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/CameraPipeComponent.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/CameraPipeComponent.kt
index ce3a3ad..28bd09a 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/CameraPipeComponent.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/CameraPipeComponent.kt
@@ -55,6 +55,9 @@
 @Qualifier
 internal annotation class CameraPipeContext
 
+@Qualifier
+internal annotation class ForGraphLifecycleManager
+
 @Singleton
 @Component(
     modules =
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt
index b93b659..6ca0561 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt
@@ -21,15 +21,24 @@
 package androidx.camera.camera2.pipe.config
 
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraBackend
+import androidx.camera.camera2.pipe.CameraBackendId
+import androidx.camera.camera2.pipe.CameraContext
 import androidx.camera.camera2.pipe.CameraController
 import androidx.camera.camera2.pipe.CameraGraph
+import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.CameraMetadata
+import androidx.camera.camera2.pipe.CameraStatusMonitor
 import androidx.camera.camera2.pipe.RequestProcessor
+import androidx.camera.camera2.pipe.StreamGraph
 import androidx.camera.camera2.pipe.compat.ExternalCameraController
 import androidx.camera.camera2.pipe.graph.GraphListener
 import dagger.Module
 import dagger.Provides
 import dagger.Subcomponent
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
 
 @CameraGraphScope
 @Subcomponent(modules = [SharedCameraGraphModules::class, ExternalCameraGraphConfigModule::class])
@@ -49,6 +58,45 @@
     private val cameraMetadata: CameraMetadata,
     private val requestProcessor: RequestProcessor
 ) {
+    private val externalCameraBackend = object : CameraBackend {
+        override val id: CameraBackendId
+            get() = CameraBackendId("External")
+        override val cameraStatus: Flow<CameraStatusMonitor.CameraStatus>
+            get() = MutableSharedFlow()
+
+        override suspend fun getCameraIds(): List<CameraId>? {
+            throwUnsupportedOperationException()
+        }
+
+        override fun awaitCameraIds(): List<CameraId>? {
+            throwUnsupportedOperationException()
+        }
+
+        override fun awaitCameraMetadata(cameraId: CameraId): CameraMetadata? {
+            throwUnsupportedOperationException()
+        }
+
+        override fun disconnectAllAsync(): Deferred<Unit> {
+            throwUnsupportedOperationException()
+        }
+
+        override fun shutdownAsync(): Deferred<Unit> {
+            throwUnsupportedOperationException()
+        }
+
+        override fun createCameraController(
+            cameraContext: CameraContext,
+            graphConfig: CameraGraph.Config,
+            graphListener: GraphListener,
+            streamGraph: StreamGraph
+        ): CameraController {
+            throwUnsupportedOperationException()
+        }
+
+        private fun throwUnsupportedOperationException(): Nothing =
+            throw UnsupportedOperationException("External CameraPipe should not use backends")
+    }
+
     @Provides
     fun provideCameraGraphConfig(): CameraGraph.Config = config
 
@@ -59,4 +107,8 @@
     @Provides
     fun provideGraphController(graphListener: GraphListener): CameraController =
         ExternalCameraController(config, graphListener, requestProcessor)
+
+    @CameraGraphScope
+    @Provides
+    fun provideCameraBackend(): CameraBackend = externalCameraBackend
 }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraPipeComponent.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraPipeComponent.kt
index 233200c..6068c13 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraPipeComponent.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraPipeComponent.kt
@@ -25,4 +25,4 @@
 @Component(modules = [ThreadConfigModule::class])
 internal interface ExternalCameraPipeComponent {
     fun cameraGraphBuilder(): ExternalCameraGraphComponent.Builder
-}
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/CameraGraphImpl.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/CameraGraphImpl.kt
index 366f78c..586f399 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/CameraGraphImpl.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/CameraGraphImpl.kt
@@ -18,6 +18,7 @@
 
 import android.view.Surface
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraBackend
 import androidx.camera.camera2.pipe.CameraController
 import androidx.camera.camera2.pipe.CameraGraph
 import androidx.camera.camera2.pipe.CameraMetadata
@@ -31,6 +32,7 @@
 import androidx.camera.camera2.pipe.core.TokenLockImpl
 import androidx.camera.camera2.pipe.core.acquire
 import androidx.camera.camera2.pipe.core.acquireOrNull
+import androidx.camera.camera2.pipe.internal.GraphLifecycleManager
 import javax.inject.Inject
 import kotlinx.atomicfu.atomic
 import kotlinx.coroutines.flow.StateFlow
@@ -44,10 +46,12 @@
 constructor(
     graphConfig: CameraGraph.Config,
     metadata: CameraMetadata,
+    private val graphLifecycleManager: GraphLifecycleManager,
     private val graphProcessor: GraphProcessor,
     private val graphListener: GraphListener,
     private val streamGraph: StreamGraphImpl,
     private val surfaceGraph: SurfaceGraph,
+    private val cameraBackend: CameraBackend,
     private val cameraController: CameraController,
     private val graphState3A: GraphState3A,
     private val listener3A: Listener3A
@@ -104,7 +108,7 @@
         Debug.traceStart { "$this#start" }
         Log.info { "Starting $this" }
         graphListener.onGraphStarting()
-        cameraController.start()
+        graphLifecycleManager.monitorAndStart(cameraBackend, cameraController)
         Debug.traceStop()
     }
 
@@ -112,7 +116,7 @@
         Debug.traceStart { "$this#stop" }
         Log.info { "Stopping $this" }
         graphListener.onGraphStopping()
-        cameraController.stop()
+        graphLifecycleManager.monitorAndStop(cameraBackend, cameraController)
         Debug.traceStop()
     }
 
@@ -146,7 +150,7 @@
         Log.info { "Closing $this" }
         sessionLock.close()
         graphProcessor.close()
-        cameraController.close()
+        graphLifecycleManager.monitorAndClose(cameraBackend, cameraController)
         surfaceGraph.close()
         Debug.traceStop()
     }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/GraphLifecycleManager.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/GraphLifecycleManager.kt
new file mode 100644
index 0000000..1429f76
--- /dev/null
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/GraphLifecycleManager.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.pipe.internal
+
+import androidx.annotation.GuardedBy
+import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraBackend
+import androidx.camera.camera2.pipe.CameraBackendId
+import androidx.camera.camera2.pipe.CameraController
+import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.CameraStatusMonitor
+import androidx.camera.camera2.pipe.CameraStatusMonitor.CameraStatus
+import androidx.camera.camera2.pipe.core.Threads
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlinx.coroutines.CoroutineName
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+
+/**
+ * GraphLifecycleManager is a CameraPipe-level lifecycle manager that does the following:
+ * - Oversees and executes the operations of [CameraController]`s. This means it will make sure the
+ *   operations are atomic, and executed based on permissible state transitions.
+ * - Subscribe to [CameraStatusMonitor]s for camera status changes, basically “can attempt to
+ *   restart signals”, from the respective camera backends, and then only restart
+ *   [CameraController]s when the conditions are right.
+ * - Once we've determined that we can restart [CameraController]s, select the “suitable”
+ *   [CameraController] to restart.
+ */
+@Singleton
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+internal class GraphLifecycleManager @Inject constructor(val threads: Threads) {
+    private val lock = Any()
+
+    private val scope = CoroutineScope(
+        threads.lightweightDispatcher.plus(CoroutineName("CXCP-GraphLifecycleManager"))
+    )
+
+    @GuardedBy("lock")
+    private val backendControllerMap =
+        mutableMapOf<CameraBackendId, LinkedHashSet<CameraController>>()
+
+    @GuardedBy("lock")
+    private val backendStatusCollectJobMap = mutableMapOf<CameraBackendId, Job>()
+
+    internal fun monitorAndStart(cameraBackend: CameraBackend, cameraController: CameraController) =
+        synchronized(lock) {
+            startMonitoring(cameraBackend, cameraController)
+            cameraController.start()
+        }
+
+    internal fun monitorAndStop(cameraBackend: CameraBackend, cameraController: CameraController) =
+        synchronized(lock) {
+            cameraController.stop()
+            stopMonitoring(cameraBackend, cameraController)
+        }
+
+    internal fun monitorAndClose(cameraBackend: CameraBackend, cameraController: CameraController) =
+        synchronized(lock) {
+            cameraController.close()
+            stopMonitoring(cameraBackend, cameraController)
+        }
+
+    @GuardedBy("lock")
+    private fun startMonitoring(cameraBackend: CameraBackend, cameraController: CameraController) {
+        if (backendControllerMap.containsKey(cameraBackend.id)) {
+            backendControllerMap[cameraBackend.id]?.add(cameraController)
+            return
+        }
+        backendControllerMap[cameraBackend.id] = linkedSetOf(cameraController)
+        backendStatusCollectJobMap[cameraBackend.id] = scope.launch {
+            cameraBackend.cameraStatus.collect { cameraStatus ->
+                when (cameraStatus) {
+                    is CameraStatus.CameraPrioritiesChanged ->
+                        tryRestartCameraController(cameraBackend)
+
+                    is CameraStatus.CameraAvailable ->
+                        tryRestartCameraController(cameraBackend, cameraStatus.cameraId)
+                }
+            }
+        }
+    }
+
+    @GuardedBy("lock")
+    private fun stopMonitoring(cameraBackend: CameraBackend, cameraController: CameraController) {
+        if (backendControllerMap.containsKey(cameraBackend.id)) {
+            val controllerSet = backendControllerMap[cameraBackend.id]
+            controllerSet?.remove(cameraController)
+            if (controllerSet?.size == 0) {
+                backendControllerMap.remove(cameraBackend.id)
+                backendStatusCollectJobMap[cameraBackend.id]?.cancel()
+                backendStatusCollectJobMap.remove(cameraBackend.id)
+            }
+        }
+    }
+
+    private fun tryRestartCameraController(
+        cameraBackend: CameraBackend,
+        cameraId: CameraId? = null,
+    ) = synchronized(lock) {
+        // Restart the last CameraController being tracked in each backend. The last
+        // CameraController would be the latest one being tracked, and should thus take priority
+        // over previous CameraControllers.
+        backendControllerMap[cameraBackend.id]?.findLast {
+            if (cameraId != null) {
+                it.cameraId == cameraId
+            } else {
+                true
+            }
+        }?.tryRestart()
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/graph/CameraGraphImplTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/graph/CameraGraphImplTest.kt
index e377214..05af92f 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/graph/CameraGraphImplTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/graph/CameraGraphImplTest.kt
@@ -30,6 +30,7 @@
 import androidx.camera.camera2.pipe.Request
 import androidx.camera.camera2.pipe.StreamFormat
 import androidx.camera.camera2.pipe.internal.CameraBackendsImpl
+import androidx.camera.camera2.pipe.internal.GraphLifecycleManager
 import androidx.camera.camera2.pipe.testing.CameraControllerSimulator
 import androidx.camera.camera2.pipe.testing.FakeCameraBackend
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
@@ -92,6 +93,7 @@
                 threads
             )
         val cameraContext = CameraBackendsImpl.CameraBackendContext(context, threads, backends)
+        val graphLifecycleManager = GraphLifecycleManager(threads)
         val streamGraph = StreamGraphImpl(metadata, graphConfig)
         cameraController =
             CameraControllerSimulator(cameraContext, graphConfig, fakeGraphProcessor, streamGraph)
@@ -101,10 +103,12 @@
             CameraGraphImpl(
                 graphConfig,
                 metadata,
+                graphLifecycleManager,
                 fakeGraphProcessor,
                 fakeGraphProcessor,
                 streamGraph,
                 surfaceGraph,
+                backend,
                 cameraController,
                 GraphState3A(),
                 Listener3A()
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt
index b637133..c49f98a 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt
@@ -18,12 +18,15 @@
 
 import android.view.Surface
 import androidx.camera.camera2.pipe.CameraController
+import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.StreamId
 
 internal class FakeCameraController : CameraController {
     var started = false
     var closed = false
     var surfaceMap: Map<StreamId, Surface>? = null
+    override val cameraId: CameraId
+        get() = CameraId.fromCamera2Id("0")
 
     override fun start() {
         started = true
@@ -33,6 +36,11 @@
         started = false
     }
 
+    override fun tryRestart() {
+        stop()
+        start()
+    }
+
     override fun close() {
         closed = true
         started = false
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CamcorderProfileProviderTest.kt b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CamcorderProfileProviderTest.kt
deleted file mode 100644
index 6d48e3e7..0000000
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CamcorderProfileProviderTest.kt
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.camera2.internal
-
-import android.hardware.camera2.CameraCharacteristics
-import android.media.CamcorderProfile
-import android.util.Size
-import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat
-import androidx.camera.camera2.internal.compat.StreamConfigurationMapCompat
-import androidx.camera.core.CameraSelector
-import androidx.camera.core.impl.ImageFormatConstants
-import androidx.camera.testing.CameraUtil
-import androidx.test.filters.SdkSuppress
-import androidx.test.filters.SmallTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-@RunWith(Parameterized::class)
-@SmallTest
-@Suppress("DEPRECATION")
-@SdkSuppress(minSdkVersion = 21)
-public class Camera2CamcorderProfileProviderTest(private val quality: Int) {
-    public companion object {
-        @JvmStatic
-        @Parameterized.Parameters
-        public fun data(): Array<Array<Int>> = arrayOf(
-            arrayOf(CamcorderProfile.QUALITY_LOW),
-            arrayOf(CamcorderProfile.QUALITY_HIGH),
-            arrayOf(CamcorderProfile.QUALITY_QCIF),
-            arrayOf(CamcorderProfile.QUALITY_CIF),
-            arrayOf(CamcorderProfile.QUALITY_480P),
-            arrayOf(CamcorderProfile.QUALITY_720P),
-            arrayOf(CamcorderProfile.QUALITY_1080P),
-            arrayOf(CamcorderProfile.QUALITY_QVGA),
-            arrayOf(CamcorderProfile.QUALITY_2160P),
-            arrayOf(CamcorderProfile.QUALITY_VGA),
-            arrayOf(CamcorderProfile.QUALITY_4KDCI),
-            arrayOf(CamcorderProfile.QUALITY_QHD),
-            arrayOf(CamcorderProfile.QUALITY_2K)
-        )
-    }
-
-    private lateinit var camcorderProfileProvider: Camera2CamcorderProfileProvider
-    private lateinit var cameraCharacteristics: CameraCharacteristicsCompat
-    private var isLegacyCamera = false
-    private var intCameraId = -1
-
-    @Before
-    public fun setup() {
-        assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK))
-
-        val cameraId = CameraUtil.getCameraIdWithLensFacing(CameraSelector.LENS_FACING_BACK)!!
-        intCameraId = cameraId.toInt()
-
-        cameraCharacteristics = CameraCharacteristicsCompat.toCameraCharacteristicsCompat(
-            CameraUtil.getCameraCharacteristics(CameraSelector.LENS_FACING_BACK)!!
-        )
-        val hardwareLevel =
-            cameraCharacteristics[CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL]
-
-        isLegacyCamera = hardwareLevel != null && hardwareLevel == CameraCharacteristics
-            .INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
-
-        camcorderProfileProvider = Camera2CamcorderProfileProvider(cameraId, cameraCharacteristics)
-    }
-
-    @Test
-    public fun nonLegacyCamera_hasProfile_returnSameResult() {
-        assumeTrue(!isLegacyCamera)
-
-        assertThat(camcorderProfileProvider.hasProfile(quality))
-            .isEqualTo(CamcorderProfile.hasProfile(intCameraId, quality))
-    }
-
-    @Test
-    public fun nonLegacyCamera_notHasProfile_getReturnNull() {
-        assumeTrue(!isLegacyCamera)
-        assumeTrue(!CamcorderProfile.hasProfile(intCameraId, quality))
-
-        assertThat(camcorderProfileProvider.get(quality)).isNull()
-    }
-
-    @Test
-    public fun nonLegacyCamera_hasProfile_getReturnSameQualityProfile() {
-        assumeTrue(!isLegacyCamera)
-        assumeTrue(CamcorderProfile.hasProfile(intCameraId, quality))
-
-        val profileProxy = camcorderProfileProvider.get(quality)!!
-        val profile = CamcorderProfile.get(intCameraId, quality)
-        assertThat(profileProxy.quality).isEqualTo(profile.quality)
-    }
-
-    @Test
-    public fun legacyCamera_notHasProfile_returnFalse() {
-        assumeTrue(isLegacyCamera)
-        assumeTrue(!CamcorderProfile.hasProfile(intCameraId, quality))
-
-        assertThat(camcorderProfileProvider.hasProfile(quality)).isFalse()
-    }
-
-    @Test
-    public fun legacyCamera_hasProfile_shouldCheckSupportedResolution() {
-        assumeTrue(isLegacyCamera)
-        assumeTrue(CamcorderProfile.hasProfile(intCameraId, quality))
-
-        val videoSupportedResolutions = getVideoSupportedResolutions()
-        val isResolutionSupported =
-            videoSupportedResolutions.contains(CamcorderProfile.get(intCameraId, quality).size())
-
-        assertThat(camcorderProfileProvider.hasProfile(quality)).isEqualTo(isResolutionSupported)
-    }
-
-    @Test
-    public fun legacyCamera_notHasProfile_getReturnNull() {
-        assumeTrue(isLegacyCamera)
-        assumeTrue(!CamcorderProfile.hasProfile(intCameraId, quality))
-
-        assertThat(camcorderProfileProvider.get(quality)).isNull()
-    }
-
-    @Test
-    public fun legacyCamera_hasProfile_getShouldCheckSupportedResolution() {
-        assumeTrue(isLegacyCamera)
-        assumeTrue(CamcorderProfile.hasProfile(intCameraId, quality))
-
-        val profile = CamcorderProfile.get(intCameraId, quality)
-        val videoSupportedResolutions = getVideoSupportedResolutions()
-        val isResolutionSupported = videoSupportedResolutions.contains(profile.size())
-
-        val profileProxy = camcorderProfileProvider.get(quality)
-        if (isResolutionSupported) {
-            assertThat(profileProxy!!.quality).isEqualTo(profile.quality)
-        } else {
-            assertThat(profileProxy).isNull()
-        }
-    }
-
-    private fun getVideoSupportedResolutions(): Array<Size> {
-        val mapCompat = StreamConfigurationMapCompat.toStreamConfigurationMapCompat(
-            cameraCharacteristics[CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP]!!
-        )
-        return mapCompat.getOutputSizes(ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE)
-            ?: emptyArray()
-    }
-
-    private fun CamcorderProfile.size() = Size(videoFrameWidth, videoFrameHeight)
-}
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProviderTest.kt b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProviderTest.kt
index 8a87d6a..4376357 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProviderTest.kt
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProviderTest.kt
@@ -17,16 +17,18 @@
 package androidx.camera.camera2.internal
 
 import android.media.CamcorderProfile
-import android.media.EncoderProfiles.VideoProfile.YUV_420
 import android.media.EncoderProfiles.VideoProfile.HDR_NONE
+import android.media.EncoderProfiles.VideoProfile.YUV_420
 import android.os.Build
+import androidx.camera.camera2.internal.compat.quirk.DeviceQuirks
+import androidx.camera.camera2.internal.compat.quirk.InvalidVideoProfilesQuirk
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy.BIT_DEPTH_8
 import androidx.camera.testing.CameraUtil
 import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
-import org.junit.Assume
+import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.Rule
@@ -68,7 +70,6 @@
 
     @Before
     fun setup() {
-        skipTestOnProblematicBuildsOfCuttlefishApi33()
         assumeTrue(CameraUtil.hasCameraWithLensFacing(CameraSelector.LENS_FACING_BACK))
 
         cameraId = CameraUtil.getCameraIdWithLensFacing(CameraSelector.LENS_FACING_BACK)!!
@@ -156,6 +157,7 @@
     @Test
     fun afterApi33_hasSameContentAsEncoderProfiles() {
         assumeTrue(CamcorderProfile.hasProfile(quality))
+        skipTestOnDevicesWithProblematicBuild()
 
         val profiles = CamcorderProfile.getAll(cameraId, quality)
         val video = profiles!!.videoProfiles[0]
@@ -184,13 +186,14 @@
         assertThat(audioProxy.profile).isEqualTo(audio.profile)
     }
 
-    // TODO: removes after b/265613005 is fixed
-    private fun skipTestOnProblematicBuildsOfCuttlefishApi33() {
-        // Skip test for b/265613005
-        Assume.assumeFalse(
-            "Cuttlefish has null VideoProfile issue. Unable to test.",
-            Build.MODEL.contains("Cuttlefish") && Build.VERSION.SDK_INT == 33 &&
-                Build.ID.startsWith("TP1A")
+    private fun skipTestOnDevicesWithProblematicBuild() {
+        // Skip test for b/265613005 and b/223439995
+        val hasVideoProfilesQuirk = DeviceQuirks.get(InvalidVideoProfilesQuirk::class.java) != null
+        val isProblematicCuttlefishBuild =
+            Build.MODEL.contains("Cuttlefish") && Build.ID.startsWith("TP1A")
+        assumeFalse(
+            "Skip test with null VideoProfile issue. Unable to test.",
+            hasVideoProfilesQuirk || isProblematicCuttlefishBuild
         )
     }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CamcorderProfileProvider.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CamcorderProfileProvider.java
deleted file mode 100644
index 4ad7dd3..0000000
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CamcorderProfileProvider.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.camera2.internal;
-
-import android.media.CamcorderProfile;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
-import androidx.camera.camera2.internal.compat.quirk.CamcorderProfileResolutionQuirk;
-import androidx.camera.camera2.internal.compat.quirk.CameraQuirks;
-import androidx.camera.camera2.internal.compat.workaround.CamcorderProfileResolutionValidator;
-import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProvider;
-import androidx.camera.core.impl.CamcorderProfileProxy;
-
-/** An implementation that provides the {@link CamcorderProfileProxy}. */
-@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public class Camera2CamcorderProfileProvider implements CamcorderProfileProvider {
-    private static final String TAG = "Camera2CamcorderProfileProvider";
-
-    private final boolean mHasValidCameraId;
-    private final int mCameraId;
-    private final CamcorderProfileResolutionValidator mCamcorderProfileResolutionValidator;
-
-    public Camera2CamcorderProfileProvider(@NonNull String cameraId,
-            @NonNull CameraCharacteristicsCompat cameraCharacteristics) {
-        boolean hasValidCameraId = false;
-        int intCameraId = -1;
-        try {
-            intCameraId = Integer.parseInt(cameraId);
-            hasValidCameraId = true;
-        } catch (NumberFormatException e) {
-            Logger.w(TAG, "Camera id is not an integer: " + cameraId
-                    + ", unable to create CamcorderProfileProvider");
-        }
-        mHasValidCameraId = hasValidCameraId;
-        mCameraId = intCameraId;
-        CamcorderProfileResolutionQuirk quirk = CameraQuirks.get(cameraId, cameraCharacteristics)
-                .get(CamcorderProfileResolutionQuirk.class);
-        mCamcorderProfileResolutionValidator = new CamcorderProfileResolutionValidator(quirk);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean hasProfile(int quality) {
-        if (!mHasValidCameraId) {
-            return false;
-        }
-
-        if (!CamcorderProfile.hasProfile(mCameraId, quality)) {
-            return false;
-        }
-
-        if (mCamcorderProfileResolutionValidator.hasQuirk()) {
-            // Only get profile when quirk exist for performance concern.
-            CamcorderProfileProxy profile = getProfileInternal(quality);
-            return mCamcorderProfileResolutionValidator.hasValidVideoResolution(profile);
-        }
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    @Nullable
-    public CamcorderProfileProxy get(int quality) {
-        if (!mHasValidCameraId) {
-            return null;
-        }
-
-        if (!CamcorderProfile.hasProfile(mCameraId, quality)) {
-            return null;
-        }
-
-        CamcorderProfileProxy profile = getProfileInternal(quality);
-        if (!mCamcorderProfileResolutionValidator.hasValidVideoResolution(profile)) {
-            return null;
-        }
-        return profile;
-    }
-
-    @Nullable
-    @SuppressWarnings("deprecation")
-    private CamcorderProfileProxy getProfileInternal(int quality) {
-        CamcorderProfile profile = null;
-        try {
-            profile = CamcorderProfile.get(mCameraId, quality);
-        } catch (RuntimeException e) {
-            // CamcorderProfile.get() will throw
-            // - RuntimeException if not able to retrieve camcorder profile params.
-            // - IllegalArgumentException if quality is not valid.
-            Logger.w(TAG, "Unable to get CamcorderProfile by quality: " + quality, e);
-        }
-        return profile != null ? CamcorderProfileProxy.fromCamcorderProfile(profile) : null;
-    }
-}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraFactory.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraFactory.java
index 4cb23e3..bc62ecf 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraFactory.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraFactory.java
@@ -27,10 +27,12 @@
 import androidx.annotation.RequiresApi;
 import androidx.camera.camera2.internal.compat.CameraAccessExceptionCompat;
 import androidx.camera.camera2.internal.compat.CameraManagerCompat;
+import androidx.camera.camera2.internal.concurrent.Camera2CameraCoordinator;
 import androidx.camera.core.CameraSelector;
 import androidx.camera.core.CameraUnavailableException;
 import androidx.camera.core.InitializationException;
 import androidx.camera.core.Logger;
+import androidx.camera.core.concurrent.CameraCoordinator;
 import androidx.camera.core.impl.CameraFactory;
 import androidx.camera.core.impl.CameraInternal;
 import androidx.camera.core.impl.CameraStateRegistry;
@@ -50,6 +52,7 @@
 public final class Camera2CameraFactory implements CameraFactory {
     private static final String TAG = "Camera2CameraFactory";
     private static final int DEFAULT_ALLOWED_CONCURRENT_OPEN_CAMERAS = 1;
+    private final CameraCoordinator mCameraCoordinator;
     private final CameraThreadConfig mThreadConfig;
     private final CameraStateRegistry mCameraStateRegistry;
     private final CameraManagerCompat mCameraManager;
@@ -69,6 +72,7 @@
         List<String> optimizedCameraIds = CameraSelectionOptimizer.getSelectedAvailableCameraIds(
                 this, availableCamerasSelector);
         mAvailableCameraIds = getBackwardCompatibleCameraIds(optimizedCameraIds);
+        mCameraCoordinator = new Camera2CameraCoordinator(mCameraManager);
     }
 
     @Override
@@ -110,6 +114,12 @@
 
     @NonNull
     @Override
+    public CameraCoordinator getCameraCoordinator() {
+        return mCameraCoordinator;
+    }
+
+    @NonNull
+    @Override
     public CameraManagerCompat getCameraManager() {
         return mCameraManager;
     }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
index df26798..a79d18b 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
@@ -54,9 +54,9 @@
 import androidx.camera.core.FocusMeteringAction;
 import androidx.camera.core.Logger;
 import androidx.camera.core.ZoomState;
-import androidx.camera.core.impl.CamcorderProfileProvider;
 import androidx.camera.core.impl.CameraCaptureCallback;
 import androidx.camera.core.impl.CameraInfoInternal;
+import androidx.camera.core.impl.EncoderProfilesProvider;
 import androidx.camera.core.impl.ImageOutputConfig.RotationValue;
 import androidx.camera.core.impl.Quirks;
 import androidx.camera.core.impl.Timebase;
@@ -115,7 +115,7 @@
     @NonNull
     private final Quirks mCameraQuirks;
     @NonNull
-    private final CamcorderProfileProvider mCamera2CamcorderProfileProvider;
+    private final EncoderProfilesProvider mCamera2EncoderProfilesProvider;
     @NonNull
     private final CameraManagerCompat mCameraManager;
 
@@ -131,8 +131,7 @@
         mCameraCharacteristicsCompat = cameraManager.getCameraCharacteristicsCompat(mCameraId);
         mCamera2CameraInfo = new Camera2CameraInfo(this);
         mCameraQuirks = CameraQuirks.get(cameraId, mCameraCharacteristicsCompat);
-        mCamera2CamcorderProfileProvider = new Camera2CamcorderProfileProvider(cameraId,
-                mCameraCharacteristicsCompat);
+        mCamera2EncoderProfilesProvider = new Camera2EncoderProfilesProvider(cameraId);
         mCameraStateLiveData = new RedirectableLiveData<>(
                 CameraState.create(CameraState.Type.CLOSED));
     }
@@ -401,8 +400,8 @@
     /** {@inheritDoc} */
     @NonNull
     @Override
-    public CamcorderProfileProvider getCamcorderProfileProvider() {
-        return mCamera2CamcorderProfileProvider;
+    public EncoderProfilesProvider getEncoderProfilesProvider() {
+        return mCamera2EncoderProfilesProvider;
     }
 
     @NonNull
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProvider.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProvider.java
index a35596c..5103731 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProvider.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2EncoderProfilesProvider.java
@@ -24,6 +24,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
+import androidx.camera.camera2.internal.compat.quirk.DeviceQuirks;
+import androidx.camera.camera2.internal.compat.quirk.InvalidVideoProfilesQuirk;
 import androidx.camera.core.Logger;
 import androidx.camera.core.impl.EncoderProfilesProvider;
 import androidx.camera.core.impl.EncoderProfilesProxy;
@@ -80,23 +82,44 @@
     }
 
     @Nullable
-    @SuppressWarnings("deprecation")
     private EncoderProfilesProxy getProfilesInternal(int quality) {
         if (Build.VERSION.SDK_INT >= 31) {
             EncoderProfiles profiles = Api31Impl.getAll(mCameraId, quality);
-            return profiles != null ? EncoderProfilesProxyCompat.from(profiles) : null;
-        } else {
-            CamcorderProfile profile = null;
-            try {
-                profile = CamcorderProfile.get(mIntCameraId, quality);
-            } catch (RuntimeException e) {
-                // CamcorderProfile.get() will throw
-                // - RuntimeException if not able to retrieve camcorder profile params.
-                // - IllegalArgumentException if quality is not valid.
-                Logger.w(TAG, "Unable to get CamcorderProfile by quality: " + quality, e);
+            if (profiles == null) {
+                return null;
             }
-            return profile != null ? EncoderProfilesProxyCompat.from(profile) : null;
+
+            boolean isVideoProfilesInvalid = DeviceQuirks.get(InvalidVideoProfilesQuirk.class)
+                    != null;
+            if (isVideoProfilesInvalid) {
+                Logger.d(TAG, "EncoderProfiles contains invalid video profiles, use "
+                        + "CamcorderProfile to create EncoderProfilesProxy.");
+            } else {
+                try {
+                    return EncoderProfilesProxyCompat.from(profiles);
+                } catch (NullPointerException e) {
+                    Logger.w(TAG, "Failed to create EncoderProfilesProxy, EncoderProfiles might "
+                            + " contain invalid video profiles. Use CamcorderProfile instead.", e);
+                }
+            }
         }
+
+        return createProfilesFromCamcorderProfile(quality);
+    }
+
+    @Nullable
+    @SuppressWarnings("deprecation")
+    private EncoderProfilesProxy createProfilesFromCamcorderProfile(int quality) {
+        CamcorderProfile profile = null;
+        try {
+            profile = CamcorderProfile.get(mIntCameraId, quality);
+        } catch (RuntimeException e) {
+            // CamcorderProfile.get() will throw
+            // - RuntimeException if not able to retrieve camcorder profile params.
+            // - IllegalArgumentException if quality is not valid.
+            Logger.w(TAG, "Unable to get CamcorderProfile by quality: " + quality, e);
+        }
+        return profile != null ? EncoderProfilesProxyCompat.from(profile) : null;
     }
 
     @RequiresApi(31)
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirk.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirk.java
index 86a0c16..abeb482 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirk.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirk.java
@@ -25,8 +25,8 @@
 import androidx.annotation.RequiresApi;
 import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
 import androidx.camera.camera2.internal.compat.StreamConfigurationMapCompat;
-import androidx.camera.camera2.internal.compat.workaround.CamcorderProfileResolutionValidator;
 import androidx.camera.core.Logger;
+import androidx.camera.core.impl.EncoderProfilesResolutionValidator;
 import androidx.camera.core.impl.ImageFormatConstants;
 import androidx.camera.core.impl.quirk.ProfileResolutionQuirk;
 
@@ -52,7 +52,7 @@
  *                  resolution is contained in the list returned.
  *     Device(s): All legacy devices
  *     @see CamcorderProfile#hasProfile
- *     @see CamcorderProfileResolutionValidator
+ *     @see EncoderProfilesResolutionValidator
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 public class CamcorderProfileResolutionQuirk implements ProfileResolutionQuirk {
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/DeviceQuirksLoader.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/DeviceQuirksLoader.java
index 45aa1b8..ed4d62e 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/DeviceQuirksLoader.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/DeviceQuirksLoader.java
@@ -86,6 +86,9 @@
         if (ExtraSupportedOutputSizeQuirk.load()) {
             quirks.add(new ExtraSupportedOutputSizeQuirk());
         }
+        if (InvalidVideoProfilesQuirk.load()) {
+            quirks.add(new InvalidVideoProfilesQuirk());
+        }
 
         return quirks;
     }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/InvalidVideoProfilesQuirk.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/InvalidVideoProfilesQuirk.java
new file mode 100644
index 0000000..bb4c9e1
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/InvalidVideoProfilesQuirk.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.internal.compat.quirk;
+
+import android.media.EncoderProfiles;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.impl.Quirk;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Quirk denoting the video profile list returns by {@link EncoderProfiles} is invalid.
+ *
+ * <p>QuirkSummary
+ *     Bug Id: 267727595
+ *     Description: When using {@link EncoderProfiles} on TP1A or TD1A builds of Android API 33,
+ *                  {@link EncoderProfiles#getVideoProfiles()} returns a list with size one, but
+ *                  the single value in the list is null. This is not the expected behavior, and
+ *                  makes {@link EncoderProfiles} lack of video information.
+ *     Device(s): Pixel 4 and above pixel devices with TP1A or TD1A builds (API 33).
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+public class InvalidVideoProfilesQuirk implements Quirk {
+
+    static final List<String> AFFECTED_MODELS = Arrays.asList(
+            "pixel 4",
+            "pixel 4a",
+            "pixel 4 xl",
+            "pixel 5",
+            "pixel 5a",
+            "pixel 6",
+            "pixel 6a",
+            "pixel 6 pro",
+            "pixel 7",
+            "pixel 7 pro"
+    );
+
+    static boolean load() {
+        return isAffectedModel() && isAffectedBuild();
+    }
+
+    private static boolean isAffectedModel() {
+        return AFFECTED_MODELS.contains(Build.MODEL.toLowerCase(Locale.US));
+    }
+
+    private static boolean isAffectedBuild() {
+        return isTp1aBuild() || isTd1aBuild();
+    }
+
+    private static boolean isTp1aBuild() {
+        return Build.ID.startsWith("TP1A");
+    }
+
+    private static boolean isTd1aBuild() {
+        return Build.ID.startsWith("TD1A");
+    }
+}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/workaround/CamcorderProfileResolutionValidator.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/workaround/CamcorderProfileResolutionValidator.java
deleted file mode 100644
index e63fcda..0000000
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/workaround/CamcorderProfileResolutionValidator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.camera2.internal.compat.workaround;
-
-import android.media.CamcorderProfile;
-import android.util.Size;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.camera.camera2.internal.compat.quirk.CamcorderProfileResolutionQuirk;
-import androidx.camera.core.impl.CamcorderProfileProxy;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Validates the video resolution of {@link CamcorderProfile}.
- *
- * @see CamcorderProfileResolutionQuirk
- */
-@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public class CamcorderProfileResolutionValidator {
-
-    private final CamcorderProfileResolutionQuirk mQuirk;
-    private final Set<Size> mSupportedResolutions;
-
-    public CamcorderProfileResolutionValidator(@Nullable CamcorderProfileResolutionQuirk quirk) {
-        mQuirk = quirk;
-        mSupportedResolutions = quirk != null ? new HashSet<>(quirk.getSupportedResolutions()) :
-                Collections.emptySet();
-    }
-
-    /** Checks if this validator contains quirk. */
-    public boolean hasQuirk() {
-        return mQuirk != null;
-    }
-
-    /** Checks if the video resolution of CamcorderProfile is valid. */
-    public boolean hasValidVideoResolution(@Nullable CamcorderProfileProxy profile) {
-        if (profile == null) {
-            return false;
-        }
-
-        if (mQuirk == null) {
-            // Quirk doesn't exist, always valid.
-            return true;
-        }
-
-        Size videoSize = new Size(profile.getVideoFrameWidth(), profile.getVideoFrameHeight());
-        return mSupportedResolutions.contains(videoSize);
-    }
-}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinator.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinator.java
new file mode 100644
index 0000000..e1f4760
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinator.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.internal.concurrent;
+
+import android.hardware.camera2.CameraCharacteristics;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
+import androidx.camera.camera2.internal.compat.CameraAccessExceptionCompat;
+import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
+import androidx.camera.camera2.internal.compat.CameraManagerCompat;
+import androidx.camera.camera2.interop.Camera2CameraInfo;
+import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
+import androidx.camera.core.CameraInfo;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.Logger;
+import androidx.camera.core.concurrent.CameraCoordinator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Implementation for {@link CameraCoordinator}.
+ */
+@RequiresApi(21)
+public class Camera2CameraCoordinator implements CameraCoordinator {
+
+    private static final String TAG = "Camera2CameraCoordinator";
+
+    @NonNull private final CameraManagerCompat mCameraManager;
+    @NonNull private Map<String, String> mConcurrentCameraIdMap;
+    @NonNull private Set<Set<String>> mConcurrentCameraIds;
+    @NonNull private final List<ConcurrentCameraModeListener> mConcurrentCameraModeListeners;
+
+    private boolean mIsConcurrentCameraModeOn;
+
+    public Camera2CameraCoordinator(@NonNull CameraManagerCompat cameraManager) {
+        mCameraManager = cameraManager;
+        mConcurrentCameraIdMap = new HashMap<>();
+        mConcurrentCameraIds = new HashSet<>();
+        mConcurrentCameraModeListeners = new ArrayList<>();
+    }
+
+    @Override
+    public void init() {
+        mConcurrentCameraIds = retrieveConcurrentCameraIds(mCameraManager);
+        for (Set<String> concurrentCameraIdList: mConcurrentCameraIds) {
+            List<String> cameraIdList = new ArrayList<>(concurrentCameraIdList);
+
+            // TODO(b/268531569): enumerate concurrent camera ids and convert to a map for
+            //  paired camera id lookup.
+            mConcurrentCameraIdMap.put(cameraIdList.get(0), cameraIdList.get(1));
+            mConcurrentCameraIdMap.put(cameraIdList.get(1), cameraIdList.get(0));
+        }
+    }
+
+    @NonNull
+    @Override
+    public List<List<CameraSelector>> getConcurrentCameraSelectors() {
+        List<List<CameraSelector>> concurrentCameraSelectorLists = new ArrayList<>();
+        for (Set<String> concurrentCameraIdList: mConcurrentCameraIds) {
+            List<CameraSelector> cameraSelectors = new ArrayList<>();
+            for (String concurrentCameraId : concurrentCameraIdList) {
+                cameraSelectors.add(createCameraSelectorById(mCameraManager, concurrentCameraId));
+            }
+            concurrentCameraSelectorLists.add(cameraSelectors);
+        }
+        return concurrentCameraSelectorLists;
+    }
+
+    @Nullable
+    @Override
+    public String getPairedConcurrentCameraId(@NonNull String cameraId) {
+        if (mConcurrentCameraIdMap.containsKey(cameraId)) {
+            return mConcurrentCameraIdMap.get(cameraId);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isConcurrentCameraModeOn() {
+        return mIsConcurrentCameraModeOn;
+    }
+
+    @Override
+    public void setConcurrentCameraMode(boolean isConcurrentCameraModeOn) {
+        if (isConcurrentCameraModeOn != mIsConcurrentCameraModeOn) {
+            for (ConcurrentCameraModeListener listener : mConcurrentCameraModeListeners) {
+                listener.notifyConcurrentCameraModeUpdated(isConcurrentCameraModeOn);
+            }
+        }
+        mIsConcurrentCameraModeOn = isConcurrentCameraModeOn;
+    }
+
+    @Override
+    public void addListener(@NonNull ConcurrentCameraModeListener listener) {
+        mConcurrentCameraModeListeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(@NonNull ConcurrentCameraModeListener listener) {
+        mConcurrentCameraModeListeners.remove(listener);
+    }
+
+    @NonNull
+    private static Set<Set<String>> retrieveConcurrentCameraIds(
+            @NonNull CameraManagerCompat cameraManager) {
+        Set<Set<String>> map = new HashSet<>();
+        try {
+            map = cameraManager.getConcurrentCameraIds();
+        } catch (CameraAccessExceptionCompat e) {
+            Logger.e(TAG, "Failed to get concurrent camera ids");
+        }
+        return map;
+    }
+
+    @OptIn(markerClass = ExperimentalCamera2Interop.class)
+    private static CameraSelector createCameraSelectorById(
+            @NonNull CameraManagerCompat cameraManager,
+            @NonNull String cameraId) {
+        CameraSelector.Builder builder =
+                new CameraSelector.Builder().addCameraFilter(cameraInfos -> {
+                    for (CameraInfo cameraInfo : cameraInfos) {
+                        if (cameraId.equals(Camera2CameraInfo.from(cameraInfo).getCameraId())) {
+                            return Collections.singletonList(cameraInfo);
+                        }
+                    }
+
+                    throw new IllegalArgumentException("No camera can be find for id: " + cameraId);
+                });
+
+        try {
+            CameraCharacteristicsCompat cameraCharacteristics =
+                    cameraManager.getCameraCharacteristicsCompat(cameraId);
+            Integer cameraLensFacing = cameraCharacteristics.get(
+                    CameraCharacteristics.LENS_FACING);
+            builder.requireLensFacing(cameraLensFacing);
+        } catch (CameraAccessExceptionCompat e) {
+            throw new RuntimeException(e);
+        }
+
+        return builder.build();
+    }
+}
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt
index 760a818..1a822dd 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package androidx.camera.camera2.internal
 
 import android.content.Context
@@ -21,6 +22,10 @@
 import android.hardware.camera2.CameraCharacteristics
 import android.hardware.camera2.CameraMetadata
 import android.media.CamcorderProfile
+import android.media.CamcorderProfile.QUALITY_1080P
+import android.media.CamcorderProfile.QUALITY_2160P
+import android.media.CamcorderProfile.QUALITY_480P
+import android.media.CamcorderProfile.QUALITY_720P
 import android.os.Build
 import android.util.Pair
 import android.util.Range
@@ -62,16 +67,16 @@
 import androidx.camera.core.impl.utils.CompareSizesByArea
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
 import androidx.camera.core.internal.utils.SizeUtil.RESOLUTION_VGA
-import androidx.camera.testing.CamcorderProfileUtil
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.CameraXUtil
 import androidx.camera.testing.Configs
+import androidx.camera.testing.EncoderProfilesUtil
 import androidx.camera.testing.SurfaceTextureProvider
 import androidx.camera.testing.SurfaceTextureProvider.SurfaceTextureCallback
-import androidx.camera.testing.fakes.FakeCamcorderProfileProvider
 import androidx.camera.testing.fakes.FakeCamera
 import androidx.camera.testing.fakes.FakeCameraFactory
 import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import androidx.camera.testing.fakes.FakeEncoderProfilesProvider
 import androidx.camera.testing.fakes.FakeUseCaseConfig
 import androidx.camera.video.FallbackStrategy
 import androidx.camera.video.MediaSpec
@@ -145,18 +150,17 @@
         CamcorderProfile::class.java
     )
     private var cameraManagerCompat: CameraManagerCompat? = null
-    private val profileUhd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_2160P, RECORD_SIZE.width, RECORD_SIZE.height
+    private val profileUhd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        RECORD_SIZE.width, RECORD_SIZE.height
     )
-    private val profileFhd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_1080P, 1920, 1080
+    private val profileFhd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        1920, 1080
     )
-    private val profileHd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_720P, PREVIEW_SIZE.width, PREVIEW_SIZE.height
+    private val profileHd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        PREVIEW_SIZE.width, PREVIEW_SIZE.height
     )
-    private val profileSd = CamcorderProfileUtil.createCamcorderProfileProxy(
-        CamcorderProfile.QUALITY_480P, RESOLUTION_VGA.width,
-        RESOLUTION_VGA.height
+    private val profileSd = EncoderProfilesUtil.createFakeEncoderProfilesProxy(
+        RESOLUTION_VGA.width, RESOLUTION_VGA.height
     )
     private val context = ApplicationProvider.getApplicationContext<Context>()
     private var cameraFactory: FakeCameraFactory? = null
@@ -3052,15 +3056,12 @@
             sensorOrientation,
             CameraCharacteristics.LENS_FACING_BACK
         ).apply {
-            camcorderProfileProvider = FakeCamcorderProfileProvider.Builder()
-                .addProfile(
-                    CamcorderProfileUtil.asHighQuality(profileUhd),
-                    profileUhd,
-                    profileFhd,
-                    profileHd,
-                    profileSd,
-                    CamcorderProfileUtil.asLowQuality(profileSd)
-                ).build()
+            encoderProfilesProvider = FakeEncoderProfilesProvider.Builder()
+                .add(QUALITY_2160P, profileUhd)
+                .add(QUALITY_1080P, profileFhd)
+                .add(QUALITY_720P, profileHd)
+                .add(QUALITY_480P, profileSd)
+                .build()
         }
 
         cameraFactory = FakeCameraFactory().apply {
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt
index f052a5a..baecee6 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt
@@ -23,8 +23,8 @@
 import android.os.Build
 import android.util.Size
 import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_1080P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_2160P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_1080P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_2160P
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -40,10 +40,10 @@
 @RunWith(RobolectricTestRunner::class)
 @DoNotInstrument
 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
-public class CamcorderProfileResolutionQuirkTest {
+class CamcorderProfileResolutionQuirkTest {
 
     @Test
-    public fun loadByHardwareLevel() {
+    fun loadByHardwareLevel() {
         var cameraCharacteristicsCompat =
             createCameraCharacteristicsCompat(CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
         assertThat(CamcorderProfileResolutionQuirk.load(cameraCharacteristicsCompat)).isFalse()
@@ -62,7 +62,7 @@
     }
 
     @Test
-    public fun canGetCorrectSupportedSizes() {
+    fun canGetCorrectSupportedSizes() {
         val cameraCharacteristicsCompat =
             createCameraCharacteristicsCompat(
                 supportedSizes = arrayOf(
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/workaround/CamcorderProfileResolutionValidatorTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/workaround/CamcorderProfileResolutionValidatorTest.kt
deleted file mode 100644
index 5787efb..0000000
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/workaround/CamcorderProfileResolutionValidatorTest.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.camera2.internal.compat.workaround
-
-import android.graphics.SurfaceTexture
-import android.hardware.camera2.CameraCharacteristics
-import android.hardware.camera2.params.StreamConfigurationMap
-import android.os.Build
-import android.util.Size
-import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat
-import androidx.camera.camera2.internal.compat.quirk.CamcorderProfileResolutionQuirk
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_2160P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_720P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_2160P
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers
-import org.mockito.Mockito
-import org.mockito.Mockito.`when`
-import org.robolectric.RobolectricTestRunner
-import org.robolectric.annotation.Config
-import org.robolectric.annotation.internal.DoNotInstrument
-import org.robolectric.shadow.api.Shadow
-import org.robolectric.shadows.ShadowCameraCharacteristics
-
-@RunWith(RobolectricTestRunner::class)
-@DoNotInstrument
-@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
-public class CamcorderProfileResolutionValidatorTest {
-
-    @Test
-    public fun noQuirk_alwaysValid() {
-        val validator = CamcorderProfileResolutionValidator(null)
-
-        assertThat(validator.hasValidVideoResolution(PROFILE_2160P)).isTrue()
-        assertThat(validator.hasValidVideoResolution(PROFILE_720P)).isTrue()
-    }
-
-    @Test
-    public fun hasQuirk_shouldCheckSupportedResolutions() {
-        val cameraCharacteristicsCompat = createCameraCharacteristicsCompat(
-            supportedResolution = arrayOf(RESOLUTION_2160P)
-        )
-        val quirk = CamcorderProfileResolutionQuirk(cameraCharacteristicsCompat)
-        val validator = CamcorderProfileResolutionValidator(quirk)
-
-        assertThat(validator.hasValidVideoResolution(PROFILE_2160P)).isTrue()
-        assertThat(validator.hasValidVideoResolution(PROFILE_720P)).isFalse()
-    }
-
-    @Test
-    public fun nullProfile_notValid() {
-        val cameraCharacteristicsCompat = createCameraCharacteristicsCompat(
-            supportedResolution = arrayOf(RESOLUTION_2160P)
-        )
-        val quirk = CamcorderProfileResolutionQuirk(cameraCharacteristicsCompat)
-        val validator = CamcorderProfileResolutionValidator(quirk)
-
-        assertThat(validator.hasValidVideoResolution(null)).isFalse()
-    }
-
-    private fun createCameraCharacteristicsCompat(
-        supportedResolution: Array<Size> = emptyArray()
-    ): CameraCharacteristicsCompat {
-        val characteristics = ShadowCameraCharacteristics.newCameraCharacteristics()
-        val shadowCharacteristics = Shadow.extract<ShadowCameraCharacteristics>(characteristics)
-
-        val mockMap = Mockito.mock(StreamConfigurationMap::class.java)
-
-        // Before Android 23, use {@link SurfaceTexture} will finally mapped to 0x22 in
-        // StreamConfigurationMap to retrieve the output sizes information.
-        `when`(mockMap.getOutputSizes(ArgumentMatchers.any<Class<SurfaceTexture>>()))
-            .thenReturn(supportedResolution)
-        `when`(mockMap.getOutputSizes(ArgumentMatchers.anyInt()))
-            .thenReturn(supportedResolution)
-
-        shadowCharacteristics.set(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP, mockMap)
-
-        return CameraCharacteristicsCompat.toCameraCharacteristicsCompat(characteristics)
-    }
-}
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
new file mode 100644
index 0000000..4eae589
--- /dev/null
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2023 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 androidx.camera.camera2.internal.concurrent
+
+import android.hardware.camera2.CameraCharacteristics
+import android.hardware.camera2.CameraDevice
+import android.hardware.camera2.CameraManager
+import android.os.Build
+import androidx.camera.camera2.internal.compat.CameraManagerCompat
+import androidx.camera.core.concurrent.CameraCoordinator
+import androidx.camera.core.impl.utils.MainThreadAsyncHandler
+import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+
+@RunWith(RobolectricTestRunner::class)
+@DoNotInstrument
+@Config(
+    minSdk = Build.VERSION_CODES.LOLLIPOP,
+    instrumentedPackages = ["androidx.camera.camera2.internal"]
+)
+class Camera2CameraCoordinatorTest {
+
+    private lateinit var cameraCoordinator: CameraCoordinator
+
+    @Before
+    fun setup() {
+        val fakeCameraImpl = FakeCameraManagerImpl()
+        val cameraCharacteristics0 = mock(CameraCharacteristics::class.java)
+        Mockito.`when`(cameraCharacteristics0.get(CameraCharacteristics.LENS_FACING))
+            .thenReturn(CameraCharacteristics.LENS_FACING_BACK)
+        val cameraCharacteristics1 = mock(CameraCharacteristics::class.java)
+        Mockito.`when`(cameraCharacteristics1.get(CameraCharacteristics.LENS_FACING))
+            .thenReturn(CameraCharacteristics.LENS_FACING_FRONT)
+        fakeCameraImpl.addCamera("0", cameraCharacteristics0)
+        fakeCameraImpl.addCamera("1", cameraCharacteristics1)
+        cameraCoordinator = Camera2CameraCoordinator(CameraManagerCompat.from(fakeCameraImpl))
+        cameraCoordinator.init()
+    }
+
+    @Test
+    fun getConcurrentCameraSelectors() {
+        assertThat(cameraCoordinator.concurrentCameraSelectors).isNotEmpty()
+        assertThat(cameraCoordinator.concurrentCameraSelectors[0]).isNotEmpty()
+        assertThat(cameraCoordinator.concurrentCameraSelectors[0][0].lensFacing)
+            .isEqualTo(CameraCharacteristics.LENS_FACING_BACK)
+        assertThat(cameraCoordinator.concurrentCameraSelectors[0][1].lensFacing)
+            .isEqualTo(CameraCharacteristics.LENS_FACING_FRONT)
+    }
+
+    @Test
+    fun getPairedCameraId() {
+        assertThat(cameraCoordinator.getPairedConcurrentCameraId("0")).isEqualTo("1")
+        assertThat(cameraCoordinator.getPairedConcurrentCameraId("1")).isEqualTo("0")
+    }
+
+    @Test
+    fun setAndIsConcurrentCameraMode() {
+        assertThat(cameraCoordinator.isConcurrentCameraModeOn).isFalse()
+        cameraCoordinator.setConcurrentCameraMode(true)
+        assertThat(cameraCoordinator.isConcurrentCameraModeOn).isTrue()
+        cameraCoordinator.setConcurrentCameraMode(false)
+        assertThat(cameraCoordinator.isConcurrentCameraModeOn).isFalse()
+    }
+
+    @Test
+    fun addAndRemoveListener() {
+        val listener = mock(CameraCoordinator.ConcurrentCameraModeListener::class.java)
+        cameraCoordinator.addListener(listener)
+        cameraCoordinator.setConcurrentCameraMode(true)
+        verify(listener).notifyConcurrentCameraModeUpdated(true)
+        cameraCoordinator.setConcurrentCameraMode(false)
+        verify(listener).notifyConcurrentCameraModeUpdated(false)
+
+        reset(listener)
+        cameraCoordinator.removeListener(listener)
+        cameraCoordinator.setConcurrentCameraMode(true)
+        verify(listener, never()).notifyConcurrentCameraModeUpdated(true)
+    }
+
+    private class FakeCameraManagerImpl : CameraManagerCompat.CameraManagerCompatImpl {
+
+        private val mCameraManagerImpl = CameraManagerCompat.CameraManagerCompatImpl.from(
+            ApplicationProvider.getApplicationContext(),
+            MainThreadAsyncHandler.getInstance()
+        )
+
+        private val mCameraIdCharacteristics = HashMap<String, CameraCharacteristics>()
+
+        fun addCamera(
+            cameraId: String,
+            cameraCharacteristics: CameraCharacteristics
+        ) {
+            mCameraIdCharacteristics[cameraId] = cameraCharacteristics
+        }
+
+        override fun getCameraIdList(): Array<String> {
+            return mCameraIdCharacteristics.keys.toTypedArray()
+        }
+
+        override fun getConcurrentCameraIds(): MutableSet<MutableSet<String>> {
+            return mutableSetOf(mCameraIdCharacteristics.keys)
+        }
+
+        override fun registerAvailabilityCallback(
+            executor: Executor,
+            callback: CameraManager.AvailabilityCallback
+        ) {
+        }
+
+        override fun unregisterAvailabilityCallback(callback: CameraManager.AvailabilityCallback) {
+        }
+
+        override fun getCameraCharacteristics(cameraId: String): CameraCharacteristics {
+            return mCameraIdCharacteristics[cameraId]!!
+        }
+
+        override fun openCamera(
+            cameraId: String,
+            executor: Executor,
+            callback: CameraDevice.StateCallback
+        ) {
+        }
+
+        override fun getCameraManager(): CameraManager {
+            return mCameraManagerImpl.cameraManager
+        }
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CamcorderProfileProxyTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CamcorderProfileProxyTest.kt
deleted file mode 100644
index ce31a22..0000000
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CamcorderProfileProxyTest.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.core.impl
-
-import android.media.CamcorderProfile
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SdkSuppress
-import androidx.test.filters.SmallTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Assume.assumeTrue
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-@Suppress("DEPRECATION")
-@SdkSuppress(minSdkVersion = 21)
-public class CamcorderProfileProxyTest {
-
-    @Test
-    public fun createInstance() {
-        // QUALITY_HIGH is guaranteed to be supported.
-        assumeTrue(CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH))
-
-        val profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)
-        val profileProxy = CamcorderProfileProxy.fromCamcorderProfile(profile)
-
-        assertThat(profileProxy.duration).isEqualTo(profile.duration)
-        assertThat(profileProxy.quality).isEqualTo(profile.quality)
-        assertThat(profileProxy.fileFormat).isEqualTo(profile.fileFormat)
-        assertThat(profileProxy.videoCodec).isEqualTo(profile.videoCodec)
-        assertThat(profileProxy.videoBitRate).isEqualTo(profile.videoBitRate)
-        assertThat(profileProxy.videoFrameRate).isEqualTo(profile.videoFrameRate)
-        assertThat(profileProxy.videoFrameWidth).isEqualTo(profile.videoFrameWidth)
-        assertThat(profileProxy.videoFrameHeight).isEqualTo(profile.videoFrameHeight)
-        assertThat(profileProxy.audioCodec).isEqualTo(profile.audioCodec)
-        assertThat(profileProxy.audioBitRate).isEqualTo(profile.audioBitRate)
-        assertThat(profileProxy.audioSampleRate).isEqualTo(profile.audioSampleRate)
-        assertThat(profileProxy.audioChannels).isEqualTo(profile.audioChannels)
-    }
-}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java
index 58183ca..7416ee1 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java
@@ -17,11 +17,15 @@
 
 import static androidx.core.util.Preconditions.checkArgument;
 
+import static java.util.Objects.requireNonNull;
+
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
+import androidx.camera.core.processing.SurfaceProcessorInternal;
+import androidx.camera.core.processing.SurfaceProcessorWithExecutor;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -195,4 +199,21 @@
     public ImageProcessor getImageProcessor() {
         return mImageProcessor;
     }
+
+    // --- Internal methods ---
+
+    /**
+     * Creates a {@link SurfaceProcessorInternal} instance.
+     *
+     * <p>Throws {@link IllegalArgumentException} if the effect does not contain a
+     * {@link SurfaceProcessor}.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @NonNull
+    public SurfaceProcessorInternal createSurfaceProcessorInternal() {
+        return new SurfaceProcessorWithExecutor(requireNonNull(getSurfaceProcessor()),
+                getExecutor());
+    }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index d5f8971..75bbe4f 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -340,9 +340,6 @@
     @SuppressWarnings("WeakerAccess")
     final Executor mSequentialIoExecutor;
 
-    @Nullable
-    private CameraEffect mCameraEffect;
-
     /**
      * Creates a new image capture use case from the given configuration.
      *
@@ -1664,7 +1661,7 @@
         Size resolution = streamSpec.getResolution();
 
         checkState(mImagePipeline == null);
-        mImagePipeline = new ImagePipeline(config, resolution, mCameraEffect);
+        mImagePipeline = new ImagePipeline(config, resolution, getEffect());
 
         if (mTakePictureManager == null) {
             // mTakePictureManager is reused when the Surface is reset.
@@ -1805,27 +1802,6 @@
         return mImagePipeline != null && mTakePictureManager != null;
     }
 
-    /**
-     * @hide
-     */
-    @MainThread
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    public void setEffect(@Nullable CameraEffect cameraEffect) {
-        checkMainThread();
-        mCameraEffect = cameraEffect;
-    }
-
-    /**
-     * @hide
-     */
-    @MainThread
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public CameraEffect getEffect() {
-        checkMainThread();
-        return mCameraEffect;
-    }
-
     @VisibleForTesting
     @NonNull
     TakePictureManager getTakePictureManager() {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
index c2af128..72331e6 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
@@ -82,12 +82,10 @@
 import androidx.camera.core.impl.UseCaseConfig;
 import androidx.camera.core.impl.UseCaseConfigFactory;
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
-import androidx.camera.core.internal.CameraUseCaseAdapter;
 import androidx.camera.core.internal.TargetConfig;
 import androidx.camera.core.internal.ThreadConfig;
 import androidx.camera.core.processing.Node;
 import androidx.camera.core.processing.SurfaceEdge;
-import androidx.camera.core.processing.SurfaceProcessorInternal;
 import androidx.camera.core.processing.SurfaceProcessorNode;
 import androidx.core.util.Consumer;
 import androidx.lifecycle.LifecycleOwner;
@@ -191,9 +189,6 @@
     private Size mSurfaceSize;
 
     @Nullable
-    private SurfaceProcessorInternal mSurfaceProcessor;
-
-    @Nullable
     private SurfaceProcessorNode mNode;
 
     /**
@@ -213,7 +208,7 @@
             @NonNull StreamSpec streamSpec) {
         // Build pipeline with node if processor is set. Eventually we will move all the code to
         // createPipelineWithNode.
-        if (mSurfaceProcessor != null) {
+        if (getEffect() != null) {
             return createPipelineWithNode(cameraId, config, streamSpec);
         }
 
@@ -251,14 +246,13 @@
             @NonNull StreamSpec streamSpec) {
         // Check arguments
         checkMainThread();
-        checkNotNull(mSurfaceProcessor);
-        CameraInternal camera = getCamera();
-        checkNotNull(camera);
+        CameraEffect effect = requireNonNull(getEffect());
+        CameraInternal camera = requireNonNull(getCamera());
 
         clearPipeline();
 
         // Create nodes and edges.
-        mNode = new SurfaceProcessorNode(camera, mSurfaceProcessor);
+        mNode = new SurfaceProcessorNode(camera, effect.createSurfaceProcessorInternal());
         // Make sure the previously created camera edge is cleared before creating a new one.
         checkState(mCameraEdge == null);
         mCameraEdge = new SurfaceEdge(
@@ -311,31 +305,6 @@
     }
 
     /**
-     * Sets a {@link SurfaceProcessorInternal}.
-     *
-     * <p>Internal API invoked by {@link CameraUseCaseAdapter}. {@link #createPipeline} uses the
-     * value to setup post-processing pipeline.
-     *
-     * @hide
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    public void setProcessor(@Nullable SurfaceProcessorInternal surfaceProcessor) {
-        mSurfaceProcessor = surfaceProcessor;
-    }
-
-    /**
-     * Gets the {@link SurfaceProcessorInternal} for testing.
-     *
-     * @hide
-     */
-    @Nullable
-    @VisibleForTesting
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    public SurfaceProcessorInternal getProcessor() {
-        return mSurfaceProcessor;
-    }
-
-    /**
      * Creates previously allocated {@link DeferrableSurface} include those allocated by nodes.
      */
     private void clearPipeline() {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
index ea17bcd..47c501d 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
@@ -147,6 +147,9 @@
     @GuardedBy("mCameraLock")
     private CameraInternal mCamera;
 
+    @Nullable
+    private CameraEffect mEffect;
+
     ////////////////////////////////////////////////////////////////////////////////////////////
     // [UseCase attached dynamic] - Can change but is only available when the UseCase is attached.
     ////////////////////////////////////////////////////////////////////////////////////////////
@@ -791,6 +794,27 @@
     }
 
     /**
+     * Sets the {@link CameraEffect} associated with this use case.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    public void setEffect(@Nullable CameraEffect effect) {
+        mEffect = effect;
+    }
+
+    /**
+     * Gets the {@link CameraEffect} associated with this use case.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    public CameraEffect getEffect() {
+        return mEffect;
+    }
+
+    /**
      * Sets whether the producer writes camera transform to the {@link Surface}.
      *
      * @hide
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/concurrent/CameraCoordinator.java b/camera/camera-core/src/main/java/androidx/camera/core/concurrent/CameraCoordinator.java
new file mode 100644
index 0000000..7ade18a
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/concurrent/CameraCoordinator.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2023 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 androidx.camera.core.concurrent;
+
+
+import android.hardware.camera2.CameraManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.impl.CameraStateRegistry;
+
+import java.util.List;
+
+/**
+ * Coordinator for concurrent camera.
+ *
+ * <p>It coordinates the order of camera device open and camera capture session configuration.
+ * All camera devices intended to be operated concurrently, must be opened before configuring
+ * sessions on any of the camera devices.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@RequiresApi(21)
+public interface CameraCoordinator {
+
+    /**
+     * Initializes the map for concurrent camera ids and convert camera ids to camera selectors.
+     */
+    void init();
+
+    /**
+     * Returns concurrent camera selectors, which are converted from concurrent camera ids
+     * queried from {@link CameraManager#getConcurrentCameraIds()}.
+     *
+     * <p>This API is exposed to external users to select one combination of supported concurrent
+     * {@link CameraSelector}s to bind.
+     *
+     * @return List of list of {@link CameraSelector}.
+     */
+    @NonNull
+    List<List<CameraSelector>> getConcurrentCameraSelectors();
+
+    /**
+     * Returns paired camera id in concurrent mode.
+     *
+     * <p>The paired camera id dictionary is constructed when {@link CameraCoordinator#init()} is
+     * called. This internal API is used to look up paired camera id when coordinating device
+     * open and session config in {@link CameraStateRegistry}. Currently only dual cameras will
+     * be supported in concurrent mode.
+     *
+     * @param cameraId camera id.
+     * @return The paired camera id if exists or null if paired camera not exists.
+     */
+    @Nullable
+    String getPairedConcurrentCameraId(@NonNull String cameraId);
+
+    /**
+     * Returns concurrent camera mode.
+     *
+     * @return true if concurrent mode is on, otherwise returns false.
+     */
+    boolean isConcurrentCameraModeOn();
+
+    /**
+     * Sets concurrent camera mode.
+     *
+     * <p>This internal API will be called when user binds user cases to cameras, which will
+     * enable or disable concurrent camera mode based on the input config.
+     *
+     * @param enabled true if concurrent camera mode is enabled, otherwise false.
+     */
+    void setConcurrentCameraMode(boolean enabled);
+
+    /**
+     * Adds listener for concurrent camera mode update.
+     * @param listener
+     */
+    void addListener(@NonNull ConcurrentCameraModeListener listener);
+
+    /**
+     * Removes listener for concurrent camera mode update.
+     * @param listener
+     */
+    void removeListener(@NonNull ConcurrentCameraModeListener listener);
+
+    /**
+     * Interface for concurrent camera mode update.
+     *
+     * <p>Everytime user sets concurrent mode, the observer will be notified and update related
+     * states or parameters accordingly. E.g. in
+     * {@link CameraStateRegistry}, we will update the number of max
+     * allowed cameras if concurrent mode is set.
+     */
+    interface ConcurrentCameraModeListener {
+        void notifyConcurrentCameraModeUpdated(boolean isConcurrentCameraModeOn);
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CamcorderProfileProvider.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CamcorderProfileProvider.java
deleted file mode 100644
index e8ed228..0000000
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CamcorderProfileProvider.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.core.impl;
-
-import android.media.CamcorderProfile;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-
-/**
- * CamcorderProfileProvider is used to obtain the {@link CamcorderProfileProxy}.
- */
-@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public interface CamcorderProfileProvider {
-
-    /**
-     * Check if the quality is supported on this device.
-     *
-     * <p>The quality should be one of quality constants defined in {@link CamcorderProfile}.
-     */
-    boolean hasProfile(int quality);
-
-    /**
-     * Gets the {@link CamcorderProfileProxy} if the quality is supported on the device.
-     *
-     * <p>The quality should be one of quality constants defined in {@link CamcorderProfile}.
-     *
-     * @see #hasProfile(int)
-     */
-    @Nullable
-    CamcorderProfileProxy get(int quality);
-
-    /** An implementation that contains no data. */
-    CamcorderProfileProvider EMPTY = new CamcorderProfileProvider() {
-        @Override
-        public boolean hasProfile(int quality) {
-            return false;
-        }
-
-        @Nullable
-        @Override
-        public CamcorderProfileProxy get(int quality) {
-            return null;
-        }
-    };
-}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CamcorderProfileProxy.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CamcorderProfileProxy.java
deleted file mode 100644
index 325c32f..0000000
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CamcorderProfileProxy.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.core.impl;
-
-import static android.media.MediaRecorder.AudioEncoder.AAC;
-import static android.media.MediaRecorder.AudioEncoder.AAC_ELD;
-import static android.media.MediaRecorder.AudioEncoder.AMR_NB;
-import static android.media.MediaRecorder.AudioEncoder.AMR_WB;
-import static android.media.MediaRecorder.AudioEncoder.HE_AAC;
-import static android.media.MediaRecorder.AudioEncoder.OPUS;
-import static android.media.MediaRecorder.AudioEncoder.VORBIS;
-import static android.media.MediaRecorder.VideoEncoder.H263;
-import static android.media.MediaRecorder.VideoEncoder.H264;
-import static android.media.MediaRecorder.VideoEncoder.HEVC;
-import static android.media.MediaRecorder.VideoEncoder.MPEG_4_SP;
-import static android.media.MediaRecorder.VideoEncoder.VP8;
-
-import android.media.CamcorderProfile;
-import android.media.MediaCodecInfo;
-import android.media.MediaFormat;
-import android.media.MediaRecorder;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-
-import com.google.auto.value.AutoValue;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * CamcorderProfileProxy defines the get methods that is mapping to the fields of
- * {@link CamcorderProfile}.
- */
-@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-@AutoValue
-public abstract class CamcorderProfileProxy {
-
-    /** Constant representing no codec profile. */
-    public static int CODEC_PROFILE_NONE = -1;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({H263, H264, HEVC, VP8, MPEG_4_SP, MediaRecorder.VideoEncoder.DEFAULT})
-    @interface VideoEncoder {
-    }
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({AAC, AAC_ELD, AMR_NB, AMR_WB, HE_AAC, OPUS, VORBIS,
-            MediaRecorder.AudioEncoder.DEFAULT})
-    @interface AudioEncoder {
-    }
-
-    /** Creates a CamcorderProfileProxy instance. */
-    @NonNull
-    public static CamcorderProfileProxy create(int duration,
-            int quality,
-            int fileFormat,
-            @VideoEncoder int videoCodec,
-            int videoBitRate,
-            int videoFrameRate,
-            int videoFrameWidth,
-            int videoFrameHeight,
-            @AudioEncoder int audioCodec,
-            int audioBitRate,
-            int audioSampleRate,
-            int audioChannels) {
-        return new AutoValue_CamcorderProfileProxy(
-                duration,
-                quality,
-                fileFormat,
-                videoCodec,
-                videoBitRate,
-                videoFrameRate,
-                videoFrameWidth,
-                videoFrameHeight,
-                audioCodec,
-                audioBitRate,
-                audioSampleRate,
-                audioChannels
-        );
-    }
-
-    /** Creates a CamcorderProfileProxy instance from {@link CamcorderProfile}. */
-    @NonNull
-    public static CamcorderProfileProxy fromCamcorderProfile(
-            @NonNull CamcorderProfile camcorderProfile) {
-        return new AutoValue_CamcorderProfileProxy(
-                camcorderProfile.duration,
-                camcorderProfile.quality,
-                camcorderProfile.fileFormat,
-                camcorderProfile.videoCodec,
-                camcorderProfile.videoBitRate,
-                camcorderProfile.videoFrameRate,
-                camcorderProfile.videoFrameWidth,
-                camcorderProfile.videoFrameHeight,
-                camcorderProfile.audioCodec,
-                camcorderProfile.audioBitRate,
-                camcorderProfile.audioSampleRate,
-                camcorderProfile.audioChannels
-        );
-    }
-
-    /** @see CamcorderProfile#duration */
-    public abstract int getDuration();
-
-    /** @see CamcorderProfile#quality */
-    public abstract int getQuality();
-
-    /** @see CamcorderProfile#fileFormat */
-    public abstract int getFileFormat();
-
-    /** @see CamcorderProfile#videoCodec */
-    @VideoEncoder
-    public abstract int getVideoCodec();
-
-    /** @see CamcorderProfile#videoBitRate */
-    public abstract int getVideoBitRate();
-
-    /** @see CamcorderProfile#videoFrameRate */
-    public abstract int getVideoFrameRate();
-
-    /** @see CamcorderProfile#videoFrameWidth */
-    public abstract int getVideoFrameWidth();
-
-    /** @see CamcorderProfile#videoFrameHeight */
-    public abstract int getVideoFrameHeight();
-
-    /** @see CamcorderProfile#audioCodec */
-    @AudioEncoder
-    public abstract int getAudioCodec();
-
-    /** @see CamcorderProfile#audioBitRate */
-    public abstract int getAudioBitRate();
-
-    /** @see CamcorderProfile#audioSampleRate */
-    public abstract int getAudioSampleRate();
-
-    /** @see CamcorderProfile#audioChannels */
-    public abstract int getAudioChannels();
-
-    /**
-     * Returns a mime-type string for the video codec type returned by {@link #getVideoCodec()}.
-     *
-     * @return A mime-type string or {@code null} if the codec type is
-     * {@link android.media.MediaRecorder.VideoEncoder#DEFAULT}, as this type is under-defined
-     * and cannot be resolved to a specific mime type without more information.
-     */
-    @Nullable
-    public String getVideoCodecMimeType() {
-        // Mime-type definitions taken from
-        // frameworks/av/media/libstagefright/foundation/MediaDefs.cpp
-        switch (getVideoCodec()) {
-            case H263:
-                return MediaFormat.MIMETYPE_VIDEO_H263;
-            case H264:
-                return MediaFormat.MIMETYPE_VIDEO_AVC;
-            case HEVC:
-                return MediaFormat.MIMETYPE_VIDEO_HEVC;
-            case VP8:
-                return MediaFormat.MIMETYPE_VIDEO_VP8;
-            case MPEG_4_SP:
-                return MediaFormat.MIMETYPE_VIDEO_MPEG4;
-            case MediaRecorder.VideoEncoder.DEFAULT:
-                break;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a mime-type string for the audio codec type returned by {@link #getAudioCodec()}.
-     *
-     * @return A mime-type string or {@code null} if the codec type is
-     * {@link android.media.MediaRecorder.AudioEncoder#DEFAULT}, as this type is under-defined
-     * and cannot be resolved to a specific mime type without more information.
-     */
-    @Nullable
-    public String getAudioCodecMimeType() {
-        // Mime-type definitions taken from
-        // frameworks/av/media/libstagefright/foundation/MediaDefs.cpp
-        switch (getAudioCodec()) {
-            case AAC: // Should use aac-profile LC
-            case HE_AAC: // Should use aac-profile HE
-            case AAC_ELD: // Should use aac-profile ELD
-                return MediaFormat.MIMETYPE_AUDIO_AAC;
-            case AMR_NB:
-                return MediaFormat.MIMETYPE_AUDIO_AMR_NB;
-            case AMR_WB:
-                return MediaFormat.MIMETYPE_AUDIO_AMR_WB;
-            case OPUS:
-                return MediaFormat.MIMETYPE_AUDIO_OPUS;
-            case VORBIS:
-                return MediaFormat.MIMETYPE_AUDIO_VORBIS;
-            case MediaRecorder.AudioEncoder.DEFAULT:
-                break;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the required audio profile for the audio encoder given by {@link #getAudioCodec()}.
-     *
-     * <p>For example, this can be used to differentiate between AAC encoders
-     * {@link android.media.MediaRecorder.AudioEncoder#AAC},
-     * {@link android.media.MediaRecorder.AudioEncoder#AAC_ELD},
-     * and {@link android.media.MediaRecorder.AudioEncoder#HE_AAC}.
-     * Should be used with the {@link MediaCodecInfo.CodecProfileLevel#profile} field.
-     *
-     * @return The profile required by the audio codec. If no profile is required, returns
-     * {@link #CODEC_PROFILE_NONE}.
-     */
-    public int getRequiredAudioProfile() {
-        switch (getAudioCodec()) {
-            case AAC:
-                return MediaCodecInfo.CodecProfileLevel.AACObjectLC;
-            case AAC_ELD:
-                return MediaCodecInfo.CodecProfileLevel.AACObjectELD;
-            case HE_AAC:
-                return MediaCodecInfo.CodecProfileLevel.AACObjectHE;
-            default:
-                return CODEC_PROFILE_NONE;
-        }
-    }
-}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraFactory.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraFactory.java
index 814ea36..4fe95d9 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraFactory.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraFactory.java
@@ -24,6 +24,7 @@
 import androidx.camera.core.CameraSelector;
 import androidx.camera.core.CameraUnavailableException;
 import androidx.camera.core.InitializationException;
+import androidx.camera.core.concurrent.CameraCoordinator;
 
 import java.util.Set;
 
@@ -74,6 +75,14 @@
     Set<String> getAvailableCameraIds();
 
     /**
+     * Gets the {@link CameraCoordinator}.
+     *
+     * @return the instance of {@link CameraCoordinator}.
+     */
+    @Nullable
+    CameraCoordinator getCameraCoordinator();
+
+    /**
      * Gets the camera manager instance that is used to access the camera API.
      *
      * <p>Notes that actual type of this camera manager depends on the implementation. While it
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java
index 633c72c..1fb2f48 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInfoInternal.java
@@ -65,9 +65,9 @@
     @NonNull
     Quirks getCameraQuirks();
 
-    /** Returns the {@link CamcorderProfileProvider} associated with this camera. */
+    /** Returns the {@link EncoderProfilesProvider} associated with this camera. */
     @NonNull
-    CamcorderProfileProvider getCamcorderProfileProvider();
+    EncoderProfilesProvider getEncoderProfilesProvider();
 
     /** Returns the {@link Timebase} of frame output by this camera. */
     @NonNull
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/compat/EncoderProfilesProxyCompat.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/compat/EncoderProfilesProxyCompat.java
index cd50106..a214fe1 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/compat/EncoderProfilesProxyCompat.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/compat/EncoderProfilesProxyCompat.java
@@ -22,6 +22,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
+import androidx.camera.core.Logger;
 import androidx.camera.core.impl.EncoderProfilesProxy;
 
 /**
@@ -31,6 +32,8 @@
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 public final class EncoderProfilesProxyCompat {
 
+    private static final String TAG = "EncoderProfilesProxyCompat";
+
     /** Creates an EncoderProfilesProxy instance from {@link EncoderProfiles}. */
     @RequiresApi(31)
     @NonNull
@@ -50,13 +53,11 @@
     @NonNull
     public static EncoderProfilesProxy from(@NonNull CamcorderProfile camcorderProfile) {
         if (Build.VERSION.SDK_INT >= 31) {
-            throw new RuntimeException(
-                    "Should not use from(CamcorderProfile) on API " + Build.VERSION.SDK_INT
-                            + ". CamcorderProfile is deprecated on API 31, use "
-                            + "from(EncoderProfiles) instead.");
-        } else {
-            return EncoderProfilesProxyCompatBaseImpl.from(camcorderProfile);
+            Logger.w(TAG, "Should use from(EncoderProfiles) on API " + Build.VERSION.SDK_INT
+                    + "instead. CamcorderProfile is deprecated on API 31.");
         }
+
+        return EncoderProfilesProxyCompatBaseImpl.from(camcorderProfile);
     }
 
     // Class should not be instantiated.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
index f6b3836..924d3a4 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
@@ -58,7 +58,6 @@
 import androidx.camera.core.impl.UseCaseConfig;
 import androidx.camera.core.impl.UseCaseConfigFactory;
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
-import androidx.camera.core.processing.SurfaceProcessorWithExecutor;
 import androidx.camera.core.streamsharing.StreamSharing;
 import androidx.core.util.Preconditions;
 
@@ -545,18 +544,9 @@
         // Set effects on the UseCases. This also removes existing effects if necessary.
         for (UseCase useCase : useCases) {
             if (useCase instanceof Preview) {
-                Preview preview = ((Preview) useCase);
-                CameraEffect effect = effectsByTargets.get(CameraEffect.PREVIEW);
-                if (effect == null) {
-                    preview.setProcessor(null);
-                    continue;
-                }
-                preview.setProcessor(new SurfaceProcessorWithExecutor(
-                        requireNonNull(effect.getSurfaceProcessor()),
-                        effect.getExecutor()));
+                useCase.setEffect(effectsByTargets.get(CameraEffect.PREVIEW));
             } else if (useCase instanceof ImageCapture) {
-                ImageCapture imageCapture = ((ImageCapture) useCase);
-                imageCapture.setEffect(effectsByTargets.get(CameraEffect.IMAGE_CAPTURE));
+                useCase.setEffect(effectsByTargets.get(CameraEffect.IMAGE_CAPTURE));
             }
         }
     }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
index 9ce2398..e1271ec 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
@@ -39,7 +39,6 @@
 import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
 import androidx.camera.core.internal.CameraUseCaseAdapter
 import androidx.camera.core.internal.utils.SizeUtil
-import androidx.camera.core.processing.SurfaceProcessorInternal
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.CameraXUtil
 import androidx.camera.testing.fakes.FakeAppConfig
@@ -47,6 +46,7 @@
 import androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager
 import androidx.camera.testing.fakes.FakeCameraFactory
 import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import androidx.camera.testing.fakes.FakeSurfaceEffect
 import androidx.camera.testing.fakes.FakeSurfaceProcessorInternal
 import androidx.camera.testing.fakes.FakeUseCase
 import androidx.test.core.app.ApplicationProvider
@@ -75,7 +75,7 @@
 )
 class PreviewTest {
 
-    var cameraUseCaseAdapter: CameraUseCaseAdapter? = null
+    private var cameraUseCaseAdapter: CameraUseCaseAdapter? = null
 
     private lateinit var appSurface: Surface
     private lateinit var appSurfaceTexture: SurfaceTexture
@@ -84,6 +84,8 @@
     private lateinit var cameraXConfig: CameraXConfig
     private lateinit var context: Context
     private lateinit var previewToDetach: Preview
+    private lateinit var processor: FakeSurfaceProcessorInternal
+    private lateinit var effect: CameraEffect
 
     @Before
     @Throws(ExecutionException::class, InterruptedException::class)
@@ -109,6 +111,8 @@
         ).setCameraFactoryProvider(cameraFactoryProvider).build()
         context = ApplicationProvider.getApplicationContext<Context>()
         CameraXUtil.initialize(context, cameraXConfig).get()
+        processor = FakeSurfaceProcessorInternal(mainThreadExecutor())
+        effect = FakeSurfaceEffect(processor)
     }
 
     @After
@@ -123,6 +127,7 @@
         if (::previewToDetach.isInitialized) {
             previewToDetach.onUnbind()
         }
+        processor.release()
         CameraXUtil.shutdown().get()
     }
 
@@ -233,11 +238,10 @@
     @Test
     fun createSurfaceRequestWithProcessor_noCameraTransform() {
         // Arrange: attach Preview without a SurfaceProvider.
-        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor())
         var transformationInfo: TransformationInfo? = null
 
         // Act: create pipeline in Preview and provide Surface.
-        val preview = createPreview(processor)
+        val preview = createPreview(effect)
         preview.mCurrentSurfaceRequest!!.setTransformationInfoListener(mainThreadExecutor()) {
             transformationInfo = it
         }
@@ -265,31 +269,24 @@
 
     @Test
     fun backCameraWithProcessor_notMirrored() {
-        // Arrange.
-        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor())
         // Act: create pipeline
-        val preview = createPreview(processor, backCamera)
+        val preview = createPreview(effect, backCamera)
         // Assert
         assertThat(preview.cameraEdge.mirroring).isFalse()
     }
 
     @Test
     fun frontCameraWithProcessor_mirrored() {
-        // Arrange.
-        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor())
         // Act: create pipeline
-        val preview = createPreview(processor, frontCamera)
+        val preview = createPreview(effect, frontCamera)
         // Assert
         assertThat(preview.cameraEdge.mirroring).isTrue()
     }
 
     @Test
     fun setTargetRotationWithProcessor_rotationChangesOnSurfaceEdge() {
-        // Arrange.
-        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor())
-
         // Act: create pipeline
-        val preview = createPreview(processor)
+        val preview = createPreview(effect)
         // Act: update target rotation
         preview.targetRotation = Surface.ROTATION_0
         shadowOf(getMainLooper()).idle()
@@ -306,8 +303,7 @@
     @Test
     fun invalidateAppSurfaceRequestWithProcessing_cameraNotReset() {
         // Arrange: create Preview with processing.
-        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor(), false)
-        val surfaceRequest = createPreview(processor).mCurrentSurfaceRequest
+        val surfaceRequest = createPreview(effect).mCurrentSurfaceRequest
         // Act: invalidate.
         surfaceRequest!!.invalidate()
         shadowOf(getMainLooper()).idle()
@@ -318,8 +314,7 @@
     @Test
     fun invalidateNodeSurfaceRequest_cameraReset() {
         // Arrange: create Preview with processing.
-        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor(), false)
-        val preview = createPreview(processor)
+        val preview = createPreview(effect)
         // Act: invalidate.
         processor.surfaceRequest!!.invalidate()
         shadowOf(getMainLooper()).idle()
@@ -342,8 +337,7 @@
     @Test
     fun invalidateWhenDetached_deferrableSurfaceClosed() {
         // Arrange: create Preview with processing then detach.
-        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor(), false)
-        val preview = createPreview(processor)
+        val preview = createPreview(effect)
         val surfaceRequest = processor.surfaceRequest!!
         preview.unbindFromCamera(backCamera)
         // Act: invalidate.
@@ -358,7 +352,7 @@
     fun hasCameraTransform_rotationDegreesNotFlipped() {
         // Act: create preview with hasCameraTransform == true
         val preview = createPreview(
-            FakeSurfaceProcessorInternal(mainThreadExecutor()),
+            effect,
             frontCamera,
             targetRotation = Surface.ROTATION_90
         )
@@ -371,7 +365,7 @@
     fun noCameraTransform_rotationDegreesFlipped() {
         // Act: create preview with hasCameraTransform == false
         val preview = createPreview(
-            FakeSurfaceProcessorInternal(mainThreadExecutor()),
+            effect,
             frontCamera,
             hasCameraTransform = false,
             targetRotation = Surface.ROTATION_90
@@ -384,7 +378,7 @@
     fun setNoCameraTransform_propagatesToCameraEdge() {
         // Act: create preview with hasCameraTransform == false
         val preview = createPreview(
-            FakeSurfaceProcessorInternal(mainThreadExecutor()),
+            effect,
             hasCameraTransform = false,
             targetRotation = Surface.ROTATION_90
         )
@@ -397,7 +391,7 @@
     fun frontCameraWithoutCameraTransform_noMirroring() {
         // Act: create preview with hasCameraTransform == false
         val preview = createPreview(
-            FakeSurfaceProcessorInternal(mainThreadExecutor()),
+            effect,
             frontCamera,
             hasCameraTransform = false,
             targetRotation = Surface.ROTATION_90
@@ -408,23 +402,13 @@
 
     @Test
     fun cameraEdgeHasTransformByDefault() {
-        assertThat(
-            createPreview(
-                FakeSurfaceProcessorInternal(mainThreadExecutor())
-            ).cameraEdge.hasCameraTransform()
-        ).isTrue()
+        assertThat(createPreview(effect).cameraEdge.hasCameraTransform()).isTrue()
     }
 
     @Test
     fun bindAndUnbindPreview_surfacesPropagated() {
-        // Arrange.
-        val processor = FakeSurfaceProcessorInternal(
-            mainThreadExecutor(),
-            false
-        )
-
         // Act: create pipeline in Preview and provide Surface.
-        val preview = createPreview(processor)
+        val preview = createPreview(effect)
         val surfaceRequest = preview.mCurrentSurfaceRequest!!
         var appSurfaceReadyToRelease = false
         surfaceRequest.provideSurface(appSurface, mainThreadExecutor()) {
@@ -450,21 +434,13 @@
         assertThat(processor.isReleased).isTrue()
         assertThat(processor.isOutputSurfaceRequestedToClose[PREVIEW]).isTrue()
         assertThat(processor.isInputSurfaceReleased).isTrue()
-        assertThat(appSurfaceReadyToRelease).isFalse()
-
-        // Act: close SurfaceOutput
-        processor.surfaceOutputs[CameraEffect.PREVIEW]!!.close()
-        shadowOf(getMainLooper()).idle()
         assertThat(appSurfaceReadyToRelease).isTrue()
     }
 
     @Test
     fun invokedErrorListener_recreatePipeline() {
         // Arrange: create pipeline and get a reference of the SessionConfig.
-        val processor = FakeSurfaceProcessorInternal(
-            mainThreadExecutor()
-        )
-        val preview = createPreview(processor)
+        val preview = createPreview(effect)
         val originalSessionConfig = preview.sessionConfig
 
         // Act: invoke the error listener.
@@ -666,7 +642,7 @@
     }
 
     private fun createPreview(
-        surfaceProcessor: SurfaceProcessorInternal? = null,
+        effect: CameraEffect? = null,
         camera: FakeCamera = backCamera,
         hasCameraTransform: Boolean = true,
         targetRotation: Int = Surface.ROTATION_0
@@ -675,7 +651,7 @@
             .setTargetRotation(targetRotation)
             .build()
         previewToDetach.hasCameraTransform = hasCameraTransform
-        previewToDetach.processor = surfaceProcessor
+        previewToDetach.effect = effect
         previewToDetach.setSurfaceProvider(CameraXExecutors.directExecutor()) {}
         val previewConfig = PreviewConfig(
             cameraXConfig.getUseCaseConfigFactoryProvider(null)!!.newInstance(context).getConfig(
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/UseCaseGroupTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/UseCaseGroupTest.kt
index 035cbfa0..7d877d1 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/UseCaseGroupTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/UseCaseGroupTest.kt
@@ -22,7 +22,7 @@
 import androidx.camera.core.CameraEffect.VIDEO_CAPTURE
 import androidx.camera.core.UseCaseGroup.Builder.getHumanReadableTargets
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
-import androidx.camera.testing.fakes.FakePreviewEffect
+import androidx.camera.testing.fakes.FakeSurfaceEffect
 import androidx.camera.testing.fakes.FakeSurfaceProcessor
 import androidx.camera.testing.fakes.FakeUseCase
 import com.google.common.truth.Truth.assertThat
@@ -43,7 +43,7 @@
     @Test
     fun duplicateTargets_throwsException() {
         // Arrange.
-        val previewEffect = FakePreviewEffect(
+        val previewEffect = FakeSurfaceEffect(
             CameraXExecutors.mainThreadExecutor(),
             FakeSurfaceProcessor(CameraXExecutors.mainThreadExecutor())
         )
@@ -61,8 +61,8 @@
 
         // Assert.
         assertThat(message).isEqualTo(
-            "Effects androidx.camera.testing.fakes.FakePreviewEffect " +
-                "and androidx.camera.testing.fakes.FakePreviewEffect " +
+            "Effects androidx.camera.testing.fakes.FakeSurfaceEffect " +
+                "and androidx.camera.testing.fakes.FakeSurfaceEffect " +
                 "contain duplicate targets PREVIEW."
         )
     }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt
index 898c3b7..b8e92f5 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt
@@ -41,11 +41,10 @@
 import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
 import androidx.camera.core.internal.CameraUseCaseAdapter.CameraException
 import androidx.camera.core.processing.DefaultSurfaceProcessor
-import androidx.camera.core.processing.SurfaceProcessorWithExecutor
 import androidx.camera.core.streamsharing.StreamSharing
 import androidx.camera.testing.fakes.FakeCamera
 import androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager
-import androidx.camera.testing.fakes.FakePreviewEffect
+import androidx.camera.testing.fakes.FakeSurfaceEffect
 import androidx.camera.testing.fakes.FakeSurfaceProcessor
 import androidx.camera.testing.fakes.FakeSurfaceProcessorInternal
 import androidx.camera.testing.fakes.FakeUseCase
@@ -88,6 +87,7 @@
     private lateinit var fakeCameraDeviceSurfaceManager: FakeCameraDeviceSurfaceManager
     private lateinit var fakeCamera: FakeCamera
     private lateinit var useCaseConfigFactory: UseCaseConfigFactory
+    private lateinit var previewEffect: FakeSurfaceEffect
     private val fakeCameraSet = LinkedHashSet<CameraInternal>()
     private val imageEffect = GrayscaleImageEffect()
     private val preview = Preview.Builder().build()
@@ -104,7 +104,11 @@
         fakeCameraSet.add(fakeCamera)
         surfaceProcessor = FakeSurfaceProcessor(mainThreadExecutor())
         executor = Executors.newSingleThreadExecutor()
-        effects = listOf(FakePreviewEffect(executor, surfaceProcessor), imageEffect)
+        previewEffect = FakeSurfaceEffect(
+            executor,
+            surfaceProcessor
+        )
+        effects = listOf(previewEffect, imageEffect)
         adapter = CameraUseCaseAdapter(
             fakeCameraSet,
             fakeCameraDeviceSurfaceManager,
@@ -824,17 +828,14 @@
 
         // Act: update use cases with effects.
         CameraUseCaseAdapter.updateEffects(effects, useCases)
-        // Assert: preview has processor wrapped with the right executor.
-        val previewProcessor = preview.processor as SurfaceProcessorWithExecutor
-        assertThat(previewProcessor.processor).isEqualTo(surfaceProcessor)
-        assertThat(previewProcessor.executor).isEqualTo(executor)
-        // Assert: imageCapture has the effect set.
+        // Assert: UseCase have effects
+        assertThat(preview.effect).isEqualTo(previewEffect)
         assertThat(imageCapture.effect).isEqualTo(imageEffect)
 
         // Act: update again with no effects.
         CameraUseCaseAdapter.updateEffects(listOf(), useCases)
         // Assert: use cases no longer has effects.
-        assertThat(preview.processor).isNull()
+        assertThat(preview.effect).isNull()
         assertThat(imageCapture.effect).isNull()
     }
 
diff --git a/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt b/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
index 8cb0c37..0c38d7a 100644
--- a/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
+++ b/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
@@ -30,14 +30,13 @@
 import androidx.camera.core.concurrent.SingleCameraConfig
 import androidx.camera.core.impl.CameraFactory
 import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
-import androidx.camera.core.processing.SurfaceProcessorWithExecutor
 import androidx.camera.testing.fakes.FakeAppConfig
 import androidx.camera.testing.fakes.FakeCamera
 import androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager
 import androidx.camera.testing.fakes.FakeCameraFactory
 import androidx.camera.testing.fakes.FakeCameraInfoInternal
 import androidx.camera.testing.fakes.FakeLifecycleOwner
-import androidx.camera.testing.fakes.FakePreviewEffect
+import androidx.camera.testing.fakes.FakeSurfaceEffect
 import androidx.camera.testing.fakes.FakeSurfaceProcessor
 import androidx.camera.testing.fakes.FakeUseCaseConfigFactory
 import androidx.concurrent.futures.await
@@ -81,7 +80,10 @@
         // Arrange.
         ProcessCameraProvider.configureInstance(FakeAppConfig.create())
         val surfaceProcessor = FakeSurfaceProcessor(mainThreadExecutor())
-        val effect = FakePreviewEffect(mainThreadExecutor(), surfaceProcessor)
+        val effect = FakeSurfaceEffect(
+            mainThreadExecutor(),
+            surfaceProcessor
+        )
         val preview = Preview.Builder().setSessionOptionUnpacker { _, _ -> }.build()
         val useCaseGroup = UseCaseGroup.Builder().addUseCase(preview).addEffect(effect).build()
 
@@ -94,8 +96,7 @@
             )
 
             // Assert.
-            val useCaseProcessor = (preview.processor as SurfaceProcessorWithExecutor).processor
-            assertThat(useCaseProcessor).isEqualTo(surfaceProcessor)
+            assertThat(preview.effect).isEqualTo(effect)
         }
     }
 
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/CamcorderProfileUtil.java b/camera/camera-testing/src/main/java/androidx/camera/testing/CamcorderProfileUtil.java
deleted file mode 100644
index 923a59b..0000000
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/CamcorderProfileUtil.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.testing;
-
-import android.media.CamcorderProfile;
-import android.media.MediaRecorder;
-import android.util.Size;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.camera.core.impl.CamcorderProfileProxy;
-
-/**
- * Utility methods for testing {@link CamcorderProfile} related classes, including predefined
- * resolutions, attributes and {@link CamcorderProfileProxy}, which can be used directly on the
- * unit tests.
- */
-@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public final class CamcorderProfileUtil {
-
-    private CamcorderProfileUtil() {
-    }
-
-    /** Resolution for QCIF. */
-    public static final Size RESOLUTION_QCIF = new Size(176, 144);
-    /** Resolution for QVGA. */
-    public static final Size RESOLUTION_QVGA = new Size(320, 240);
-    /** Resolution for CIF. */
-    public static final Size RESOLUTION_CIF = new Size(352, 288);
-    /** Resolution for VGA. */
-    public static final Size RESOLUTION_VGA = new Size(640, 480);
-    /** Resolution for 480P. */
-    public static final Size RESOLUTION_480P = new Size(720, 480); /* 640, 704 or 720 x 480 */
-    /** Resolution for 720P. */
-    public static final Size RESOLUTION_720P = new Size(1280, 720);
-    /** Resolution for 1080P. */
-    public static final Size RESOLUTION_1080P = new Size(1920, 1080); /* 1920 x 1080 or 1088 */
-    /** Resolution for 2K. */
-    public static final Size RESOLUTION_2K = new Size(2048, 1080);
-    /** Resolution for QHD. */
-    public static final Size RESOLUTION_QHD = new Size(2560, 1440);
-    /** Resolution for 2160P. */
-    public static final Size RESOLUTION_2160P = new Size(3840, 2160);
-    /** Resolution for 4KDCI. */
-    public static final Size RESOLUTION_4KDCI = new Size(4096, 2160);
-
-    /** Default duration. */
-    public static final int DEFAULT_DURATION = 30;
-    /** Default output format. */
-    public static final int DEFAULT_OUTPUT_FORMAT = MediaRecorder.OutputFormat.MPEG_4;
-    /** Default video codec. */
-    public static final int DEFAULT_VIDEO_CODEC = MediaRecorder.VideoEncoder.H264;
-    /** Default video bitrate. */
-    public static final int DEFAULT_VIDEO_BITRATE = 8 * 1024 * 1024;
-    /** Default video frame rate. */
-    public static final int DEFAULT_VIDEO_FRAME_RATE = 30;
-    /** Default audio codec. */
-    public static final int DEFAULT_AUDIO_CODEC = MediaRecorder.AudioEncoder.AAC;
-    /** Default audio bitrate. */
-    public static final int DEFAULT_AUDIO_BITRATE = 192_000;
-    /** Default audio sample rate. */
-    public static final int DEFAULT_AUDIO_SAMPLE_RATE = 48_000;
-    /** Default channel count. */
-    public static final int DEFAULT_AUDIO_CHANNELS = 1;
-
-    public static final CamcorderProfileProxy PROFILE_QCIF = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_QCIF,
-            RESOLUTION_QCIF.getWidth(),
-            RESOLUTION_QCIF.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_QVGA = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_QVGA,
-            RESOLUTION_QVGA.getWidth(),
-            RESOLUTION_QVGA.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_CIF = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_CIF,
-            RESOLUTION_CIF.getWidth(),
-            RESOLUTION_CIF.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_VGA = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_VGA,
-            RESOLUTION_VGA.getWidth(),
-            RESOLUTION_VGA.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_480P = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_480P,
-            RESOLUTION_480P.getWidth(),
-            RESOLUTION_480P.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_720P = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_720P,
-            RESOLUTION_720P.getWidth(),
-            RESOLUTION_720P.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_1080P = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_1080P,
-            RESOLUTION_1080P.getWidth(),
-            RESOLUTION_1080P.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_2K = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_2K,
-            RESOLUTION_2K.getWidth(),
-            RESOLUTION_2K.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_QHD = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_QHD,
-            RESOLUTION_QHD.getWidth(),
-            RESOLUTION_QHD.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_2160P = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_2160P,
-            RESOLUTION_2160P.getWidth(),
-            RESOLUTION_2160P.getHeight()
-    );
-
-    public static final CamcorderProfileProxy PROFILE_4KDCI = createCamcorderProfileProxy(
-            CamcorderProfile.QUALITY_4KDCI,
-            RESOLUTION_4KDCI.getWidth(),
-            RESOLUTION_4KDCI.getHeight()
-    );
-
-    /** A utility method to create a CamcorderProfileProxy with some default values. */
-    @NonNull
-    public static CamcorderProfileProxy createCamcorderProfileProxy(
-            int quality,
-            int videoFrameWidth,
-            int videoFrameHeight
-    ) {
-        return CamcorderProfileProxy.create(
-                DEFAULT_DURATION,
-                quality,
-                DEFAULT_OUTPUT_FORMAT,
-                DEFAULT_VIDEO_CODEC,
-                DEFAULT_VIDEO_BITRATE,
-                DEFAULT_VIDEO_FRAME_RATE,
-                videoFrameWidth,
-                videoFrameHeight,
-                DEFAULT_AUDIO_CODEC,
-                DEFAULT_AUDIO_BITRATE,
-                DEFAULT_AUDIO_SAMPLE_RATE,
-                DEFAULT_AUDIO_CHANNELS
-        );
-    }
-
-    /**
-     * Copies a CamcorderProfileProxy and sets the quality to
-     * {@link CamcorderProfile#QUALITY_HIGH}.
-     */
-    @NonNull
-    public static CamcorderProfileProxy asHighQuality(@NonNull CamcorderProfileProxy profile) {
-        return asQuality(profile, CamcorderProfile.QUALITY_HIGH);
-    }
-
-    /**
-     * Copies a CamcorderProfileProxy and sets the quality to
-     * {@link CamcorderProfile#QUALITY_LOW}.
-     */
-    @NonNull
-    public static CamcorderProfileProxy asLowQuality(@NonNull CamcorderProfileProxy profile) {
-        return asQuality(profile, CamcorderProfile.QUALITY_LOW);
-    }
-
-    private static CamcorderProfileProxy asQuality(@NonNull CamcorderProfileProxy profile,
-            int quality) {
-        return CamcorderProfileProxy.create(
-                profile.getDuration(),
-                quality,
-                profile.getFileFormat(),
-                profile.getVideoCodec(),
-                profile.getVideoBitRate(),
-                profile.getVideoFrameRate(),
-                profile.getVideoFrameWidth(),
-                profile.getVideoFrameHeight(),
-                profile.getAudioCodec(),
-                profile.getAudioBitRate(),
-                profile.getAudioSampleRate(),
-                profile.getAudioChannels()
-        );
-    }
-}
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamcorderProfileProvider.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamcorderProfileProvider.java
deleted file mode 100644
index f59107f..0000000
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamcorderProfileProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.testing.fakes;
-
-import android.media.CameraProfile;
-import android.util.SparseArray;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.camera.core.impl.CamcorderProfileProvider;
-import androidx.camera.core.impl.CamcorderProfileProxy;
-
-/**
- * A fake implementation of the {@link CamcorderProfileProvider} and used for test.
- */
-@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public class FakeCamcorderProfileProvider implements CamcorderProfileProvider {
-
-    private final SparseArray<CamcorderProfileProxy> mQualityToProfileMap;
-
-    FakeCamcorderProfileProvider(@NonNull SparseArray<CamcorderProfileProxy> qualityToProfileMap) {
-        mQualityToProfileMap = qualityToProfileMap;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    @Nullable
-    public CamcorderProfileProxy get(int quality) {
-        return mQualityToProfileMap.get(quality);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean hasProfile(int quality) {
-        return mQualityToProfileMap.get(quality) != null;
-    }
-
-    /**
-     * The builder to create a FakeCamcorderProfileProvider instance.
-     */
-    @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-    public static class Builder {
-        private final SparseArray<CamcorderProfileProxy> mQualityToProfileMap = new SparseArray<>();
-
-        /**
-         * Sets the camera id and corresponding profiles.
-         *
-         * <p>In normal case, the {@link CameraProfile#QUALITY_HIGH} and
-         * {@link CameraProfile#QUALITY_LOW} should be added in order to follow the contract of
-         * CamcorderProfile.
-         */
-        @NonNull
-        public Builder addProfile(@NonNull CamcorderProfileProxy ...camcorderProfiles) {
-            for (CamcorderProfileProxy camcorderProfile : camcorderProfiles) {
-                mQualityToProfileMap.put(camcorderProfile.getQuality(), camcorderProfile);
-            }
-            return this;
-        }
-
-        /** Builds the FakeCamcorderProfileProvider instance. */
-        @NonNull
-        public FakeCamcorderProfileProvider build() {
-            return new FakeCamcorderProfileProvider(mQualityToProfileMap.clone());
-        }
-    }
-}
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
index 08a26e7..ea0e9f8 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraFactory.java
@@ -23,6 +23,7 @@
 import androidx.annotation.RestrictTo.Scope;
 import androidx.camera.core.CameraSelector;
 import androidx.camera.core.Logger;
+import androidx.camera.core.concurrent.CameraCoordinator;
 import androidx.camera.core.impl.CameraFactory;
 import androidx.camera.core.impl.CameraInternal;
 import androidx.core.util.Pair;
@@ -58,6 +59,9 @@
     @Nullable
     private Object mCameraManager = null;
 
+    @Nullable
+    private CameraCoordinator mCameraCoordinator = null;
+
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     final Map<String, Pair<Integer, Callable<CameraInternal>>> mCameraMap = new HashMap<>();
 
@@ -170,6 +174,16 @@
         return filteredCameraIds;
     }
 
+    @Nullable
+    @Override
+    public CameraCoordinator getCameraCoordinator() {
+        return mCameraCoordinator;
+    }
+
+    public void setCameraCoordinator(@Nullable CameraCoordinator cameraCoordinator) {
+        mCameraCoordinator = cameraCoordinator;
+    }
+
     public void setCameraManager(@Nullable Object cameraManager) {
         mCameraManager = cameraManager;
     }
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
index d15ce7a..77cfb2b 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
@@ -30,9 +30,9 @@
 import androidx.camera.core.FocusMeteringAction;
 import androidx.camera.core.TorchState;
 import androidx.camera.core.ZoomState;
-import androidx.camera.core.impl.CamcorderProfileProvider;
 import androidx.camera.core.impl.CameraCaptureCallback;
 import androidx.camera.core.impl.CameraInfoInternal;
+import androidx.camera.core.impl.EncoderProfilesProvider;
 import androidx.camera.core.impl.ImageOutputConfig.RotationValue;
 import androidx.camera.core.impl.Quirk;
 import androidx.camera.core.impl.Quirks;
@@ -70,7 +70,7 @@
     // Leave uninitialized to support camera-core:1.0.0 dependencies.
     // Can be initialized during class init once there are no more pinned dependencies on
     // camera-core:1.0.0
-    private CamcorderProfileProvider mCamcorderProfileProvider;
+    private EncoderProfilesProvider mEncoderProfilesProvider;
 
     private boolean mIsPrivateReprocessingSupported = false;
     private float mIntrinsicZoomRatio = 1.0F;
@@ -173,9 +173,9 @@
 
     @NonNull
     @Override
-    public CamcorderProfileProvider getCamcorderProfileProvider() {
-        return mCamcorderProfileProvider == null ? CamcorderProfileProvider.EMPTY :
-                mCamcorderProfileProvider;
+    public EncoderProfilesProvider getEncoderProfilesProvider() {
+        return mEncoderProfilesProvider == null ? EncoderProfilesProvider.EMPTY :
+                mEncoderProfilesProvider;
     }
 
     @NonNull
@@ -242,10 +242,10 @@
         mImplementationType = implementationType;
     }
 
-    /** Set the CamcorderProfileProvider for testing */
-    public void setCamcorderProfileProvider(
-            @NonNull CamcorderProfileProvider camcorderProfileProvider) {
-        mCamcorderProfileProvider = Preconditions.checkNotNull(camcorderProfileProvider);
+    /** Set the EncoderProfilesProvider for testing */
+    public void setEncoderProfilesProvider(
+            @NonNull EncoderProfilesProvider encoderProfilesProvider) {
+        mEncoderProfilesProvider = Preconditions.checkNotNull(encoderProfilesProvider);
     }
 
     /** Set the timebase for testing */
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakePreviewEffect.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakePreviewEffect.java
deleted file mode 100644
index e1a6ea9..0000000
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakePreviewEffect.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2022 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 androidx.camera.testing.fakes;
-
-import android.os.Build;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.camera.core.CameraEffect;
-import androidx.camera.core.SurfaceProcessor;
-
-import java.util.concurrent.Executor;
-
-/**
- * A fake {@link CameraEffect} with {@link SurfaceProcessor}.
- */
-@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
-public class FakePreviewEffect extends CameraEffect {
-    public FakePreviewEffect(
-            @NonNull Executor processorExecutor,
-            @NonNull SurfaceProcessor surfaceProcessor) {
-        super(PREVIEW, processorExecutor, surfaceProcessor);
-    }
-}
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceEffect.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceEffect.java
new file mode 100644
index 0000000..b792c7a
--- /dev/null
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceEffect.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 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 androidx.camera.testing.fakes;
+
+import static androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor;
+
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.CameraEffect;
+import androidx.camera.core.SurfaceProcessor;
+import androidx.camera.core.processing.SurfaceProcessorInternal;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A fake {@link CameraEffect} with {@link SurfaceProcessor}.
+ */
+@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+public class FakeSurfaceEffect extends CameraEffect {
+
+    private SurfaceProcessorInternal mSurfaceProcessorInternal;
+
+    public FakeSurfaceEffect(
+            @NonNull Executor processorExecutor,
+            @NonNull SurfaceProcessor surfaceProcessor) {
+        super(PREVIEW, processorExecutor, surfaceProcessor);
+    }
+
+    /**
+     * Create a fake {@link CameraEffect} the {@link #createSurfaceProcessorInternal} value
+     * overridden.
+     *
+     * <p> This is helpful when we want to make sure the {@link SurfaceProcessorInternal} is
+     * released properly.
+     */
+    public FakeSurfaceEffect(@NonNull SurfaceProcessorInternal surfaceProcessorInternal) {
+        super(PREVIEW, mainThreadExecutor(), surfaceProcessorInternal);
+        mSurfaceProcessorInternal = surfaceProcessorInternal;
+    }
+
+    @NonNull
+    @Override
+    public SurfaceProcessorInternal createSurfaceProcessorInternal() {
+        if (mSurfaceProcessorInternal != null) {
+            return mSurfaceProcessorInternal;
+        } else {
+            return super.createSurfaceProcessorInternal();
+        }
+    }
+}
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioChecker.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioChecker.kt
index dbd3371..4a6f310 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioChecker.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioChecker.kt
@@ -24,7 +24,7 @@
 import androidx.camera.testing.CameraUtil
 import androidx.camera.video.internal.AudioSource
 import androidx.camera.video.internal.FakeBufferProvider
-import androidx.camera.video.internal.config.AudioSourceSettingsCamcorderProfileResolver
+import androidx.camera.video.internal.config.AudioSourceSettingsAudioProfileResolver
 import androidx.camera.video.internal.encoder.FakeInputBuffer
 import androidx.concurrent.futures.await
 import kotlinx.coroutines.CompletableDeferred
@@ -56,16 +56,16 @@
             cameraSelector: CameraSelector,
             qualitySelector: QualitySelector
         ) = runBlocking {
-            // Get audio source settings from CamcorderProfile
+            // Get audio source settings from EncoderProfiles
             val cameraInfo =
                 CameraUtil.createCameraUseCaseAdapter(context, cameraSelector).cameraInfo
             val videoCapabilities = VideoCapabilities.from(cameraInfo)
             val quality = qualitySelector.getPrioritizedQualities(cameraInfo).first()
             // Get a config using the default audio spec.
             val audioSourceSettings =
-                AudioSourceSettingsCamcorderProfileResolver(
+                AudioSourceSettingsAudioProfileResolver(
                     AudioSpec.builder().build(),
-                    videoCapabilities.getProfile(quality)!!
+                    videoCapabilities.getProfiles(quality)!!.defaultAudioProfile!!
                 ).get()
             val audioSource = AudioSource(audioSourceSettings, CameraXExecutors.ioExecutor(), null)
             try {
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/DeviceCompatibilityTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/DeviceCompatibilityTest.kt
index 7892f10..1261cd5 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/DeviceCompatibilityTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/DeviceCompatibilityTest.kt
@@ -25,10 +25,11 @@
 import androidx.camera.core.CameraSelector.DEFAULT_BACK_CAMERA
 import androidx.camera.core.CameraSelector.DEFAULT_FRONT_CAMERA
 import androidx.camera.core.CameraXConfig
-import androidx.camera.core.impl.CamcorderProfileProxy
+import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy
 import androidx.camera.testing.CameraPipeConfigTestRule
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.CameraXUtil
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy
 import androidx.camera.video.internal.compat.quirk.DeviceQuirks
 import androidx.camera.video.internal.compat.quirk.MediaCodecInfoReportIncorrectInfoQuirk
 import androidx.test.core.app.ApplicationProvider
@@ -86,11 +87,11 @@
     }
 
     @Test
-    fun mediaCodecInfoShouldSupportCamcorderProfileSizes() {
+    fun mediaCodecInfoShouldSupportEncoderProfilesSizes() {
         assumeTrue(DeviceQuirks.get(MediaCodecInfoReportIncorrectInfoQuirk::class.java) == null)
 
         // Arrange: Collect all supported profiles from default back/front camera.
-        val supportedProfiles = mutableListOf<CamcorderProfileProxy>()
+        val supportedProfiles = mutableListOf<VideoValidatedEncoderProfilesProxy>()
         supportedProfiles.addAll(getSupportedProfiles(DEFAULT_BACK_CAMERA))
         supportedProfiles.addAll(getSupportedProfiles(DEFAULT_FRONT_CAMERA))
         assumeTrue(supportedProfiles.isNotEmpty())
@@ -99,7 +100,11 @@
             // Arrange: Find the codec and its video capabilities.
             // If mime is null, skip the test instead of failing it since this isn't the purpose
             // of the test.
-            val mime = profile.videoCodecMimeType ?: return@forEach
+            val videoProfile = profile.defaultVideoProfile
+            val mime = videoProfile.mediaType
+            if (mime == VideoProfileProxy.MEDIA_TYPE_NONE) {
+                return@forEach
+            }
             val capabilities = MediaCodec.createEncoderByType(mime).let { codec ->
                 try {
                     codec.codecInfo.getCapabilitiesForType(mime).videoCapabilities
@@ -109,7 +114,7 @@
             }
 
             // Act.
-            val (width, height) = profile.videoFrameWidth to profile.videoFrameHeight
+            val (width, height) = videoProfile.width to videoProfile.height
             val supportedWidths = capabilities.supportedWidths
             val supportedHeights = capabilities.supportedHeights
             val supportedWidthsForHeight = capabilities.getWidthsForHeightQuietly(height)
@@ -128,14 +133,16 @@
         }
     }
 
-    private fun getSupportedProfiles(cameraSelector: CameraSelector): List<CamcorderProfileProxy> {
+    private fun getSupportedProfiles(
+        cameraSelector: CameraSelector
+    ): List<VideoValidatedEncoderProfilesProxy> {
         if (!CameraUtil.hasCameraWithLensFacing(cameraSelector.lensFacing!!)) {
             return emptyList()
         }
         val cameraInfo = CameraUtil.createCameraUseCaseAdapter(context, cameraSelector).cameraInfo
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
         return videoCapabilities.supportedQualities
-            .mapNotNull { videoCapabilities.getProfile(it) }
+            .mapNotNull { videoCapabilities.getProfiles(it) }
     }
 
     private fun android.util.Range<Int>.toClosed() = Range.closed(lower, upper)
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/SupportedQualitiesVerificationTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/SupportedQualitiesVerificationTest.kt
index 66b2c8e..be254c5 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/SupportedQualitiesVerificationTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/SupportedQualitiesVerificationTest.kt
@@ -37,6 +37,7 @@
 import androidx.camera.camera2.Camera2Config
 import androidx.camera.camera2.pipe.integration.CameraPipeConfig
 import androidx.camera.core.Camera
+import androidx.camera.core.CameraEffect
 import androidx.camera.core.CameraInfo
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.CameraXConfig
@@ -47,6 +48,7 @@
 import androidx.camera.testing.CameraPipeConfigTestRule
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.fakes.FakeLifecycleOwner
+import androidx.camera.testing.fakes.FakeSurfaceEffect
 import androidx.core.util.Consumer
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.LargeTest
@@ -187,14 +189,14 @@
     fun qualityOptionCanRecordVideo_enableSurfaceProcessor() {
         assumeSuccessfulSurfaceProcessing()
 
-        testQualityOptionRecordVideo(surfaceProcessor = createSurfaceProcessor())
+        testQualityOptionRecordVideo(effect = createEffect())
     }
 
-    private fun testQualityOptionRecordVideo(surfaceProcessor: SurfaceProcessorInternal? = null) {
+    private fun testQualityOptionRecordVideo(effect: CameraEffect? = null) {
         // Arrange.
         val recorder = Recorder.Builder().setQualitySelector(QualitySelector.from(quality)).build()
         val videoCapture = VideoCapture.withOutput(recorder)
-        videoCapture.setProcessor(surfaceProcessor)
+        videoCapture.effect = effect
         val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
         val latchForRecordingStatus = CountDownLatch(5)
         val latchForRecordingFinalized = CountDownLatch(1)
@@ -239,8 +241,13 @@
         file.delete()
     }
 
-    private fun createSurfaceProcessor(): SurfaceProcessorInternal =
-        DefaultSurfaceProcessor.Factory.newInstance().apply { surfaceProcessorsToRelease.add(this) }
+    private fun createEffect(): CameraEffect {
+        val fakeSurfaceProcessor = DefaultSurfaceProcessor.Factory.newInstance()
+        surfaceProcessorsToRelease.add(fakeSurfaceProcessor)
+        return FakeSurfaceEffect(
+            fakeSurfaceProcessor
+        )
+    }
 
     /** Skips tests which will enable surface processing and encounter device specific issues. */
     private fun assumeSuccessfulSurfaceProcessing() {
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioEncoderConfigCamcorderProfileResolverTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioEncoderConfigAudioProfileResolverTest.kt
similarity index 70%
rename from camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioEncoderConfigCamcorderProfileResolverTest.kt
rename to camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioEncoderConfigAudioProfileResolverTest.kt
index df98596..68d64f6 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioEncoderConfigCamcorderProfileResolverTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioEncoderConfigAudioProfileResolverTest.kt
@@ -48,7 +48,7 @@
 @RunWith(Parameterized::class)
 @SmallTest
 @SdkSuppress(minSdkVersion = 21)
-class AudioEncoderConfigCamcorderProfileResolverTest(
+class AudioEncoderConfigAudioProfileResolverTest(
     private val implName: String,
     private val cameraConfig: CameraXConfig
 ) {
@@ -103,38 +103,49 @@
     @Test
     fun defaultAudioSpecAndAudioSourceProducesValidSettings() {
         val supportedProfiles = videoCapabilities.supportedQualities.map {
-            videoCapabilities.getProfile(it)!!
+            videoCapabilities.getProfiles(it)!!
         }
 
-        supportedProfiles.forEach {
+        for (encoderProfiles in supportedProfiles) {
+            val audioProfile = encoderProfiles.defaultAudioProfile ?: continue
+
             val sourceSettings =
-                AudioSourceSettingsCamcorderProfileResolver(defaultAudioSpec, it).get()
-            val config = AudioEncoderConfigCamcorderProfileResolver(
-                it.audioCodecMimeType!!,
-                it.requiredAudioProfile,
+                AudioSourceSettingsAudioProfileResolver(
+                    defaultAudioSpec,
+                    audioProfile
+                ).get()
+            val config = AudioEncoderConfigAudioProfileResolver(
+                audioProfile.mediaType,
+                audioProfile.profile,
                 timebase,
                 defaultAudioSpec,
                 sourceSettings,
-                it
+                audioProfile
             ).get()
 
-            assertThat(config.mimeType).isEqualTo(it.audioCodecMimeType)
-            assertThat(config.bitrate).isEqualTo(it.audioBitRate)
-            assertThat(config.sampleRate).isEqualTo(it.audioSampleRate)
-            assertThat(config.channelCount).isEqualTo(it.audioChannels)
+            assertThat(config.mimeType).isEqualTo(audioProfile.mediaType)
+            assertThat(config.bitrate).isEqualTo(audioProfile.bitrate)
+            assertThat(config.sampleRate).isEqualTo(audioProfile.sampleRate)
+            assertThat(config.channelCount).isEqualTo(audioProfile.channels)
         }
     }
 
     @Test
     fun increasedChannelCountIncreasesBitrate() {
+        val encoderProfiles = videoCapabilities.getProfiles(Quality.HIGHEST)!!
+        val profile = encoderProfiles.defaultAudioProfile
+        Assume.assumeTrue(profile != null)
+
         // Get default channel count
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
         val defaultSourceSettings =
-            AudioSourceSettingsCamcorderProfileResolver(defaultAudioSpec, profile).get()
+            AudioSourceSettingsAudioProfileResolver(
+                defaultAudioSpec,
+                profile!!
+            ).get()
         val defaultConfig =
-            AudioEncoderConfigCamcorderProfileResolver(
-                profile.audioCodecMimeType!!,
-                profile.requiredAudioProfile,
+            AudioEncoderConfigAudioProfileResolver(
+                profile.mediaType,
+                profile.profile,
                 timebase,
                 defaultAudioSpec,
                 defaultSourceSettings,
@@ -145,9 +156,9 @@
         val higherChannelCountSourceSettings =
             defaultSourceSettings.toBuilder().setChannelCount(defaultChannelCount * 2).build()
 
-        val higherChannelCountConfig = AudioEncoderConfigCamcorderProfileResolver(
-            profile.audioCodecMimeType!!,
-            profile.requiredAudioProfile,
+        val higherChannelCountConfig = AudioEncoderConfigAudioProfileResolver(
+            profile.mediaType,
+            profile.profile,
             timebase,
             defaultAudioSpec,
             higherChannelCountSourceSettings,
@@ -159,14 +170,20 @@
 
     @Test
     fun increasedSampleRateIncreasesBitrate() {
+        val encoderProfiles = videoCapabilities.getProfiles(Quality.HIGHEST)!!
+        val profile = encoderProfiles.defaultAudioProfile
+        Assume.assumeTrue(profile != null)
+
         // Get default sample rate
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
         val defaultSourceSettings =
-            AudioSourceSettingsCamcorderProfileResolver(defaultAudioSpec, profile).get()
+            AudioSourceSettingsAudioProfileResolver(
+                defaultAudioSpec,
+                profile!!
+            ).get()
         val defaultConfig =
-            AudioEncoderConfigCamcorderProfileResolver(
-                profile.audioCodecMimeType!!,
-                profile.requiredAudioProfile,
+            AudioEncoderConfigAudioProfileResolver(
+                profile.mediaType,
+                profile.profile,
                 timebase,
                 defaultAudioSpec,
                 defaultSourceSettings,
@@ -177,9 +194,9 @@
         val higherSampleRateSourceSettings =
             defaultSourceSettings.toBuilder().setChannelCount(defaultSampleRate * 2).build()
 
-        val higherSampleRateConfig = AudioEncoderConfigCamcorderProfileResolver(
-            profile.audioCodecMimeType!!,
-            profile.requiredAudioProfile,
+        val higherSampleRateConfig = AudioEncoderConfigAudioProfileResolver(
+            profile.mediaType,
+            profile.profile,
             timebase,
             defaultAudioSpec,
             higherSampleRateSourceSettings,
@@ -191,11 +208,17 @@
 
     @Test
     fun bitrateRangeInVideoSpecClampsBitrate() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
-        val defaultSourceSettings =
-            AudioSourceSettingsCamcorderProfileResolver(defaultAudioSpec, profile).get()
+        val encoderProfiles = videoCapabilities.getProfiles(Quality.HIGHEST)!!
+        val profile = encoderProfiles.defaultAudioProfile
+        Assume.assumeTrue(profile != null)
 
-        val defaultBitrate = profile.audioBitRate
+        val defaultSourceSettings =
+            AudioSourceSettingsAudioProfileResolver(
+                defaultAudioSpec,
+                profile!!
+            ).get()
+
+        val defaultBitrate = profile.bitrate
 
         // Create audio spec with limit 20% higher than default.
         val higherBitrate = (defaultBitrate * 1.2).toInt()
@@ -207,9 +230,9 @@
         val lowerAudioSpec = AudioSpec.builder().setBitrate(Range(0, lowerBitrate)).build()
 
         assertThat(
-            AudioEncoderConfigCamcorderProfileResolver(
-                profile.audioCodecMimeType!!,
-                profile.requiredAudioProfile,
+            AudioEncoderConfigAudioProfileResolver(
+                profile.mediaType,
+                profile.profile,
                 timebase,
                 higherAudioSpec,
                 defaultSourceSettings,
@@ -218,9 +241,9 @@
         ).isEqualTo(higherBitrate)
 
         assertThat(
-            AudioEncoderConfigCamcorderProfileResolver(
-                profile.audioCodecMimeType!!,
-                profile.requiredAudioProfile,
+            AudioEncoderConfigAudioProfileResolver(
+                profile.mediaType,
+                profile.profile,
                 timebase,
                 lowerAudioSpec,
                 defaultSourceSettings,
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSourceSettingsCamcorderProfileResolverTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSourceSettingsAudioProfileResolverTest.kt
similarity index 74%
rename from camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSourceSettingsCamcorderProfileResolverTest.kt
rename to camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSourceSettingsAudioProfileResolverTest.kt
index 5d67a7a..13e4086 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSourceSettingsCamcorderProfileResolverTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSourceSettingsAudioProfileResolverTest.kt
@@ -51,7 +51,7 @@
 @RunWith(Parameterized::class)
 @SmallTest
 @SdkSuppress(minSdkVersion = 21)
-class AudioSourceSettingsCamcorderProfileResolverTest(
+class AudioSourceSettingsAudioProfileResolverTest(
     private val implName: String,
     private val cameraConfig: CameraXConfig
 ) {
@@ -106,9 +106,17 @@
 
     @Test
     fun defaultAudioSpecResolvesToSupportedSettings() {
-        val resolvedSettings = videoCapabilities.supportedQualities.map {
-            val camcorderProfile = videoCapabilities.getProfile(it)
-            AudioSourceSettingsCamcorderProfileResolver(defaultAudioSpec, camcorderProfile!!).get()
+        val resolvedSettings = videoCapabilities.supportedQualities.mapNotNull {
+            val encoderProfiles = videoCapabilities.getProfiles(it)!!
+            val audioProfile = encoderProfiles.defaultAudioProfile
+            if (audioProfile == null) {
+                null
+            } else {
+                AudioSourceSettingsAudioProfileResolver(
+                    defaultAudioSpec,
+                    audioProfile
+                ).get()
+            }
         }
 
         resolvedSettings.forEach {
@@ -131,9 +139,17 @@
         )
 
         val resolvedSettings = videoCapabilities.supportedQualities.flatMap { quality ->
-            val camcorderProfile = videoCapabilities.getProfile(quality)
-            audioSpecs.map {
-                AudioSourceSettingsCamcorderProfileResolver(it, camcorderProfile!!).get()
+            val encoderProfiles = videoCapabilities.getProfiles(quality)!!
+            val audioProfile = encoderProfiles.defaultAudioProfile
+            if (audioProfile == null) {
+                emptyList()
+            } else {
+                audioSpecs.map {
+                    AudioSourceSettingsAudioProfileResolver(
+                        it,
+                        audioProfile
+                    ).get()
+                }
             }
         }
 
@@ -149,21 +165,27 @@
     }
 
     @Test
-    fun sampleRateCanOverrideCamcorderProfile_ifSupported() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)
+    fun sampleRateCanOverrideEncoderProfiles_ifSupported() {
+        val encoderProfiles = videoCapabilities.getProfiles(Quality.HIGHEST)!!
+        val audioProfile = encoderProfiles.defaultAudioProfile
+        Assume.assumeTrue(audioProfile != null)
+
         // Get a config using the default audio spec to retrieve the source format
         // Note: This relies on resolution of sample rate and source format being independent.
         // If a dependency between the two is introduced, this will stop working and will
         // need to be rewritten.
-        val autoCamcorderProfileConfig =
-            AudioSourceSettingsCamcorderProfileResolver(defaultAudioSpec, profile!!).get()
+        val autoEncoderProfileConfig =
+            AudioSourceSettingsAudioProfileResolver(
+                defaultAudioSpec,
+                audioProfile!!
+            ).get()
         // Try to find a sample rate that is supported, but not the
-        // sample rate advertised by CamcorderProfile
+        // sample rate advertised by EncoderProfiles
         val nonReportedSampleRate = AudioSource.COMMON_SAMPLE_RATES.firstOrNull {
-            it != profile.audioSampleRate && AudioSource.isSettingsSupported(
+            it != audioProfile.sampleRate && AudioSource.isSettingsSupported(
                 it,
-                profile.audioChannels,
-                autoCamcorderProfileConfig.audioFormat
+                audioProfile.channels,
+                autoEncoderProfileConfig.audioFormat
             )
         }
         Assume.assumeTrue(
@@ -176,20 +198,26 @@
             AudioSpec.builder().setSampleRate(Range(nonReportedSampleRate!!, nonReportedSampleRate))
                 .build()
         val resolvedSampleRate =
-            AudioSourceSettingsCamcorderProfileResolver(audioSpec, profile).get().sampleRate
+            AudioSourceSettingsAudioProfileResolver(
+                audioSpec,
+                audioProfile
+            ).get().sampleRate
 
-        assertThat(resolvedSampleRate).isNotEqualTo(profile.audioSampleRate)
+        assertThat(resolvedSampleRate).isNotEqualTo(audioProfile.sampleRate)
         assertThat(resolvedSampleRate).isEqualTo(nonReportedSampleRate)
     }
 
     @Test
     fun audioSpecDefaultProducesValidSourceEnum() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)
+        val encoderProfiles = videoCapabilities.getProfiles(Quality.HIGHEST)!!
+        val audioProfile = encoderProfiles.defaultAudioProfile
+        Assume.assumeTrue(audioProfile != null)
+
         val audioSpec = AudioSpec.builder().build()
         val resolvedAudioSourceEnum =
-            AudioSourceSettingsCamcorderProfileResolver(
+            AudioSourceSettingsAudioProfileResolver(
                 audioSpec,
-                profile!!
+                audioProfile!!
             ).get().audioSource
 
         assertThat(resolvedAudioSourceEnum).isAnyOf(
@@ -200,12 +228,15 @@
 
     @Test
     fun audioSpecDefaultProducesValidSourceFormat() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)
+        val encoderProfiles = videoCapabilities.getProfiles(Quality.HIGHEST)!!
+        val audioProfile = encoderProfiles.defaultAudioProfile
+        Assume.assumeTrue(audioProfile != null)
+
         val audioSpec = AudioSpec.builder().build()
         val resolvedAudioSourceFormat =
-            AudioSourceSettingsCamcorderProfileResolver(
+            AudioSourceSettingsAudioProfileResolver(
                 audioSpec,
-                profile!!
+                audioProfile!!
             ).get().audioFormat
 
         assertThat(resolvedAudioSourceFormat).isNotEqualTo(AudioFormat.ENCODING_INVALID)
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigDefaultResolverTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigDefaultResolverTest.kt
index 066adfd..afdaa23 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigDefaultResolverTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigDefaultResolverTest.kt
@@ -18,7 +18,7 @@
 
 import android.util.Range
 import androidx.camera.core.impl.Timebase
-import androidx.camera.testing.CamcorderProfileUtil
+import androidx.camera.testing.EncoderProfilesUtil
 import androidx.camera.video.VideoSpec
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SdkSuppress
@@ -44,9 +44,9 @@
 
     @Test
     fun defaultVideoSpecProducesValidSettings_forDifferentSurfaceSizes() {
-        val surfaceSizeCif = CamcorderProfileUtil.RESOLUTION_CIF
-        val surfaceSize720p = CamcorderProfileUtil.RESOLUTION_720P
-        val surfaceSize1080p = CamcorderProfileUtil.RESOLUTION_1080P
+        val surfaceSizeCif = EncoderProfilesUtil.RESOLUTION_CIF
+        val surfaceSize720p = EncoderProfilesUtil.RESOLUTION_720P
+        val surfaceSize1080p = EncoderProfilesUtil.RESOLUTION_1080P
 
         val expectedFrameRateRange = Range(FRAME_RATE_30, FRAME_RATE_30)
 
@@ -96,7 +96,7 @@
 
     @Test
     fun bitrateRangeInVideoSpecClampsBitrate() {
-        val surfaceSize720p = CamcorderProfileUtil.RESOLUTION_720P
+        val surfaceSize720p = EncoderProfilesUtil.RESOLUTION_720P
 
         // Get default bit rate for this size
         val defaultConfig =
@@ -144,7 +144,7 @@
         // Give a VideoSpec with a frame rate higher than 30
         val videoSpec =
             VideoSpec.builder().setFrameRate(Range(FRAME_RATE_60, FRAME_RATE_60)).build()
-        val size = CamcorderProfileUtil.RESOLUTION_1080P
+        val size = EncoderProfilesUtil.RESOLUTION_1080P
 
         assertThat(
             VideoEncoderConfigDefaultResolver(
@@ -164,7 +164,7 @@
         // Give a VideoSpec with a frame rate higher than 30
         val videoSpec =
             VideoSpec.builder().setFrameRate(Range(FRAME_RATE_60, FRAME_RATE_60)).build()
-        val size = CamcorderProfileUtil.RESOLUTION_1080P
+        val size = EncoderProfilesUtil.RESOLUTION_1080P
 
         val expectedFrameRateRange = Range(FRAME_RATE_30, FRAME_RATE_30)
 
@@ -187,7 +187,7 @@
         // Give a VideoSpec with a frame rate higher than 30
         val videoSpec =
             VideoSpec.builder().setFrameRate(Range(FRAME_RATE_30, FRAME_RATE_45)).build()
-        val size = CamcorderProfileUtil.RESOLUTION_1080P
+        val size = EncoderProfilesUtil.RESOLUTION_1080P
 
         val expectedFrameRateRange = Range(FRAME_RATE_30, FRAME_RATE_60)
 
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigCamcorderProfileResolverTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigVideoProfileResolverTest.kt
similarity index 71%
rename from camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigCamcorderProfileResolverTest.kt
rename to camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigVideoProfileResolverTest.kt
index 1a555f6..1719d00 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigCamcorderProfileResolverTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/VideoEncoderConfigVideoProfileResolverTest.kt
@@ -49,7 +49,7 @@
 @RunWith(Parameterized::class)
 @SmallTest
 @SdkSuppress(minSdkVersion = 21)
-class VideoEncoderConfigCamcorderProfileResolverTest(
+class VideoEncoderConfigVideoProfileResolverTest(
     private val implName: String,
     private val cameraConfig: CameraXConfig
 ) {
@@ -103,33 +103,34 @@
     @Test
     fun defaultVideoSpecProducesValidSettings_forSurfaceSizeEquivalentToQuality() {
         val supportedProfiles = videoCapabilities.supportedQualities.map {
-            videoCapabilities.getProfile(it)!!
+            videoCapabilities.getProfiles(it)!!
         }
 
         supportedProfiles.forEach {
-            val config = VideoEncoderConfigCamcorderProfileResolver(
-                it.videoCodecMimeType!!,
+            val videoProfile = it.defaultVideoProfile
+            val config = VideoEncoderConfigVideoProfileResolver(
+                videoProfile.mediaType,
                 timebase,
                 defaultVideoSpec,
-                Size(it.videoFrameWidth, it.videoFrameHeight),
-                it,
+                Size(videoProfile.width, videoProfile.height),
+                videoProfile,
                 /*expectedFrameRateRange=*/null
             ).get()
 
-            assertThat(config.mimeType).isEqualTo(it.videoCodecMimeType)
-            assertThat(config.bitrate).isEqualTo(it.videoBitRate)
-            assertThat(config.resolution).isEqualTo(Size(it.videoFrameWidth, it.videoFrameHeight))
-            assertThat(config.frameRate).isEqualTo(it.videoFrameRate)
+            assertThat(config.mimeType).isEqualTo(videoProfile.mediaType)
+            assertThat(config.bitrate).isEqualTo(videoProfile.bitrate)
+            assertThat(config.resolution).isEqualTo(Size(videoProfile.width, videoProfile.height))
+            assertThat(config.frameRate).isEqualTo(videoProfile.frameRate)
         }
     }
 
     @Test
     fun bitrateIncreasesOrDecreasesWithIncreaseOrDecreaseInSurfaceSize() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
-        val surfaceSize = Size(profile.videoFrameWidth, profile.videoFrameHeight)
+        val profile = videoCapabilities.getProfiles(Quality.HIGHEST)!!.defaultVideoProfile
+        val surfaceSize = Size(profile.width, profile.height)
 
-        val defaultBitrate = VideoEncoderConfigCamcorderProfileResolver(
-            profile.videoCodecMimeType!!,
+        val defaultBitrate = VideoEncoderConfigVideoProfileResolver(
+            profile.mediaType,
             timebase,
             defaultVideoSpec,
             surfaceSize,
@@ -141,8 +142,8 @@
         val decreasedSurfaceSize = Size(surfaceSize.width - 100, surfaceSize.height - 100)
 
         assertThat(
-            VideoEncoderConfigCamcorderProfileResolver(
-                profile.videoCodecMimeType!!,
+            VideoEncoderConfigVideoProfileResolver(
+                profile.mediaType,
                 timebase,
                 defaultVideoSpec,
                 increasedSurfaceSize,
@@ -152,8 +153,8 @@
         ).isGreaterThan(defaultBitrate)
 
         assertThat(
-            VideoEncoderConfigCamcorderProfileResolver(
-                profile.videoCodecMimeType!!,
+            VideoEncoderConfigVideoProfileResolver(
+                profile.mediaType,
                 timebase,
                 defaultVideoSpec,
                 decreasedSurfaceSize,
@@ -165,11 +166,11 @@
 
     @Test
     fun bitrateRangeInVideoSpecClampsBitrate() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
-        val surfaceSize = Size(profile.videoFrameWidth, profile.videoFrameHeight)
+        val profile = videoCapabilities.getProfiles(Quality.HIGHEST)!!.defaultVideoProfile
+        val surfaceSize = Size(profile.width, profile.height)
 
-        val defaultBitrate = VideoEncoderConfigCamcorderProfileResolver(
-            profile.videoCodecMimeType!!,
+        val defaultBitrate = VideoEncoderConfigVideoProfileResolver(
+            profile.mediaType,
             timebase,
             defaultVideoSpec,
             surfaceSize,
@@ -187,8 +188,8 @@
         val lowerVideoSpec = VideoSpec.builder().setBitrate(Range(0, lowerBitrate)).build()
 
         assertThat(
-            VideoEncoderConfigCamcorderProfileResolver(
-                profile.videoCodecMimeType!!,
+            VideoEncoderConfigVideoProfileResolver(
+                profile.mediaType,
                 timebase,
                 higherVideoSpec,
                 surfaceSize,
@@ -198,8 +199,8 @@
         ).isEqualTo(higherBitrate)
 
         assertThat(
-            VideoEncoderConfigCamcorderProfileResolver(
-                profile.videoCodecMimeType!!,
+            VideoEncoderConfigVideoProfileResolver(
+                profile.mediaType,
                 timebase,
                 lowerVideoSpec,
                 surfaceSize,
@@ -211,15 +212,15 @@
 
     @Test
     fun resolvedFrameRateIsClampedToOperatingRate() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
-        val surfaceSize = Size(profile.videoFrameWidth, profile.videoFrameHeight)
+        val profile = videoCapabilities.getProfiles(Quality.HIGHEST)!!.defaultVideoProfile
+        val surfaceSize = Size(profile.width, profile.height)
 
         // Construct operating ranges that are both lower and higher than the profile FPS
-        val lowerOperatingRange = Range(profile.videoFrameRate / 4, profile.videoFrameRate / 2)
-        val higherOperatingRange = Range(profile.videoFrameRate * 2, profile.videoFrameRate * 4)
+        val lowerOperatingRange = Range(profile.frameRate / 4, profile.frameRate / 2)
+        val higherOperatingRange = Range(profile.frameRate * 2, profile.frameRate * 4)
 
-        val clampedDownFrameRate = VideoEncoderConfigCamcorderProfileResolver(
-            profile.videoCodecMimeType!!,
+        val clampedDownFrameRate = VideoEncoderConfigVideoProfileResolver(
+            profile.mediaType,
             timebase,
             defaultVideoSpec,
             surfaceSize,
@@ -227,8 +228,8 @@
             lowerOperatingRange
         ).get().frameRate
 
-        val clampedUpFrameRate = VideoEncoderConfigCamcorderProfileResolver(
-            profile.videoCodecMimeType!!,
+        val clampedUpFrameRate = VideoEncoderConfigVideoProfileResolver(
+            profile.mediaType,
             timebase,
             defaultVideoSpec,
             surfaceSize,
@@ -242,14 +243,14 @@
 
     @Test
     fun resolvedFrameRateInsideOperatingRangeIsUnchanged() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
-        val surfaceSize = Size(profile.videoFrameWidth, profile.videoFrameHeight)
+        val profile = videoCapabilities.getProfiles(Quality.HIGHEST)!!.defaultVideoProfile
+        val surfaceSize = Size(profile.width, profile.height)
 
         // Construct a range that includes the profile FPS
-        val operatingRange = Range(profile.videoFrameRate / 2, profile.videoFrameRate * 2)
+        val operatingRange = Range(profile.frameRate / 2, profile.frameRate * 2)
 
-        val resolvedFrameRate = VideoEncoderConfigCamcorderProfileResolver(
-            profile.videoCodecMimeType!!,
+        val resolvedFrameRate = VideoEncoderConfigVideoProfileResolver(
+            profile.mediaType,
             timebase,
             defaultVideoSpec,
             surfaceSize,
@@ -257,20 +258,20 @@
             operatingRange
         ).get().frameRate
 
-        assertThat(resolvedFrameRate).isEqualTo(profile.videoFrameRate)
+        assertThat(resolvedFrameRate).isEqualTo(profile.frameRate)
     }
 
     @Test
     fun bitrateScalesWithFrameRateOperatingRange() {
-        val profile = videoCapabilities.getProfile(Quality.HIGHEST)!!
-        val surfaceSize = Size(profile.videoFrameWidth, profile.videoFrameHeight)
+        val profile = videoCapabilities.getProfiles(Quality.HIGHEST)!!.defaultVideoProfile
+        val surfaceSize = Size(profile.width, profile.height)
 
         // Construct a range which is constant and half the profile FPS
-        val operatingFrameRate = profile.videoFrameRate / 2
+        val operatingFrameRate = profile.frameRate / 2
         val operatingRange = Range(operatingFrameRate, operatingFrameRate)
 
-        val resolvedBitrate = VideoEncoderConfigCamcorderProfileResolver(
-            profile.videoCodecMimeType!!,
+        val resolvedBitrate = VideoEncoderConfigVideoProfileResolver(
+            profile.mediaType,
             timebase,
             defaultVideoSpec,
             surfaceSize,
@@ -279,8 +280,7 @@
         ).get().bitrate
 
         assertThat(resolvedBitrate).isEqualTo(
-            (profile.videoBitRate *
-                (operatingFrameRate.toDouble() / profile.videoFrameRate)).toInt()
+            (profile.bitrate * (operatingFrameRate.toDouble() / profile.frameRate)).toInt()
         )
     }
 }
\ No newline at end of file
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/workaround/EncoderFinderTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/workaround/EncoderFinderTest.kt
index 72350dc..4af3517 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/workaround/EncoderFinderTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/workaround/EncoderFinderTest.kt
@@ -37,7 +37,7 @@
 import androidx.camera.video.VideoSpec
 import androidx.camera.video.internal.compat.quirk.DeviceQuirks
 import androidx.camera.video.internal.compat.quirk.MediaCodecInfoReportIncorrectInfoQuirk
-import androidx.camera.video.internal.config.VideoEncoderConfigCamcorderProfileResolver
+import androidx.camera.video.internal.config.VideoEncoderConfigVideoProfileResolver
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
@@ -144,7 +144,7 @@
 
     @LabTestRule.LabTestOnly
     @Test
-    fun findEncoderForFormat_CamcorderProfile() {
+    fun findEncoderForFormat_EncoderProfiles() {
         // Arrange.
         val cameraInfo = camera.cameraInfo as CameraInfoInternal
         val resolution = QualitySelector.getResolution(cameraInfo, quality)
@@ -153,18 +153,18 @@
             resolution != null
         )
 
-        val camcorderProfile = VideoCapabilities.from(cameraInfo).getProfile(quality)
-        val camcorderProfileVideoMime = camcorderProfile!!.videoCodecMimeType!!
+        val encoderProfiles = VideoCapabilities.from(cameraInfo).getProfiles(quality)
+        val videoProfile = encoderProfiles!!.defaultVideoProfile
 
         val videoSpec =
             VideoSpec.builder().setQualitySelector(QualitySelector.from(quality)).build()
 
-        val mediaFormat = VideoEncoderConfigCamcorderProfileResolver(
-            camcorderProfileVideoMime,
+        val mediaFormat = VideoEncoderConfigVideoProfileResolver(
+            videoProfile.mediaType,
             timebase,
             videoSpec,
             resolution!!,
-            camcorderProfile,
+            videoProfile,
             /*expectedFrameRateRange=*/null
         ).get().toMediaFormat()
 
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/QualitySelector.java b/camera/camera-video/src/main/java/androidx/camera/video/QualitySelector.java
index ae10a14..a48f442 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/QualitySelector.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/QualitySelector.java
@@ -27,7 +27,8 @@
 import androidx.annotation.RestrictTo;
 import androidx.camera.core.CameraInfo;
 import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.core.util.Preconditions;
 
 import java.util.ArrayList;
@@ -139,8 +140,9 @@
     @Nullable
     public static Size getResolution(@NonNull CameraInfo cameraInfo, @NonNull Quality quality) {
         checkQualityConstantsOrThrow(quality);
-        CamcorderProfileProxy profile = VideoCapabilities.from(cameraInfo).getProfile(quality);
-        return profile != null ? getProfileVideoSize(profile) : null;
+        VideoValidatedEncoderProfilesProxy profiles =
+                VideoCapabilities.from(cameraInfo).getProfiles(quality);
+        return profiles != null ? getProfileVideoSize(profiles) : null;
     }
 
     /**
@@ -156,7 +158,7 @@
         Map<Quality, Size> map = new HashMap<>();
         for (Quality supportedQuality : videoCapabilities.getSupportedQualities()) {
             map.put(supportedQuality, getProfileVideoSize(
-                    requireNonNull(videoCapabilities.getProfile(supportedQuality))));
+                    requireNonNull(videoCapabilities.getProfiles(supportedQuality))));
         }
         return map;
     }
@@ -404,8 +406,9 @@
     }
 
     @NonNull
-    private static Size getProfileVideoSize(@NonNull CamcorderProfileProxy profile) {
-        return new Size(profile.getVideoFrameWidth(), profile.getVideoFrameHeight());
+    private static Size getProfileVideoSize(@NonNull VideoValidatedEncoderProfilesProxy profiles) {
+        VideoProfileProxy videoProfile = profiles.getDefaultVideoProfile();
+        return new Size(videoProfile.getWidth(), videoProfile.getHeight());
     }
 
     private static void checkQualityConstantsOrThrow(@NonNull List<Quality> qualities) {
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java b/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java
index 701b88d..78f4a24 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java
@@ -59,7 +59,6 @@
 import androidx.camera.core.AspectRatio;
 import androidx.camera.core.Logger;
 import androidx.camera.core.SurfaceRequest;
-import androidx.camera.core.impl.CamcorderProfileProxy;
 import androidx.camera.core.impl.MutableStateObservable;
 import androidx.camera.core.impl.Observable;
 import androidx.camera.core.impl.StateObservable;
@@ -74,6 +73,7 @@
 import androidx.camera.video.StreamInfo.StreamState;
 import androidx.camera.video.internal.AudioSource;
 import androidx.camera.video.internal.AudioSourceAccessException;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.camera.video.internal.compat.Api26Impl;
 import androidx.camera.video.internal.compat.quirk.DeactivateEncoderSurfaceBeforeStopEncoderQuirk;
 import androidx.camera.video.internal.compat.quirk.DeviceQuirks;
@@ -346,7 +346,7 @@
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     boolean mInProgressRecordingStopping = false;
     private SurfaceRequest.TransformationInfo mSurfaceTransformationInfo = null;
-    private CamcorderProfileProxy mResolvedCamcorderProfile = null;
+    private VideoValidatedEncoderProfilesProxy mResolvedEncoderProfiles = null;
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     final List<ListenableFuture<Void>> mEncodingFutures = new ArrayList<>();
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
@@ -1041,17 +1041,17 @@
         surfaceRequest.setTransformationInfoListener(mSequentialExecutor,
                 (transformationInfo) -> mSurfaceTransformationInfo = transformationInfo);
         Size surfaceSize = surfaceRequest.getResolution();
-        // Fetch and cache nearest camcorder profile, if one exists.
+        // Fetch and cache nearest encoder profiles, if one exists.
         VideoCapabilities capabilities =
                 VideoCapabilities.from(surfaceRequest.getCamera().getCameraInfo());
         Quality highestSupportedQuality = capabilities.findHighestSupportedQualityFor(surfaceSize);
         Logger.d(TAG, "Using supported quality of " + highestSupportedQuality
                 + " for surface size " + surfaceSize);
         if (highestSupportedQuality != Quality.NONE) {
-            mResolvedCamcorderProfile = capabilities.getProfile(highestSupportedQuality);
-            if (mResolvedCamcorderProfile == null) {
+            mResolvedEncoderProfiles = capabilities.getProfiles(highestSupportedQuality);
+            if (mResolvedEncoderProfiles == null) {
                 throw new AssertionError("Camera advertised available quality but did not "
-                        + "produce CamcorderProfile for advertised quality.");
+                        + "produce EncoderProfiles  for advertised quality.");
             }
         }
         setupVideo(surfaceRequest, videoSourceTimebase);
@@ -1071,7 +1071,7 @@
             MediaSpec mediaSpec = getObservableData(mMediaSpec);
             ListenableFuture<Encoder> configureFuture =
                     videoEncoderSession.configure(request, timebase, mediaSpec,
-                            mResolvedCamcorderProfile);
+                            mResolvedEncoderProfiles);
             mVideoEncoderSession = videoEncoderSession;
             Futures.addCallback(configureFuture, new FutureCallback<Encoder>() {
                 @Override
@@ -1237,7 +1237,7 @@
             throws AudioSourceAccessException, InvalidConfigException {
         MediaSpec mediaSpec = getObservableData(mMediaSpec);
         // Resolve the audio mime info
-        MimeInfo audioMimeInfo = resolveAudioMimeInfo(mediaSpec, mResolvedCamcorderProfile);
+        MimeInfo audioMimeInfo = resolveAudioMimeInfo(mediaSpec, mResolvedEncoderProfiles);
         Timebase audioSourceTimebase = Timebase.UPTIME;
 
         // Select and create the audio source
@@ -1377,7 +1377,7 @@
                 MediaSpec mediaSpec = getObservableData(mMediaSpec);
                 int muxerOutputFormat =
                         mediaSpec.getOutputFormat() == MediaSpec.OUTPUT_FORMAT_AUTO
-                                ? supportedMuxerFormatOrDefaultFrom(mResolvedCamcorderProfile,
+                                ? supportedMuxerFormatOrDefaultFrom(mResolvedEncoderProfiles,
                                 MediaSpec.outputFormatToMuxerFormat(
                                         MEDIA_SPEC_DEFAULT.getOutputFormat()))
                                 : MediaSpec.outputFormatToMuxerFormat(mediaSpec.getOutputFormat());
@@ -2566,9 +2566,9 @@
     }
 
     private static int supportedMuxerFormatOrDefaultFrom(
-            @Nullable CamcorderProfileProxy profileProxy, int defaultMuxerFormat) {
-        if (profileProxy != null) {
-            switch (profileProxy.getFileFormat()) {
+            @Nullable VideoValidatedEncoderProfilesProxy profilesProxy, int defaultMuxerFormat) {
+        if (profilesProxy != null) {
+            switch (profilesProxy.getRecommendedFileFormat()) {
                 case MediaRecorder.OutputFormat.MPEG_4:
                     return MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4;
                 case MediaRecorder.OutputFormat.WEBM:
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java
index dfd3af6..a28a713 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java
@@ -25,10 +25,14 @@
 import androidx.annotation.RestrictTo.Scope;
 import androidx.camera.core.CameraInfo;
 import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProvider;
-import androidx.camera.core.impl.CamcorderProfileProxy;
 import androidx.camera.core.impl.CameraInfoInternal;
+import androidx.camera.core.impl.EncoderProfilesProvider;
+import androidx.camera.core.impl.EncoderProfilesProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy;
+import androidx.camera.core.impl.Quirks;
+import androidx.camera.core.impl.ResolutionValidatedEncoderProfilesProvider;
 import androidx.camera.core.impl.utils.CompareSizesByArea;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.camera.video.internal.compat.quirk.DeviceQuirks;
 import androidx.camera.video.internal.compat.quirk.VideoQualityQuirk;
 import androidx.core.util.Preconditions;
@@ -54,55 +58,61 @@
     private static final String TAG = "VideoCapabilities";
 
     /**
-     * The supported @link CamcorderProfileProxy} map from quality to CamcorderProfileProxy. The
-     * order is from size large to small.
+     * Maps quality to supported {@link VideoValidatedEncoderProfilesProxy}. The order is from
+     * size large to small.
      */
-    private final Map<Quality, CamcorderProfileProxy> mSupportedProfileMap = new LinkedHashMap<>();
+    private final Map<Quality, VideoValidatedEncoderProfilesProxy> mSupportedProfilesMap =
+            new LinkedHashMap<>();
     private final TreeMap<Size, Quality> mAreaSortedSizeToQualityMap =
             new TreeMap<>(new CompareSizesByArea());
-    private final CamcorderProfileProxy mHighestProfile;
-    private final CamcorderProfileProxy mLowestProfile;
+    private final VideoValidatedEncoderProfilesProxy mHighestProfiles;
+    private final VideoValidatedEncoderProfilesProxy mLowestProfiles;
+    private final EncoderProfilesProvider mEncoderProfilesProvider;
 
     /**
      * Creates a VideoCapabilities.
      *
      * @param cameraInfoInternal the cameraInfo
      * @throws IllegalArgumentException if unable to get the capability information from the
-     * CameraInfo.
+     *                                  CameraInfo.
      */
     VideoCapabilities(@NonNull CameraInfoInternal cameraInfoInternal) {
-        CamcorderProfileProvider camcorderProfileProvider =
-                cameraInfoInternal.getCamcorderProfileProvider();
+        Quirks cameraQuirks = cameraInfoInternal.getCameraQuirks();
+        mEncoderProfilesProvider = new ResolutionValidatedEncoderProfilesProvider(
+                cameraInfoInternal.getEncoderProfilesProvider(), cameraQuirks);
 
         // Construct supported profile map
         for (Quality quality : Quality.getSortedQualities()) {
-            // SortedQualities is from size large to small
-            Preconditions.checkState(quality instanceof Quality.ConstantQuality,
-                    "Currently only support ConstantQuality");
-            int qualityValue = ((Quality.ConstantQuality) quality).getValue();
-
-            // Get CamcorderProfile
-            if (!camcorderProfileProvider.hasProfile(qualityValue) || !isDeviceValidQuality(
-                    cameraInfoInternal, quality)) {
+            EncoderProfilesProxy profiles = getEncoderProfiles(cameraInfoInternal, quality);
+            if (profiles == null) {
                 continue;
             }
-            CamcorderProfileProxy profile =
-                    Preconditions.checkNotNull(camcorderProfileProvider.get(qualityValue));
-            Size profileSize = new Size(profile.getVideoFrameWidth(),
-                    profile.getVideoFrameHeight());
-            Logger.d(TAG, "profile = " + profile);
-            mSupportedProfileMap.put(quality, profile);
-            mAreaSortedSizeToQualityMap.put(profileSize, quality);
+
+            // Validate that EncoderProfiles contain video information
+            Logger.d(TAG, "profiles = " + profiles);
+            VideoValidatedEncoderProfilesProxy validatedProfiles = toValidatedProfiles(profiles);
+            if (validatedProfiles == null) {
+                Logger.w(TAG, "EncoderProfiles of quality " + quality + " has no video "
+                        + "validated profiles.");
+                continue;
+            }
+
+            VideoProfileProxy videoProfile = validatedProfiles.getDefaultVideoProfile();
+            Size size = new Size(videoProfile.getWidth(), videoProfile.getHeight());
+            mAreaSortedSizeToQualityMap.put(size, quality);
+
+            // SortedQualities is from size large to small
+            mSupportedProfilesMap.put(quality, validatedProfiles);
         }
-        if (mSupportedProfileMap.isEmpty()) {
-            Logger.e(TAG, "No supported CamcorderProfile");
-            mLowestProfile = null;
-            mHighestProfile = null;
+        if (mSupportedProfilesMap.isEmpty()) {
+            Logger.e(TAG, "No supported EncoderProfiles");
+            mLowestProfiles = null;
+            mHighestProfiles = null;
         } else {
-            Deque<CamcorderProfileProxy> profileQueue = new ArrayDeque<>(
-                    mSupportedProfileMap.values());
-            mHighestProfile = profileQueue.peekFirst();
-            mLowestProfile = profileQueue.peekLast();
+            Deque<VideoValidatedEncoderProfilesProxy> profileQueue = new ArrayDeque<>(
+                    mSupportedProfilesMap.values());
+            mHighestProfiles = profileQueue.peekFirst();
+            mLowestProfiles = profileQueue.peekLast();
         }
     }
 
@@ -116,77 +126,78 @@
      * Gets all supported qualities on the device.
      *
      * <p>The returned list is sorted by quality size from large to small. For the qualities in
-     * the returned list, calling {@link #getProfile(Quality)} with these qualities will return a
+     * the returned list, calling {@link #getProfiles(Quality)} with these qualities will return a
      * non-null result.
      *
      * <p>Note: Constants {@link Quality#HIGHEST} and {@link Quality#LOWEST} are not included.
      */
     @NonNull
     public List<Quality> getSupportedQualities() {
-        return new ArrayList<>(mSupportedProfileMap.keySet());
+        return new ArrayList<>(mSupportedProfilesMap.keySet());
     }
 
     /**
      * Checks if the quality is supported.
      *
      * @param quality one of the quality constants. Possible values include
-     * {@link Quality#LOWEST}, {@link Quality#HIGHEST}, {@link Quality#SD},
-     * {@link Quality#HD}, {@link Quality#FHD}, or {@link Quality#UHD}.
+     *                {@link Quality#LOWEST}, {@link Quality#HIGHEST}, {@link Quality#SD},
+     *                {@link Quality#HD}, {@link Quality#FHD}, or {@link Quality#UHD}.
      * @return {@code true} if the quality is supported; {@code false} otherwise.
      * @throws IllegalArgumentException if not a quality constant.
      */
     public boolean isQualitySupported(@NonNull Quality quality) {
         checkQualityConstantsOrThrow(quality);
-        return getProfile(quality) != null;
+        return getProfiles(quality) != null;
     }
 
     /**
-     * Gets the corresponding {@link CamcorderProfileProxy} of the input quality.
+     * Gets the corresponding {@link VideoValidatedEncoderProfilesProxy} of the input quality.
      *
      * @param quality one of the quality constants. Possible values include
-     * {@link Quality#LOWEST}, {@link Quality#HIGHEST}, {@link Quality#SD}, {@link Quality#HD},
-     * {@link Quality#FHD}, or {@link Quality#UHD}.
-     * @return the CamcorderProfileProxy
+     *                {@link Quality#LOWEST}, {@link Quality#HIGHEST}, {@link Quality#SD},
+     *                {@link Quality#HD}, {@link Quality#FHD}, or {@link Quality#UHD}.
+     * @return the VideoValidatedEncoderProfilesProxy
      * @throws IllegalArgumentException if not a quality constant
      */
     @Nullable
-    public CamcorderProfileProxy getProfile(@NonNull Quality quality) {
+    public VideoValidatedEncoderProfilesProxy getProfiles(@NonNull Quality quality) {
         checkQualityConstantsOrThrow(quality);
         if (quality == Quality.HIGHEST) {
-            return mHighestProfile;
+            return mHighestProfiles;
         } else if (quality == Quality.LOWEST) {
-            return mLowestProfile;
+            return mLowestProfiles;
         }
-        return mSupportedProfileMap.get(quality);
+        return mSupportedProfilesMap.get(quality);
     }
 
     /**
-     * Finds the supported CamcorderProfileProxy with the resolution nearest to the given
+     * Finds the supported EncoderProfilesProxy with the resolution nearest to the given
      * {@link Size}.
      *
-     * <p>The supported CamcorderProfileProxy means the corresponding {@link Quality} is also
-     * supported. If the size aligns exactly with the pixel count of a CamcorderProfileProxy, that
-     * CamcorderProfileProxy will be selected. If the size falls between two
-     * CamcorderProfileProxy, the higher resolution will always be selected. Otherwise, the
-     * nearest CamcorderProfileProxy will be selected, whether that CamcorderProfileProxy's
-     * resolution is above or below the given size.
+     * <p>The supported EncoderProfilesProxy means the corresponding {@link Quality} is also
+     * supported. If the size aligns exactly with the pixel count of an EncoderProfilesProxy, that
+     * EncoderProfilesProxy will be selected. If the size falls between two EncoderProfilesProxy,
+     * the higher resolution will always be selected. Otherwise, the nearest EncoderProfilesProxy
+     * will be selected, whether that EncoderProfilesProxy's resolution is above or below the
+     * given size.
      *
      * @see #findHighestSupportedQualityFor(Size)
      */
     @Nullable
-    public CamcorderProfileProxy findHighestSupportedCamcorderProfileFor(@NonNull Size size) {
-        CamcorderProfileProxy camcorderProfile = null;
+    public VideoValidatedEncoderProfilesProxy findHighestSupportedEncoderProfilesFor(
+            @NonNull Size size) {
+        VideoValidatedEncoderProfilesProxy encoderProfiles = null;
         Quality highestSupportedQuality = findHighestSupportedQualityFor(size);
         Logger.d(TAG,
                 "Using supported quality of " + highestSupportedQuality + " for size " + size);
         if (highestSupportedQuality != Quality.NONE) {
-            camcorderProfile = getProfile(highestSupportedQuality);
-            if (camcorderProfile == null) {
+            encoderProfiles = getProfiles(highestSupportedQuality);
+            if (encoderProfiles == null) {
                 throw new AssertionError("Camera advertised available quality but did not "
-                        + "produce CamcorderProfile for advertised quality.");
+                        + "produce EncoderProfiles for advertised quality.");
             }
         }
-        return camcorderProfile;
+        return encoderProfiles;
     }
 
     /**
@@ -196,6 +207,7 @@
      * will be selected. If the size falls between two qualities, the higher quality will always
      * be selected. Otherwise, the nearest single quality will be selected, whether that
      * quality's size is above or below the given size.
+     *
      * @param size The size representing the number of pixels for comparison. Pixels are assumed
      *             to be square.
      * @return The quality constant defined in {@link Quality}. If no qualities are supported,
@@ -238,4 +250,30 @@
         return true;
     }
 
+    @Nullable
+    private EncoderProfilesProxy getEncoderProfiles(@NonNull CameraInfoInternal cameraInfo,
+            @NonNull Quality quality) {
+        Preconditions.checkState(quality instanceof Quality.ConstantQuality,
+                "Currently only support ConstantQuality");
+        int qualityValue = ((Quality.ConstantQuality) quality).getValue();
+
+        if (!mEncoderProfilesProvider.hasProfile(qualityValue) || !isDeviceValidQuality(cameraInfo,
+                quality)) {
+            return null;
+        }
+
+        return mEncoderProfilesProvider.getAll(qualityValue);
+    }
+
+    @Nullable
+    private VideoValidatedEncoderProfilesProxy toValidatedProfiles(
+            @NonNull EncoderProfilesProxy profiles) {
+        // According to the document, the first profile is the default video profile.
+        List<VideoProfileProxy> videoProfiles = profiles.getVideoProfiles();
+        if (videoProfiles.isEmpty()) {
+            return null;
+        }
+
+        return VideoValidatedEncoderProfilesProxy.from(profiles);
+    }
 }
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
index 1d5fad6..3c0a5fa 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
@@ -73,7 +73,6 @@
 import androidx.camera.core.SurfaceRequest;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.ViewPort;
-import androidx.camera.core.impl.CamcorderProfileProxy;
 import androidx.camera.core.impl.CameraCaptureCallback;
 import androidx.camera.core.impl.CameraCaptureResult;
 import androidx.camera.core.impl.CameraInfoInternal;
@@ -101,10 +100,10 @@
 import androidx.camera.core.internal.ThreadConfig;
 import androidx.camera.core.processing.DefaultSurfaceProcessor;
 import androidx.camera.core.processing.SurfaceEdge;
-import androidx.camera.core.processing.SurfaceProcessorInternal;
 import androidx.camera.core.processing.SurfaceProcessorNode;
 import androidx.camera.video.StreamInfo.StreamState;
 import androidx.camera.video.impl.VideoCaptureConfig;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.camera.video.internal.compat.quirk.DeviceQuirks;
 import androidx.camera.video.internal.compat.quirk.ExtraSupportedResolutionQuirk;
 import androidx.camera.video.internal.compat.quirk.ImageCaptureFailedWhenVideoCaptureIsBoundQuirk;
@@ -194,8 +193,6 @@
     @SuppressWarnings("WeakerAccess") // Synthetic access
     VideoOutput.SourceState mSourceState = VideoOutput.SourceState.INACTIVE;
     @Nullable
-    private SurfaceProcessorInternal mSurfaceProcessor;
-    @Nullable
     private SurfaceProcessorNode mNode;
     @Nullable
     private VideoEncoderInfo mVideoEncoderInfo;
@@ -311,21 +308,6 @@
     }
 
     /**
-     * Sets a {@link SurfaceProcessorInternal}.
-     *
-     * <p>The processor is used to setup post-processing pipeline.
-     *
-     * <p>Note: the value will only be used when VideoCapture is bound. Calling this method after
-     * VideoCapture is bound takes no effect until VideoCapture is rebound.
-     *
-     * @hide
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    public void setProcessor(@Nullable SurfaceProcessorInternal surfaceProcessor) {
-        mSurfaceProcessor = surfaceProcessor;
-    }
-
-    /**
      * {@inheritDoc}
      *
      * @hide
@@ -719,10 +701,10 @@
 
     @Nullable
     private SurfaceProcessorNode createNodeIfNeeded(boolean isCropNeeded) {
-        if (mSurfaceProcessor != null || ENABLE_SURFACE_PROCESSING_BY_QUIRK || isCropNeeded) {
+        if (getEffect() != null || ENABLE_SURFACE_PROCESSING_BY_QUIRK || isCropNeeded) {
             Logger.d(TAG, "Surface processing is enabled.");
             return new SurfaceProcessorNode(requireNonNull(getCamera()),
-                    mSurfaceProcessor != null ? mSurfaceProcessor :
+                    getEffect() != null ? getEffect().createSurfaceProcessorInternal() :
                             DefaultSurfaceProcessor.Factory.newInstance());
         }
         return null;
@@ -897,11 +879,11 @@
             return mVideoEncoderInfo;
         }
 
-        // Find the nearest CamcorderProfile
-        CamcorderProfileProxy camcorderProfileProxy =
-                videoCapabilities.findHighestSupportedCamcorderProfileFor(resolution);
+        // Find the nearest EncoderProfiles
+        VideoValidatedEncoderProfilesProxy encoderProfiles =
+                videoCapabilities.findHighestSupportedEncoderProfilesFor(resolution);
         VideoEncoderInfo videoEncoderInfo = resolveVideoEncoderInfo(videoEncoderInfoFinder,
-                camcorderProfileProxy, mediaSpec, resolution, targetFps);
+                encoderProfiles, mediaSpec, resolution, targetFps);
         if (videoEncoderInfo == null) {
             // If VideoCapture cannot find videoEncoderInfo, it means that VideoOutput should
             // also not be able to find the encoder. VideoCapture will not handle this situation
@@ -910,9 +892,9 @@
             return null;
         }
 
-        Size profileSize = camcorderProfileProxy != null ? new Size(
-                camcorderProfileProxy.getVideoFrameWidth(),
-                camcorderProfileProxy.getVideoFrameHeight()) : null;
+        Size profileSize = encoderProfiles != null ? new Size(
+                encoderProfiles.getDefaultVideoProfile().getWidth(),
+                encoderProfiles.getDefaultVideoProfile().getHeight()) : null;
         videoEncoderInfo = VideoEncoderInfoWrapper.from(videoEncoderInfo, profileSize);
 
         // Cache the VideoEncoderInfo as it should be the same when recreating the pipeline.
@@ -926,12 +908,12 @@
     @Nullable
     private static VideoEncoderInfo resolveVideoEncoderInfo(
             @NonNull Function<VideoEncoderConfig, VideoEncoderInfo> videoEncoderInfoFinder,
-            @Nullable CamcorderProfileProxy camcorderProfileProxy,
+            @Nullable VideoValidatedEncoderProfilesProxy encoderProfiles,
             @NonNull MediaSpec mediaSpec,
             @NonNull Size resolution,
             @NonNull Range<Integer> targetFps) {
         // Resolve the VideoEncoderConfig
-        MimeInfo videoMimeInfo = resolveVideoMimeInfo(mediaSpec, camcorderProfileProxy);
+        MimeInfo videoMimeInfo = resolveVideoMimeInfo(mediaSpec, encoderProfiles);
         VideoEncoderConfig videoEncoderConfig = resolveVideoEncoderConfig(
                 videoMimeInfo,
                 // Timebase won't affect the found EncoderInfo so give a arbitrary one.
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoEncoderSession.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoEncoderSession.java
index abc597f..9b9d46c 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoEncoderSession.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoEncoderSession.java
@@ -16,8 +16,9 @@
 
 package androidx.camera.video;
 
-import android.util.Range;
-import android.util.Size;
+import static androidx.camera.video.internal.config.VideoConfigUtil.resolveVideoEncoderConfig;
+import static androidx.camera.video.internal.config.VideoConfigUtil.resolveVideoMimeInfo;
+
 import android.view.Surface;
 
 import androidx.annotation.NonNull;
@@ -25,21 +26,18 @@
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.Logger;
 import androidx.camera.core.SurfaceRequest;
-import androidx.camera.core.impl.CamcorderProfileProxy;
 import androidx.camera.core.impl.Timebase;
 import androidx.camera.core.impl.annotation.ExecutedBy;
 import androidx.camera.core.impl.utils.futures.FutureCallback;
 import androidx.camera.core.impl.utils.futures.Futures;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.camera.video.internal.config.MimeInfo;
-import androidx.camera.video.internal.config.VideoEncoderConfigCamcorderProfileResolver;
-import androidx.camera.video.internal.config.VideoEncoderConfigDefaultResolver;
 import androidx.camera.video.internal.encoder.Encoder;
 import androidx.camera.video.internal.encoder.Encoder.SurfaceInput.OnSurfaceUpdateListener;
 import androidx.camera.video.internal.encoder.EncoderFactory;
 import androidx.camera.video.internal.encoder.InvalidConfigException;
 import androidx.camera.video.internal.encoder.VideoEncoderConfig;
 import androidx.concurrent.futures.CallbackToFutureAdapter;
-import androidx.core.util.Supplier;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
@@ -109,7 +107,7 @@
     @ExecutedBy("mSequentialExecutor")
     ListenableFuture<Encoder> configure(@NonNull SurfaceRequest surfaceRequest,
             @NonNull Timebase timebase, @NonNull MediaSpec mediaSpec,
-            @Nullable CamcorderProfileProxy resolvedCamcorderProfile) {
+            @Nullable VideoValidatedEncoderProfilesProxy resolvedEncoderProfiles) {
         switch (mVideoEncoderState) {
             case NOT_INITIALIZED:
                 mVideoEncoderState = VideoEncoderState.INITIALIZING;
@@ -127,7 +125,7 @@
                 ListenableFuture<Encoder> configureFuture = CallbackToFutureAdapter.getFuture(
                         completer -> {
                             configureVideoEncoderInternal(surfaceRequest, timebase,
-                                    resolvedCamcorderProfile,
+                                    resolvedEncoderProfiles,
                                     mediaSpec, completer);
                             return "ConfigureVideoEncoderFuture " + VideoEncoderSession.this;
                         });
@@ -286,10 +284,10 @@
     @ExecutedBy("mSequentialExecutor")
     private void configureVideoEncoderInternal(@NonNull SurfaceRequest surfaceRequest,
             @NonNull Timebase timebase,
-            @Nullable CamcorderProfileProxy resolvedCamcorderProfile,
+            @Nullable VideoValidatedEncoderProfilesProxy resolvedEncoderProfiles,
             @NonNull MediaSpec mediaSpec,
             @NonNull CallbackToFutureAdapter.Completer<Encoder> configureCompleter) {
-        MimeInfo videoMimeInfo = resolveVideoMimeInfo(resolvedCamcorderProfile, mediaSpec);
+        MimeInfo videoMimeInfo = resolveVideoMimeInfo(mediaSpec, resolvedEncoderProfiles);
 
         // The VideoSpec from mediaSpec only contains settings requested by the recorder, but
         // the actual settings may need to differ depending on the FPS chosen by the camera.
@@ -371,69 +369,6 @@
         }
     }
 
-    @ExecutedBy("mSequentialExecutor")
-    private MimeInfo resolveVideoMimeInfo(@Nullable CamcorderProfileProxy resolvedCamcorderProfile,
-            @NonNull MediaSpec mediaSpec) {
-        String mediaSpecVideoMime = MediaSpec.outputFormatToVideoMime(mediaSpec.getOutputFormat());
-        String resolvedVideoMime = mediaSpecVideoMime;
-        boolean camcorderProfileIsCompatible = false;
-        if (resolvedCamcorderProfile != null) {
-            String camcorderProfileVideoMime = resolvedCamcorderProfile.getVideoCodecMimeType();
-            // Use camcorder profile settings if the media spec's output format
-            // is set to auto or happens to match the CamcorderProfile's output format.
-            if (camcorderProfileVideoMime == null) {
-                Logger.d(TAG, "CamcorderProfile contains undefined VIDEO mime type so cannot be "
-                        + "used. May rely on fallback defaults to derive settings "
-                        + "[chosen mime type: " + resolvedVideoMime + "]");
-            } else if (mediaSpec.getOutputFormat() == MediaSpec.OUTPUT_FORMAT_AUTO) {
-                camcorderProfileIsCompatible = true;
-                resolvedVideoMime = camcorderProfileVideoMime;
-                Logger.d(TAG, "MediaSpec contains OUTPUT_FORMAT_AUTO. Using CamcorderProfile "
-                        + "to derive VIDEO settings [mime type: " + resolvedVideoMime + "]");
-            } else if (Objects.equals(mediaSpecVideoMime, camcorderProfileVideoMime)) {
-                camcorderProfileIsCompatible = true;
-                resolvedVideoMime = camcorderProfileVideoMime;
-                Logger.d(TAG, "MediaSpec video mime matches CamcorderProfile. Using "
-                        + "CamcorderProfile to derive VIDEO settings [mime type: "
-                        + resolvedVideoMime + "]");
-            } else {
-                Logger.d(TAG, "MediaSpec video mime does not match CamcorderProfile, so "
-                        + "CamcorderProfile settings cannot be used. May rely on fallback "
-                        + "defaults to derive VIDEO settings [CamcorderProfile mime type: "
-                        + camcorderProfileVideoMime + ", chosen mime type: " + resolvedVideoMime
-                        + "]");
-            }
-        } else {
-            Logger.d(TAG, "No CamcorderProfile present. May rely on fallback defaults to derive "
-                    + "VIDEO settings [chosen mime type: " + resolvedVideoMime + "]");
-        }
-
-        MimeInfo.Builder mimeInfoBuilder = MimeInfo.builder(resolvedVideoMime);
-        if (camcorderProfileIsCompatible) {
-            mimeInfoBuilder.setCompatibleCamcorderProfile(resolvedCamcorderProfile);
-        }
-
-        return mimeInfoBuilder.build();
-    }
-
-    @NonNull
-    private static VideoEncoderConfig resolveVideoEncoderConfig(@NonNull MimeInfo videoMimeInfo,
-            @NonNull Timebase timebase, @NonNull VideoSpec videoSpec, @NonNull Size surfaceSize,
-            @Nullable Range<Integer> expectedFrameRateRange) {
-        Supplier<VideoEncoderConfig> configSupplier;
-        if (videoMimeInfo.getCompatibleCamcorderProfile() != null) {
-            configSupplier = new VideoEncoderConfigCamcorderProfileResolver(
-                    videoMimeInfo.getMimeType(), timebase, videoSpec, surfaceSize,
-                    videoMimeInfo.getCompatibleCamcorderProfile(),
-                    expectedFrameRateRange);
-        } else {
-            configSupplier = new VideoEncoderConfigDefaultResolver(videoMimeInfo.getMimeType(),
-                    timebase, videoSpec, surfaceSize, expectedFrameRateRange);
-        }
-
-        return configSupplier.get();
-    }
-
     @NonNull
     @Override
     public String toString() {
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/ReportedVideoQualityNotSupportedQuirk.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/ReportedVideoQualityNotSupportedQuirk.java
index acf2bd5..d4bf9fe 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/ReportedVideoQualityNotSupportedQuirk.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/ReportedVideoQualityNotSupportedQuirk.java
@@ -25,7 +25,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
-import androidx.camera.core.impl.CamcorderProfileProvider;
 import androidx.camera.core.impl.CameraInfoInternal;
 import androidx.camera.video.Quality;
 
@@ -33,7 +32,7 @@
 import java.util.Locale;
 
 /**
- * Quirk where qualities reported as available by {@link CamcorderProfileProvider#hasProfile(int)}
+ * Quirk where qualities reported as available by {@link CamcorderProfile#hasProfile(int)}
  * does not work on the device, and should not be used.
  *
  * <p>QuirkSummary
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioConfigUtil.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioConfigUtil.java
index 61bea4c..9979dd5 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioConfigUtil.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioConfigUtil.java
@@ -16,6 +16,8 @@
 
 package androidx.camera.video.internal.config;
 
+import static java.util.Objects.requireNonNull;
+
 import android.util.Range;
 import android.util.Rational;
 
@@ -23,11 +25,12 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy.AudioProfileProxy;
 import androidx.camera.core.impl.Timebase;
 import androidx.camera.video.AudioSpec;
 import androidx.camera.video.MediaSpec;
 import androidx.camera.video.internal.AudioSource;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.camera.video.internal.encoder.AudioEncoderConfig;
 import androidx.core.util.Supplier;
 
@@ -60,48 +63,48 @@
      * Resolves the audio mime information into a {@link MimeInfo}.
      *
      * @param mediaSpec        the media spec to resolve the mime info.
-     * @param camcorderProfile the camcorder profile to resolve the mime info. It can be null if
-     *                         there is no relevant camcorder profile.
+     * @param encoderProfiles  the encoder profiles to resolve the mime info. It can be null if
+     *                         there is no relevant encoder profiles.
      * @return the audio MimeInfo.
      */
     @NonNull
     public static MimeInfo resolveAudioMimeInfo(@NonNull MediaSpec mediaSpec,
-            @Nullable CamcorderProfileProxy camcorderProfile) {
+            @Nullable VideoValidatedEncoderProfilesProxy encoderProfiles) {
         String mediaSpecAudioMime = MediaSpec.outputFormatToAudioMime(mediaSpec.getOutputFormat());
         int mediaSpecAudioProfile =
                 MediaSpec.outputFormatToAudioProfile(mediaSpec.getOutputFormat());
         String resolvedAudioMime = mediaSpecAudioMime;
         int resolvedAudioProfile = mediaSpecAudioProfile;
-        boolean camcorderProfileIsCompatible = false;
-        if (camcorderProfile != null) {
-            String camcorderProfileAudioMime = camcorderProfile.getAudioCodecMimeType();
-            int camcorderProfileAudioProfile = camcorderProfile.getRequiredAudioProfile();
+        boolean encoderProfilesIsCompatible = false;
+        if (encoderProfiles != null && encoderProfiles.getDefaultAudioProfile() != null) {
+            AudioProfileProxy audioProfile = encoderProfiles.getDefaultAudioProfile();
+            String encoderProfileAudioMime = audioProfile.getMediaType();
+            int encoderProfileAudioProfile = audioProfile.getProfile();
 
-            if (camcorderProfileAudioMime == null) {
-                Logger.d(TAG, "CamcorderProfile contains undefined AUDIO mime type so cannot be "
+            if (Objects.equals(encoderProfileAudioMime, AudioProfileProxy.MEDIA_TYPE_NONE)) {
+                Logger.d(TAG, "EncoderProfiles contains undefined AUDIO mime type so cannot be "
                         + "used. May rely on fallback defaults to derive settings [chosen mime "
                         + "type: "
                         + resolvedAudioMime + "(profile: " + resolvedAudioProfile + ")]");
             } else if (mediaSpec.getOutputFormat() == MediaSpec.OUTPUT_FORMAT_AUTO) {
-                camcorderProfileIsCompatible = true;
-                resolvedAudioMime = camcorderProfileAudioMime;
-                resolvedAudioProfile = camcorderProfileAudioProfile;
-                Logger.d(TAG, "MediaSpec contains OUTPUT_FORMAT_AUTO. Using CamcorderProfile "
+                encoderProfilesIsCompatible = true;
+                resolvedAudioMime = encoderProfileAudioMime;
+                resolvedAudioProfile = encoderProfileAudioProfile;
+                Logger.d(TAG, "MediaSpec contains OUTPUT_FORMAT_AUTO. Using EncoderProfiles "
                         + "to derive AUDIO settings [mime type: "
                         + resolvedAudioMime + "(profile: " + resolvedAudioProfile + ")]");
-            } else if (Objects.equals(mediaSpecAudioMime, camcorderProfileAudioMime)
-                    && mediaSpecAudioProfile == camcorderProfileAudioProfile) {
-                camcorderProfileIsCompatible = true;
-                resolvedAudioMime = camcorderProfileAudioMime;
-                resolvedAudioProfile = camcorderProfileAudioProfile;
-                Logger.d(TAG, "MediaSpec audio mime/profile matches CamcorderProfile. "
-                        + "Using CamcorderProfile to derive AUDIO settings [mime type: "
+            } else if (Objects.equals(mediaSpecAudioMime, encoderProfileAudioMime)
+                    && mediaSpecAudioProfile == encoderProfileAudioProfile) {
+                encoderProfilesIsCompatible = true;
+                resolvedAudioMime = encoderProfileAudioMime;
+                Logger.d(TAG, "MediaSpec audio mime/profile matches EncoderProfiles. "
+                        + "Using EncoderProfiles to derive AUDIO settings [mime type: "
                         + resolvedAudioMime + "(profile: " + resolvedAudioProfile + ")]");
             } else {
-                Logger.d(TAG, "MediaSpec audio mime or profile does not match CamcorderProfile, so "
-                        + "CamcorderProfile settings cannot be used. May rely on fallback "
-                        + "defaults to derive AUDIO settings [CamcorderProfile mime type: "
-                        + camcorderProfileAudioMime + "(profile: " + camcorderProfileAudioProfile
+                Logger.d(TAG, "MediaSpec audio mime or profile does not match EncoderProfiles, so "
+                        + "EncoderProfiles settings cannot be used. May rely on fallback defaults"
+                        + " to derive AUDIO settings [EncoderProfiles mime type: "
+                        + encoderProfileAudioMime + "(profile: " + encoderProfileAudioProfile
                         + "), chosen mime type: "
                         + resolvedAudioMime + "(profile: " + resolvedAudioProfile + ")]");
             }
@@ -109,8 +112,8 @@
 
         MimeInfo.Builder mimeInfoBuilder = MimeInfo.builder(resolvedAudioMime)
                 .setProfile(resolvedAudioProfile);
-        if (camcorderProfileIsCompatible) {
-            mimeInfoBuilder.setCompatibleCamcorderProfile(camcorderProfile);
+        if (encoderProfilesIsCompatible) {
+            mimeInfoBuilder.setCompatibleEncoderProfiles(encoderProfiles);
         }
 
         return mimeInfoBuilder.build();
@@ -127,9 +130,10 @@
     public static AudioSource.Settings resolveAudioSourceSettings(@NonNull MimeInfo audioMimeInfo,
             @NonNull AudioSpec audioSpec) {
         Supplier<AudioSource.Settings> settingsSupplier;
-        if (audioMimeInfo.getCompatibleCamcorderProfile() != null) {
-            settingsSupplier = new AudioSourceSettingsCamcorderProfileResolver(audioSpec,
-                    audioMimeInfo.getCompatibleCamcorderProfile());
+        VideoValidatedEncoderProfilesProxy profiles = audioMimeInfo.getCompatibleEncoderProfiles();
+        if (profiles != null) {
+            AudioProfileProxy audioProfile = requireNonNull(profiles.getDefaultAudioProfile());
+            settingsSupplier = new AudioSourceSettingsAudioProfileResolver(audioSpec, audioProfile);
         } else {
             settingsSupplier = new AudioSourceSettingsDefaultResolver(audioSpec);
         }
@@ -151,10 +155,12 @@
             @NonNull Timebase inputTimebase, @NonNull AudioSource.Settings audioSourceSettings,
             @NonNull AudioSpec audioSpec) {
         Supplier<AudioEncoderConfig> configSupplier;
-        if (audioMimeInfo.getCompatibleCamcorderProfile() != null) {
-            configSupplier = new AudioEncoderConfigCamcorderProfileResolver(
+        VideoValidatedEncoderProfilesProxy profiles = audioMimeInfo.getCompatibleEncoderProfiles();
+        if (profiles != null) {
+            AudioProfileProxy audioProfile = requireNonNull(profiles.getDefaultAudioProfile());
+            configSupplier = new AudioEncoderConfigAudioProfileResolver(
                     audioMimeInfo.getMimeType(), audioMimeInfo.getProfile(), inputTimebase,
-                    audioSpec, audioSourceSettings, audioMimeInfo.getCompatibleCamcorderProfile());
+                    audioSpec, audioSourceSettings, audioProfile);
         } else {
             configSupplier = new AudioEncoderConfigDefaultResolver(audioMimeInfo.getMimeType(),
                     audioMimeInfo.getProfile(), inputTimebase, audioSpec, audioSourceSettings);
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioEncoderConfigCamcorderProfileResolver.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioEncoderConfigAudioProfileResolver.java
similarity index 76%
rename from camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioEncoderConfigCamcorderProfileResolver.java
rename to camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioEncoderConfigAudioProfileResolver.java
index 21d59a3..167050f 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioEncoderConfigCamcorderProfileResolver.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioEncoderConfigAudioProfileResolver.java
@@ -22,7 +22,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy.AudioProfileProxy;
 import androidx.camera.core.impl.Timebase;
 import androidx.camera.video.AudioSpec;
 import androidx.camera.video.internal.AudioSource;
@@ -32,23 +32,23 @@
 /**
  * An {@link AudioEncoderConfig} supplier that resolves requested encoder settings from an
  * {@link AudioSpec} for the given {@link AudioSource.Settings} using the provided
- * {@link CamcorderProfileProxy}.
+ * {@link AudioProfileProxy}.
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public final class AudioEncoderConfigCamcorderProfileResolver implements
+public final class AudioEncoderConfigAudioProfileResolver implements
         Supplier<AudioEncoderConfig> {
 
-    private static final String TAG = "AudioEncCmcrdrPrflRslvr";
+    private static final String TAG = "AudioEncAdPrflRslvr";
 
     private final String mMimeType;
     private final Timebase mInputTimebase;
     private final int mAudioProfile;
     private final AudioSpec mAudioSpec;
     private final AudioSource.Settings mAudioSourceSettings;
-    private final CamcorderProfileProxy mCamcorderProfile;
+    private final AudioProfileProxy mAudioProfileProxy;
 
     /**
-     * Constructor for an AudioEncoderConfigCamcorderProfileResolver.
+     * Constructor for an AudioEncoderConfigAudioProfileResolver.
      *
      * @param mimeType            The mime type for the audio encoder
      * @param audioProfile        The profile required for the audio encoder
@@ -56,30 +56,30 @@
      * @param audioSpec           The {@link AudioSpec} which defines the settings that should be
      *                            used with the audio encoder.
      * @param audioSourceSettings The settings used to configure the source of audio.
-     * @param camcorderProfile    The {@link CamcorderProfileProxy} used to resolve automatic and
+     * @param audioProfileProxy   The {@link AudioProfileProxy} used to resolve automatic and
      *                            range settings.
      */
-    public AudioEncoderConfigCamcorderProfileResolver(@NonNull String mimeType,
+    public AudioEncoderConfigAudioProfileResolver(@NonNull String mimeType,
             int audioProfile, @NonNull Timebase inputTimebase, @NonNull AudioSpec audioSpec,
             @NonNull AudioSource.Settings audioSourceSettings,
-            @NonNull CamcorderProfileProxy camcorderProfile) {
+            @NonNull AudioProfileProxy audioProfileProxy) {
         mMimeType = mimeType;
         mAudioProfile = audioProfile;
         mInputTimebase = inputTimebase;
         mAudioSpec = audioSpec;
         mAudioSourceSettings = audioSourceSettings;
-        mCamcorderProfile = camcorderProfile;
+        mAudioProfileProxy = audioProfileProxy;
     }
 
     @Override
     @NonNull
     public AudioEncoderConfig get() {
-        Logger.d(TAG, "Using resolved AUDIO bitrate from CamcorderProfile");
+        Logger.d(TAG, "Using resolved AUDIO bitrate from AudioProfile");
         Range<Integer> audioSpecBitrateRange = mAudioSpec.getBitrate();
         int resolvedBitrate = AudioConfigUtil.scaleAndClampBitrate(
-                mCamcorderProfile.getAudioBitRate(),
-                mAudioSourceSettings.getChannelCount(), mCamcorderProfile.getAudioChannels(),
-                mAudioSourceSettings.getSampleRate(), mCamcorderProfile.getAudioSampleRate(),
+                mAudioProfileProxy.getBitrate(),
+                mAudioSourceSettings.getChannelCount(), mAudioProfileProxy.getChannels(),
+                mAudioSourceSettings.getSampleRate(), mAudioProfileProxy.getSampleRate(),
                 audioSpecBitrateRange);
 
         return AudioEncoderConfig.builder()
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioSourceSettingsCamcorderProfileResolver.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioSourceSettingsAudioProfileResolver.java
similarity index 64%
rename from camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioSourceSettingsCamcorderProfileResolver.java
rename to camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioSourceSettingsAudioProfileResolver.java
index 8d6de0f..4b29d22 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioSourceSettingsCamcorderProfileResolver.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/AudioSourceSettingsAudioProfileResolver.java
@@ -21,36 +21,36 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy.AudioProfileProxy;
 import androidx.camera.video.AudioSpec;
 import androidx.camera.video.internal.AudioSource;
 import androidx.core.util.Supplier;
 
 /**
  * An {@link AudioSource.Settings} supplier that resolves requested source settings from an
- * {@link AudioSpec} using a {@link CamcorderProfileProxy}.
+ * {@link AudioSpec} using an {@link AudioProfileProxy}.
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public final class AudioSourceSettingsCamcorderProfileResolver implements
+public final class AudioSourceSettingsAudioProfileResolver implements
         Supplier<AudioSource.Settings> {
 
-    private static final String TAG = "AudioSrcCmcrdrPrflRslvr";
+    private static final String TAG = "AudioSrcAdPrflRslvr";
 
     private final AudioSpec mAudioSpec;
-    private final CamcorderProfileProxy mCamcorderProfile;
+    private final AudioProfileProxy mAudioProfile;
 
     /**
-     * Constructor for an AudioSourceSettingsCamcorderProfileResolver.
+     * Constructor for an AudioSourceSettingsAudioProfileResolver.
      *
-     * @param camcorderProfile The {@link CamcorderProfileProxy} used to resolve automatic and
-     *                         range settings.
-     * @param audioSpec        The {@link AudioSpec} which defines the settings that should be
-     *                         used with the audio source.
+     * @param audioProfile  The {@link AudioProfileProxy} used to resolve automatic and range
+     *                      settings.
+     * @param audioSpec     The {@link AudioSpec} which defines the settings that should be used
+     *                      with the audio source.
      */
-    public AudioSourceSettingsCamcorderProfileResolver(@NonNull AudioSpec audioSpec,
-            @NonNull CamcorderProfileProxy camcorderProfile) {
+    public AudioSourceSettingsAudioProfileResolver(@NonNull AudioSpec audioSpec,
+            @NonNull AudioProfileProxy audioProfile) {
         mAudioSpec = audioSpec;
-        mCamcorderProfile = camcorderProfile;
+        mAudioProfile = audioProfile;
     }
 
     @Override
@@ -67,25 +67,25 @@
         Range<Integer> audioSpecSampleRate = mAudioSpec.getSampleRate();
         int resolvedSampleRate;
         int resolvedChannelCount;
-        int camcorderProfileChannelCount = mCamcorderProfile.getAudioChannels();
+        int audioProfileChannelCount = mAudioProfile.getChannels();
         if (audioSpecChannelCount == AudioSpec.CHANNEL_COUNT_AUTO) {
-            resolvedChannelCount = camcorderProfileChannelCount;
-            Logger.d(TAG, "Resolved AUDIO channel count from CamcorderProfile: "
+            resolvedChannelCount = audioProfileChannelCount;
+            Logger.d(TAG, "Resolved AUDIO channel count from AudioProfile: "
                     + resolvedChannelCount);
         } else {
             resolvedChannelCount = audioSpecChannelCount;
-            Logger.d(TAG, "Media spec AUDIO channel count overrides CamcorderProfile "
-                    + "[CamcorderProfile channel count: " + camcorderProfileChannelCount
+            Logger.d(TAG, "Media spec AUDIO channel count overrides AudioProfile "
+                    + "[AudioProfile channel count: " + audioProfileChannelCount
                     + ", Resolved Channel Count: " + resolvedChannelCount + "]");
         }
 
-        int camcorderProfileAudioSampleRate = mCamcorderProfile.getAudioSampleRate();
+        int audioProfileSampleRate = mAudioProfile.getSampleRate();
         resolvedSampleRate = AudioConfigUtil.selectSampleRateOrNearestSupported(
                 audioSpecSampleRate, resolvedChannelCount, resolvedSourceFormat,
-                camcorderProfileAudioSampleRate);
+                audioProfileSampleRate);
         Logger.d(TAG, "Using resolved AUDIO sample rate or nearest supported from "
-                + "CamcorderProfile: " + resolvedSampleRate + "Hz. [CamcorderProfile sample rate: "
-                + camcorderProfileAudioSampleRate + "Hz]");
+                + "AudioProfile: " + resolvedSampleRate + "Hz. [AudioProfile sample rate: "
+                + audioProfileSampleRate + "Hz]");
 
         return AudioSource.Settings.builder()
                 .setAudioSource(resolvedAudioSource)
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/MimeInfo.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/MimeInfo.java
index 4fbbd71..983626b 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/MimeInfo.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/MimeInfo.java
@@ -19,7 +19,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.camera.video.internal.encoder.EncoderConfig;
 
 import com.google.auto.value.AutoValue;
@@ -29,8 +29,9 @@
  *
  * <p>The information included in this class can include the mime type, profile and any
  * compatible configuration types that can be used to resolve settings, such as
- * {@link androidx.camera.core.impl.CamcorderProfileProxy}.
+ * {@link VideoValidatedEncoderProfilesProxy}.
  */
+@SuppressWarnings("NullableProblems") // Problem from AutoValue generated class.
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 @AutoValue
 public abstract class MimeInfo {
@@ -49,12 +50,13 @@
     public abstract int getProfile();
 
     /**
-     * Returns compatible {@link CamcorderProfileProxy} that can be used to resolve settings.
+     * Returns compatible {@link VideoValidatedEncoderProfilesProxy} that can be used to resolve
+     * settings.
      *
-     * <p>If no camcorder profile is provided, returns {@code null}
+     * <p>If no EncoderProfiles is provided, returns {@code null}
      */
     @Nullable
-    public abstract CamcorderProfileProxy getCompatibleCamcorderProfile();
+    public abstract VideoValidatedEncoderProfilesProxy getCompatibleEncoderProfiles();
 
     /** Creates a builder for the given mime type */
     @NonNull
@@ -76,10 +78,10 @@
         @NonNull
         public abstract Builder setProfile(int profile);
 
-        /** Sets a compatible camcorder profile */
+        /** Sets a compatible EncoderProfiles */
         @NonNull
-        public abstract Builder setCompatibleCamcorderProfile(
-                @Nullable CamcorderProfileProxy camcorderProfile);
+        public abstract Builder setCompatibleEncoderProfiles(
+                @Nullable VideoValidatedEncoderProfilesProxy encoderProfiles);
 
         /** Builds the {@link androidx.camera.video.internal.config.MimeInfo}. */
         @NonNull
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoConfigUtil.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoConfigUtil.java
index 16416a7..8d3be191 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoConfigUtil.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoConfigUtil.java
@@ -24,10 +24,11 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy;
 import androidx.camera.core.impl.Timebase;
 import androidx.camera.video.MediaSpec;
 import androidx.camera.video.VideoSpec;
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy;
 import androidx.camera.video.internal.encoder.VideoEncoderConfig;
 import androidx.core.util.Supplier;
 
@@ -48,51 +49,51 @@
      * Resolves the video mime information into a {@link MimeInfo}.
      *
      * @param mediaSpec        the media spec to resolve the mime info.
-     * @param camcorderProfile the camcorder profile to resolve the mime info. It can be null if
-     *                         there is no relevant camcorder profile.
+     * @param encoderProfiles  the encoder profiles to resolve the mime info. It can be null if
+     *                         there is no relevant encoder profiles.
      * @return the video MimeInfo.
      */
     @NonNull
     public static MimeInfo resolveVideoMimeInfo(@NonNull MediaSpec mediaSpec,
-            @Nullable CamcorderProfileProxy camcorderProfile) {
+            @Nullable VideoValidatedEncoderProfilesProxy encoderProfiles) {
         String mediaSpecVideoMime = MediaSpec.outputFormatToVideoMime(mediaSpec.getOutputFormat());
         String resolvedVideoMime = mediaSpecVideoMime;
-        boolean camcorderProfileIsCompatible = false;
-        if (camcorderProfile != null) {
-            String camcorderProfileVideoMime = camcorderProfile.getVideoCodecMimeType();
-            // Use camcorder profile settings if the media spec's output format
-            // is set to auto or happens to match the CamcorderProfile's output format.
-            if (camcorderProfileVideoMime == null) {
-                Logger.d(TAG, "CamcorderProfile contains undefined VIDEO mime type so cannot be "
+        boolean encoderProfilesIsCompatible = false;
+        if (encoderProfiles != null) {
+            VideoProfileProxy videoProfile = encoderProfiles.getDefaultVideoProfile();
+            String encoderProfilesVideoMime = videoProfile.getMediaType();
+            // Use EncoderProfiles settings if the media spec's output format is set to auto or
+            // happens to match the EncoderProfiles' output format.
+            if (Objects.equals(encoderProfilesVideoMime, VideoProfileProxy.MEDIA_TYPE_NONE)) {
+                Logger.d(TAG, "EncoderProfiles contains undefined VIDEO mime type so cannot be "
                         + "used. May rely on fallback defaults to derive settings [chosen mime "
                         + "type: " + resolvedVideoMime + "]");
             } else if (mediaSpec.getOutputFormat() == MediaSpec.OUTPUT_FORMAT_AUTO) {
-                camcorderProfileIsCompatible = true;
-                resolvedVideoMime = camcorderProfileVideoMime;
-                Logger.d(TAG, "MediaSpec contains OUTPUT_FORMAT_AUTO. Using CamcorderProfile "
+                encoderProfilesIsCompatible = true;
+                resolvedVideoMime = encoderProfilesVideoMime;
+                Logger.d(TAG, "MediaSpec contains OUTPUT_FORMAT_AUTO. Using EncoderProfiles "
                         + "to derive VIDEO settings [mime type: " + resolvedVideoMime + "]");
-            } else if (Objects.equals(mediaSpecVideoMime, camcorderProfileVideoMime)) {
-                camcorderProfileIsCompatible = true;
-                resolvedVideoMime = camcorderProfileVideoMime;
-                Logger.d(TAG, "MediaSpec video mime matches CamcorderProfile. Using "
-                        + "CamcorderProfile to derive VIDEO settings [mime type: "
+            } else if (Objects.equals(mediaSpecVideoMime, encoderProfilesVideoMime)) {
+                encoderProfilesIsCompatible = true;
+                resolvedVideoMime = encoderProfilesVideoMime;
+                Logger.d(TAG, "MediaSpec video mime matches EncoderProfiles. Using "
+                        + "EncoderProfiles to derive VIDEO settings [mime type: "
                         + resolvedVideoMime + "]");
             } else {
-                Logger.d(TAG, "MediaSpec video mime does not match CamcorderProfile, so "
-                        + "CamcorderProfile settings cannot be used. May rely on fallback "
-                        + "defaults to derive VIDEO settings [CamcorderProfile mime type: "
-                        + camcorderProfileVideoMime + ", chosen mime type: "
+                Logger.d(TAG, "MediaSpec video mime does not match EncoderProfiles, so "
+                        + "EncoderProfiles settings cannot be used. May rely on fallback "
+                        + "defaults to derive VIDEO settings [EncoderProfiles mime type: "
+                        + encoderProfilesVideoMime + ", chosen mime type: "
                         + resolvedVideoMime + "]");
             }
         } else {
-            Logger.d(TAG,
-                    "No CamcorderProfile present. May rely on fallback defaults to derive VIDEO "
-                            + "settings [chosen mime type: " + resolvedVideoMime + "]");
+            Logger.d(TAG, "No EncoderProfiles present. May rely on fallback defaults to derive "
+                    + "VIDEO settings [chosen mime type: " + resolvedVideoMime + "]");
         }
 
         MimeInfo.Builder mimeInfoBuilder = MimeInfo.builder(resolvedVideoMime);
-        if (camcorderProfileIsCompatible) {
-            mimeInfoBuilder.setCompatibleCamcorderProfile(camcorderProfile);
+        if (encoderProfilesIsCompatible) {
+            mimeInfoBuilder.setCompatibleEncoderProfiles(encoderProfiles);
         }
 
         return mimeInfoBuilder.build();
@@ -113,11 +114,11 @@
             @NonNull Timebase inputTimebase, @NonNull VideoSpec videoSpec,
             @NonNull Size surfaceSize, @Nullable Range<Integer> expectedFrameRateRange) {
         Supplier<VideoEncoderConfig> configSupplier;
-        if (videoMimeInfo.getCompatibleCamcorderProfile() != null) {
-            configSupplier = new VideoEncoderConfigCamcorderProfileResolver(
+        VideoValidatedEncoderProfilesProxy profiles = videoMimeInfo.getCompatibleEncoderProfiles();
+        if (profiles != null) {
+            configSupplier = new VideoEncoderConfigVideoProfileResolver(
                     videoMimeInfo.getMimeType(), inputTimebase, videoSpec, surfaceSize,
-                    videoMimeInfo.getCompatibleCamcorderProfile(),
-                    expectedFrameRateRange);
+                    profiles.getDefaultVideoProfile(), expectedFrameRateRange);
         } else {
             configSupplier = new VideoEncoderConfigDefaultResolver(videoMimeInfo.getMimeType(),
                     inputTimebase, videoSpec, surfaceSize, expectedFrameRateRange);
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoEncoderConfigCamcorderProfileResolver.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoEncoderConfigVideoProfileResolver.java
similarity index 72%
rename from camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoEncoderConfigCamcorderProfileResolver.java
rename to camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoEncoderConfigVideoProfileResolver.java
index 5020129..0009f26 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoEncoderConfigCamcorderProfileResolver.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/config/VideoEncoderConfigVideoProfileResolver.java
@@ -23,7 +23,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.Logger;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy;
 import androidx.camera.core.impl.Timebase;
 import androidx.camera.video.VideoSpec;
 import androidx.camera.video.internal.encoder.VideoEncoderConfig;
@@ -32,49 +32,49 @@
 /**
  * A {@link VideoEncoderConfig} supplier that resolves requested encoder settings from a
  * {@link VideoSpec} for the given surface {@link Size} using the provided
- * {@link CamcorderProfileProxy}.
+ * {@link VideoProfileProxy}.
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
-public class VideoEncoderConfigCamcorderProfileResolver implements Supplier<VideoEncoderConfig> {
+public class VideoEncoderConfigVideoProfileResolver implements Supplier<VideoEncoderConfig> {
 
-    private static final String TAG = "VidEncCmcrdrPrflRslvr";
+    private static final String TAG = "VidEncVdPrflRslvr";
 
     private final String mMimeType;
     private final Timebase mInputTimebase;
     private final VideoSpec mVideoSpec;
     private final Size mSurfaceSize;
-    private final CamcorderProfileProxy mCamcorderProfile;
+    private final VideoProfileProxy mVideoProfile;
     @Nullable
     private final Range<Integer> mExpectedFrameRateRange;
 
     /**
-     * Constructor for a VideoEncoderConfigCamcorderProfileResolver.
+     * Constructor for a VideoEncoderConfigVideoProfileResolver.
      *
      * @param mimeType         The mime type for the video encoder
      * @param inputTimebase    The timebase of the input frame
      * @param videoSpec        The {@link VideoSpec} which defines the settings that should be
      *                         used with the video encoder.
      * @param surfaceSize      The size of the surface required by the camera for the video encoder.
-     * @param camcorderProfile The {@link CamcorderProfileProxy} used to resolve automatic and
-     *                         range settings.
+     * @param videoProfile     The {@link VideoProfileProxy} used to resolve automatic and range
+     *                         settings.
      * @param expectedFrameRateRange The expected source frame rate range. This should act as an
      *                               envelope for any frame rate calculated from {@code videoSpec
-     *                               } and {@code camcorderProfile} since the source should not
+     *                               } and {@code videoProfile} since the source should not
      *                               produce frames at a frame rate outside this range. If {@code
      *                               null}, then no information about the source frame rate is
      *                               available and it does not need to be used in calculations.
      */
-    public VideoEncoderConfigCamcorderProfileResolver(@NonNull String mimeType,
+    public VideoEncoderConfigVideoProfileResolver(@NonNull String mimeType,
             @NonNull Timebase inputTimebase,
             @NonNull VideoSpec videoSpec,
             @NonNull Size surfaceSize,
-            @NonNull CamcorderProfileProxy camcorderProfile,
+            @NonNull VideoProfileProxy videoProfile,
             @Nullable Range<Integer> expectedFrameRateRange) {
         mMimeType = mimeType;
         mInputTimebase = inputTimebase;
         mVideoSpec = videoSpec;
         mSurfaceSize = surfaceSize;
-        mCamcorderProfile = camcorderProfile;
+        mVideoProfile = videoProfile;
         mExpectedFrameRateRange = expectedFrameRateRange;
     }
 
@@ -85,12 +85,12 @@
         Logger.d(TAG, "Resolved VIDEO frame rate: " + resolvedFrameRate + "fps");
 
         Range<Integer> videoSpecBitrateRange = mVideoSpec.getBitrate();
-        Logger.d(TAG, "Using resolved VIDEO bitrate from CamcorderProfile");
+        Logger.d(TAG, "Using resolved VIDEO bitrate from EncoderProfiles");
         int resolvedBitrate = VideoConfigUtil.scaleAndClampBitrate(
-                mCamcorderProfile.getVideoBitRate(),
-                resolvedFrameRate, mCamcorderProfile.getVideoFrameRate(),
-                mSurfaceSize.getWidth(), mCamcorderProfile.getVideoFrameWidth(),
-                mSurfaceSize.getHeight(), mCamcorderProfile.getVideoFrameHeight(),
+                mVideoProfile.getBitrate(),
+                resolvedFrameRate, mVideoProfile.getFrameRate(),
+                mSurfaceSize.getWidth(), mVideoProfile.getWidth(),
+                mSurfaceSize.getHeight(), mVideoProfile.getHeight(),
                 videoSpecBitrateRange);
 
         return VideoEncoderConfig.builder()
@@ -104,15 +104,15 @@
 
     private int resolveFrameRate() {
         Range<Integer> videoSpecFrameRateRange = mVideoSpec.getFrameRate();
-        int camcorderProfileVideoFrameRate = mCamcorderProfile.getVideoFrameRate();
+        int videoProfileFrameRate = mVideoProfile.getFrameRate();
         Logger.d(TAG,
-                String.format("Frame rate from camcorder profile: %dfps. [Requested range: %s, "
-                        + "Expected operating range: %s]", camcorderProfileVideoFrameRate,
+                String.format("Frame rate from video profile: %dfps. [Requested range: %s, "
+                        + "Expected operating range: %s]", videoProfileFrameRate,
                         videoSpecFrameRateRange, mExpectedFrameRateRange));
 
         return VideoConfigUtil.resolveFrameRate(
                 /*preferredRange=*/ videoSpecFrameRateRange,
-                /*exactFrameRateHint=*/ camcorderProfileVideoFrameRate,
+                /*exactFrameRateHint=*/ videoProfileFrameRate,
                 /*strictOperatingFpsRange=*/mExpectedFrameRateRange);
     }
 }
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderConfig.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderConfig.java
index b3596b2..7d2f985 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderConfig.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderConfig.java
@@ -20,7 +20,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
-import androidx.camera.core.impl.CamcorderProfileProxy;
+import androidx.camera.core.impl.EncoderProfilesProxy;
 import androidx.camera.core.impl.Timebase;
 
 /**
@@ -32,7 +32,7 @@
 public interface EncoderConfig {
 
     /** Constant corresponding to no profile for the encoder */
-    int CODEC_PROFILE_NONE = CamcorderProfileProxy.CODEC_PROFILE_NONE;
+    int CODEC_PROFILE_NONE = EncoderProfilesProxy.CODEC_PROFILE_NONE;
 
     /**
      * The mime type of the encoder.
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/QualitySelectorTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/QualitySelectorTest.kt
index 8e7dd14..664c481 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/QualitySelectorTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/QualitySelectorTest.kt
@@ -16,16 +16,21 @@
 
 package androidx.camera.video
 
+import android.media.CamcorderProfile.QUALITY_1080P
+import android.media.CamcorderProfile.QUALITY_2160P
+import android.media.CamcorderProfile.QUALITY_480P
+import android.media.CamcorderProfile.QUALITY_720P
+import android.media.CamcorderProfile.QUALITY_HIGH
+import android.media.CamcorderProfile.QUALITY_LOW
 import android.os.Build
-import androidx.camera.testing.CamcorderProfileUtil
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_1080P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_2160P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_480P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_720P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_2160P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_720P
-import androidx.camera.testing.fakes.FakeCamcorderProfileProvider
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_2160P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_720P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_1080P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_2160P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_480P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_720P
 import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import androidx.camera.testing.fakes.FakeEncoderProfilesProvider
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertThrows
 import org.junit.Test
@@ -36,10 +41,6 @@
 
 private const val CAMERA_ID_0 = "0"
 private const val CAMERA_ID_1 = "1"
-private val CAMERA_0_PROFILE_HIGH = CamcorderProfileUtil.asHighQuality(PROFILE_2160P)
-private val CAMERA_0_PROFILE_LOW = CamcorderProfileUtil.asLowQuality(PROFILE_720P)
-private val CAMERA_1_PROFILE_HIGH = CamcorderProfileUtil.asHighQuality(PROFILE_1080P)
-private val CAMERA_1_PROFILE_LOW = CamcorderProfileUtil.asLowQuality(PROFILE_480P)
 
 @RunWith(RobolectricTestRunner::class)
 @DoNotInstrument
@@ -47,22 +48,20 @@
 class QualitySelectorTest {
 
     private val cameraInfo0 = FakeCameraInfoInternal(CAMERA_ID_0).apply {
-        camcorderProfileProvider = FakeCamcorderProfileProvider.Builder()
-            .addProfile(
-                CAMERA_0_PROFILE_HIGH,
-                PROFILE_2160P,
-                PROFILE_720P,
-                CAMERA_0_PROFILE_LOW
-            ).build()
+        encoderProfilesProvider = FakeEncoderProfilesProvider.Builder()
+            .add(QUALITY_HIGH, PROFILES_2160P)
+            .add(QUALITY_2160P, PROFILES_2160P)
+            .add(QUALITY_720P, PROFILES_720P)
+            .add(QUALITY_LOW, PROFILES_720P)
+            .build()
     }
     private val cameraInfo1 = FakeCameraInfoInternal(CAMERA_ID_1).apply {
-        camcorderProfileProvider = FakeCamcorderProfileProvider.Builder()
-            .addProfile(
-                CAMERA_1_PROFILE_HIGH,
-                PROFILE_1080P,
-                PROFILE_480P,
-                CAMERA_1_PROFILE_LOW
-            ).build()
+        encoderProfilesProvider = FakeEncoderProfilesProvider.Builder()
+            .add(QUALITY_HIGH, PROFILES_1080P)
+            .add(QUALITY_1080P, PROFILES_1080P)
+            .add(QUALITY_480P, PROFILES_480P)
+            .add(QUALITY_LOW, PROFILES_480P)
+            .build()
     }
 
     @Test
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/VideoCapabilitiesTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/VideoCapabilitiesTest.kt
index b77ffb6..8accf99 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/VideoCapabilitiesTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/VideoCapabilitiesTest.kt
@@ -16,13 +16,18 @@
 
 package androidx.camera.video
 
+import android.media.CamcorderProfile.QUALITY_2160P
+import android.media.CamcorderProfile.QUALITY_720P
+import android.media.CamcorderProfile.QUALITY_HIGH
+import android.media.CamcorderProfile.QUALITY_LOW
 import android.os.Build
 import android.util.Size
-import androidx.camera.testing.CamcorderProfileUtil
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_2160P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_720P
-import androidx.camera.testing.fakes.FakeCamcorderProfileProvider
+import androidx.camera.testing.EncoderProfilesUtil
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_2160P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_720P
 import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import androidx.camera.testing.fakes.FakeEncoderProfilesProvider
+import androidx.camera.video.internal.VideoValidatedEncoderProfilesProxy
 import androidx.core.util.component1
 import androidx.core.util.component2
 import com.google.common.truth.Truth.assertThat
@@ -32,22 +37,21 @@
 import org.robolectric.annotation.Config
 import org.robolectric.annotation.internal.DoNotInstrument
 
-private val PROFILE_HIGH = CamcorderProfileUtil.asHighQuality(PROFILE_2160P)
-private val PROFILE_LOW = CamcorderProfileUtil.asLowQuality(PROFILE_720P)
-
 @RunWith(RobolectricTestRunner::class)
 @DoNotInstrument
 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
 class VideoCapabilitiesTest {
 
     private val cameraInfo = FakeCameraInfoInternal().apply {
-        camcorderProfileProvider = FakeCamcorderProfileProvider.Builder()
-            .addProfile(PROFILE_HIGH) // UHD (2160p) per above definition
-            .addProfile(PROFILE_2160P) // UHD (2160p)
-            .addProfile(PROFILE_720P) // HD (720p)
-            .addProfile(PROFILE_LOW) // HD (720p) per above definition
+        encoderProfilesProvider = FakeEncoderProfilesProvider.Builder()
+            .add(QUALITY_HIGH, PROFILES_2160P) // UHD (2160p) per above definition
+            .add(QUALITY_2160P, PROFILES_2160P) // UHD (2160p)
+            .add(QUALITY_720P, PROFILES_720P) // HD (720p)
+            .add(QUALITY_LOW, PROFILES_720P) // HD (720p) per above definition
             .build()
     }
+    private val validatedProfiles2160p = VideoValidatedEncoderProfilesProxy.from(PROFILES_2160P)
+    private val validatedProfiles720p = VideoValidatedEncoderProfilesProxy.from(PROFILES_720P)
 
     @Test
     fun isQualitySupported() {
@@ -63,23 +67,19 @@
     @Test
     fun getProfile() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
-        assertThat(videoCapabilities.getProfile(Quality.HIGHEST))
-            .isEqualTo(PROFILE_2160P)
-        assertThat(videoCapabilities.getProfile(Quality.LOWEST))
-            .isEqualTo(PROFILE_720P)
-        assertThat(videoCapabilities.getProfile(Quality.UHD))
-            .isEqualTo(PROFILE_2160P)
-        assertThat(videoCapabilities.getProfile(Quality.FHD)).isNull()
-        assertThat(videoCapabilities.getProfile(Quality.HD))
-            .isEqualTo(PROFILE_720P)
-        assertThat(videoCapabilities.getProfile(Quality.SD)).isNull()
+        assertThat(videoCapabilities.getProfiles(Quality.HIGHEST)).isEqualTo(validatedProfiles2160p)
+        assertThat(videoCapabilities.getProfiles(Quality.LOWEST)).isEqualTo(validatedProfiles720p)
+        assertThat(videoCapabilities.getProfiles(Quality.UHD)).isEqualTo(validatedProfiles2160p)
+        assertThat(videoCapabilities.getProfiles(Quality.FHD)).isNull()
+        assertThat(videoCapabilities.getProfiles(Quality.HD)).isEqualTo(validatedProfiles720p)
+        assertThat(videoCapabilities.getProfiles(Quality.SD)).isNull()
     }
 
     @Test
     fun findHighestSupportedQuality_returnsHigherQuality() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
         // Create a size between 720p and 2160p
-        val (width720p, height720p) = CamcorderProfileUtil.RESOLUTION_720P
+        val (width720p, height720p) = EncoderProfilesUtil.RESOLUTION_720P
         val inBetweenSize = Size(width720p + 10, height720p)
 
         assertThat(videoCapabilities.findHighestSupportedQualityFor(inBetweenSize))
@@ -90,7 +90,7 @@
     fun findHighestSupportedQuality_returnsHighestQuality_whenAboveHighest() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
         // Create a size between greater than the max quality (UHD)
-        val (width2160p, height2160p) = CamcorderProfileUtil.RESOLUTION_2160P
+        val (width2160p, height2160p) = EncoderProfilesUtil.RESOLUTION_2160P
         val aboveHighestSize = Size(width2160p + 10, height2160p)
 
         assertThat(videoCapabilities.findHighestSupportedQualityFor(aboveHighestSize))
@@ -101,7 +101,7 @@
     fun findHighestSupportedQuality_returnsLowestQuality_whenBelowLowest() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
         // Create a size below the lowest quality (HD)
-        val (width720p, height720p) = CamcorderProfileUtil.RESOLUTION_720P
+        val (width720p, height720p) = EncoderProfilesUtil.RESOLUTION_720P
         val belowLowestSize = Size(width720p - 10, height720p)
 
         assertThat(videoCapabilities.findHighestSupportedQualityFor(belowLowestSize))
@@ -111,51 +111,51 @@
     @Test
     fun findHighestSupportedQuality_returnsExactQuality_whenExactSizeGiven() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
-        val exactSize720p = CamcorderProfileUtil.RESOLUTION_720P
+        val exactSize720p = EncoderProfilesUtil.RESOLUTION_720P
 
         assertThat(videoCapabilities.findHighestSupportedQualityFor(exactSize720p))
             .isEqualTo(Quality.HD)
     }
 
     @Test
-    fun findHighestSupportedCamcorderProfileFor_returnsHigherProfile() {
+    fun findHighestSupportedEncoderProfilesFor_returnsHigherProfile() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
         // Create a size between 720p and 2160p
-        val (width720p, height720p) = CamcorderProfileUtil.RESOLUTION_720P
+        val (width720p, height720p) = EncoderProfilesUtil.RESOLUTION_720P
         val inBetweenSize = Size(width720p + 10, height720p)
 
-        assertThat(videoCapabilities.findHighestSupportedCamcorderProfileFor(inBetweenSize))
-            .isEqualTo(PROFILE_2160P)
+        assertThat(videoCapabilities.findHighestSupportedEncoderProfilesFor(inBetweenSize))
+            .isEqualTo(validatedProfiles2160p)
     }
 
     @Test
-    fun findHighestSupportedCamcorderProfileFor_returnsHighestProfile_whenAboveHighest() {
+    fun findHighestSupportedEncoderProfilesFor_returnsHighestProfile_whenAboveHighest() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
         // Create a size between greater than the max quality (UHD)
-        val (width2160p, height2160p) = CamcorderProfileUtil.RESOLUTION_2160P
+        val (width2160p, height2160p) = EncoderProfilesUtil.RESOLUTION_2160P
         val aboveHighestSize = Size(width2160p + 10, height2160p)
 
-        assertThat(videoCapabilities.findHighestSupportedCamcorderProfileFor(aboveHighestSize))
-            .isEqualTo(PROFILE_2160P)
+        assertThat(videoCapabilities.findHighestSupportedEncoderProfilesFor(aboveHighestSize))
+            .isEqualTo(validatedProfiles2160p)
     }
 
     @Test
-    fun findHighestSupportedCamcorderProfileFor_returnsLowestProfile_whenBelowLowest() {
+    fun findHighestSupportedEncoderProfilesFor_returnsLowestProfile_whenBelowLowest() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
         // Create a size below the lowest quality (HD)
-        val (width720p, height720p) = CamcorderProfileUtil.RESOLUTION_720P
+        val (width720p, height720p) = EncoderProfilesUtil.RESOLUTION_720P
         val belowLowestSize = Size(width720p - 10, height720p)
 
-        assertThat(videoCapabilities.findHighestSupportedCamcorderProfileFor(belowLowestSize))
-            .isEqualTo(PROFILE_720P)
+        assertThat(videoCapabilities.findHighestSupportedEncoderProfilesFor(belowLowestSize))
+            .isEqualTo(validatedProfiles720p)
     }
 
     @Test
-    fun findHighestSupportedCamcorderProfileFor_returnsExactProfile_whenExactSizeGiven() {
+    fun findHighestSupportedEncoderProfilesFor_returnsExactProfile_whenExactSizeGiven() {
         val videoCapabilities = VideoCapabilities.from(cameraInfo)
-        val exactSize720p = CamcorderProfileUtil.RESOLUTION_720P
+        val exactSize720p = EncoderProfilesUtil.RESOLUTION_720P
 
-        assertThat(videoCapabilities.findHighestSupportedCamcorderProfileFor(exactSize720p))
-            .isEqualTo(PROFILE_720P)
+        assertThat(videoCapabilities.findHighestSupportedEncoderProfilesFor(exactSize720p))
+            .isEqualTo(validatedProfiles720p)
     }
 }
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
index dd46cef..d94802f 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
@@ -18,6 +18,12 @@
 
 import android.content.Context
 import android.graphics.Rect
+import android.media.CamcorderProfile.QUALITY_1080P
+import android.media.CamcorderProfile.QUALITY_2160P
+import android.media.CamcorderProfile.QUALITY_480P
+import android.media.CamcorderProfile.QUALITY_720P
+import android.media.CamcorderProfile.QUALITY_HIGH
+import android.media.CamcorderProfile.QUALITY_LOW
 import android.os.Build
 import android.os.Looper
 import android.util.Range
@@ -26,15 +32,16 @@
 import androidx.arch.core.util.Function
 import androidx.camera.core.AspectRatio.RATIO_16_9
 import androidx.camera.core.AspectRatio.RATIO_4_3
+import androidx.camera.core.CameraEffect
 import androidx.camera.core.CameraEffect.VIDEO_CAPTURE
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.CameraSelector.LENS_FACING_BACK
 import androidx.camera.core.CameraXConfig
 import androidx.camera.core.SurfaceRequest
 import androidx.camera.core.UseCase
-import androidx.camera.core.impl.CamcorderProfileProxy
 import androidx.camera.core.impl.CameraFactory
 import androidx.camera.core.impl.CameraInfoInternal
+import androidx.camera.core.impl.EncoderProfilesProxy
 import androidx.camera.core.impl.ImageFormatConstants
 import androidx.camera.core.impl.ImageOutputConfig
 import androidx.camera.core.impl.MutableStateObservable
@@ -47,27 +54,26 @@
 import androidx.camera.core.impl.utils.executor.CameraXExecutors.directExecutor
 import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
 import androidx.camera.core.internal.CameraUseCaseAdapter
-import androidx.camera.core.processing.SurfaceProcessorInternal
-import androidx.camera.testing.CamcorderProfileUtil
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_1080P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_2160P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_480P
-import androidx.camera.testing.CamcorderProfileUtil.PROFILE_720P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_1080P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_2160P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_480P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_720P
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_QHD
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_QVGA
-import androidx.camera.testing.CamcorderProfileUtil.RESOLUTION_VGA
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_1080P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_2160P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_480P
+import androidx.camera.testing.EncoderProfilesUtil.PROFILES_720P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_1080P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_2160P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_480P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_720P
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_QHD
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_QVGA
+import androidx.camera.testing.EncoderProfilesUtil.RESOLUTION_VGA
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.CameraXUtil
 import androidx.camera.testing.fakes.FakeAppConfig
-import androidx.camera.testing.fakes.FakeCamcorderProfileProvider
 import androidx.camera.testing.fakes.FakeCamera
 import androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager
 import androidx.camera.testing.fakes.FakeCameraFactory
 import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import androidx.camera.testing.fakes.FakeEncoderProfilesProvider
+import androidx.camera.testing.fakes.FakeSurfaceEffect
 import androidx.camera.testing.fakes.FakeSurfaceProcessorInternal
 import androidx.camera.video.Quality.FHD
 import androidx.camera.video.Quality.HD
@@ -100,11 +106,11 @@
 
 private val ANY_SIZE = Size(640, 480)
 private const val CAMERA_ID_0 = "0"
-private val CAMERA_0_PROFILES = arrayOf(
-    CamcorderProfileUtil.asHighQuality(PROFILE_2160P),
-    PROFILE_2160P,
-    PROFILE_720P,
-    CamcorderProfileUtil.asLowQuality(PROFILE_720P)
+private val CAMERA_0_PROFILES = mapOf(
+    QUALITY_HIGH to PROFILES_2160P,
+    QUALITY_2160P to PROFILES_2160P,
+    QUALITY_720P to PROFILES_720P,
+    QUALITY_LOW to PROFILES_720P,
 )
 
 @RunWith(RobolectricTestRunner::class)
@@ -145,8 +151,7 @@
     fun setNoCameraTransform_propagatesToCameraEdge() {
         // Arrange.
         setupCamera()
-        val processor = createFakeSurfaceProcessor()
-        val videoCapture = createVideoCapture(createVideoOutput(), processor = processor)
+        val videoCapture = createVideoCapture(createVideoOutput(), effect = createFakeEffect())
         // Act: set no transform and create pipeline.
         videoCapture.hasCameraTransform = false
         videoCapture.bindToCamera(camera, null, null)
@@ -163,8 +168,7 @@
         // Arrange.
         setupCamera()
         createCameraUseCaseAdapter()
-        val processor = createFakeSurfaceProcessor()
-        val videoCapture = createVideoCapture(createVideoOutput(), processor = processor)
+        val videoCapture = createVideoCapture(createVideoOutput(), effect = createFakeEffect())
         // Act.
         addAndAttachUseCases(videoCapture)
         // Assert.
@@ -199,7 +203,7 @@
     fun enableProcessor_sensorRotationIs0AndSetTargetRotation_sendCorrectResolution() {
         testSetRotationWillSendCorrectResolution(
             sensorRotation = 0,
-            processor = createFakeSurfaceProcessor()
+            effect = createFakeEffect()
         )
     }
 
@@ -207,7 +211,7 @@
     fun enableProcessor_sensorRotationIs90AndSetTargetRotation_sendCorrectResolution() {
         testSetRotationWillSendCorrectResolution(
             sensorRotation = 90,
-            processor = createFakeSurfaceProcessor()
+            effect = createFakeEffect()
         )
     }
 
@@ -215,7 +219,7 @@
     fun enableProcessor_sensorRotationIs180AndSetTargetRotation_sendCorrectResolution() {
         testSetRotationWillSendCorrectResolution(
             sensorRotation = 180,
-            processor = createFakeSurfaceProcessor()
+            effect = createFakeEffect()
         )
     }
 
@@ -223,7 +227,7 @@
     fun enableProcessor_sensorRotationIs270AndSetTargetRotation_sendCorrectResolution() {
         testSetRotationWillSendCorrectResolution(
             sensorRotation = 270,
-            processor = createFakeSurfaceProcessor()
+            effect = createFakeEffect()
         )
     }
 
@@ -233,7 +237,7 @@
         setupCamera()
         createCameraUseCaseAdapter()
         val videoCapture =
-            createVideoCapture(createVideoOutput(), processor = createFakeSurfaceProcessor())
+            createVideoCapture(createVideoOutput(), effect = createFakeEffect())
         addAndAttachUseCases(videoCapture)
         // Act: invalidate.
         videoCapture.surfaceRequest.invalidate()
@@ -247,8 +251,9 @@
         // Arrange: create videoCapture.
         setupCamera()
         createCameraUseCaseAdapter()
-        val processor = createFakeSurfaceProcessor()
-        val videoCapture = createVideoCapture(createVideoOutput(), processor = processor)
+        val processor = FakeSurfaceProcessorInternal(mainThreadExecutor())
+        val effect = createFakeEffect(processor = processor)
+        val videoCapture = createVideoCapture(createVideoOutput(), effect = effect)
         addAndAttachUseCases(videoCapture)
         // Act: invalidate.
         processor.surfaceRequest!!.invalidate()
@@ -277,7 +282,7 @@
         setupCamera()
         createCameraUseCaseAdapter()
         val videoCapture =
-            createVideoCapture(createVideoOutput(), processor = createFakeSurfaceProcessor())
+            createVideoCapture(createVideoOutput(), effect = createFakeEffect())
         addAndAttachUseCases(videoCapture)
         val surfaceRequest = videoCapture.surfaceRequest
         detachAndRemoveUseCases(videoCapture)
@@ -291,7 +296,7 @@
 
     private fun testSetRotationWillSendCorrectResolution(
         sensorRotation: Int = 0,
-        processor: SurfaceProcessorInternal? = null
+        effect: CameraEffect? = null
     ) {
         setupCamera(sensorRotation = sensorRotation)
         createCameraUseCaseAdapter()
@@ -313,7 +318,7 @@
                 surfaceRequestListener = { request, _ ->
                     surfaceRequest = request
                 })
-            val videoCapture = createVideoCapture(videoOutput, processor = processor)
+            val videoCapture = createVideoCapture(videoOutput, effect = effect)
             videoCapture.targetRotation = targetRotation
 
             // Act.
@@ -321,7 +326,7 @@
 
             // Assert.
             val resolution = CAMERA_0_QUALITY_SIZE[quality]!!
-            val expectedResolution = if (processor != null) {
+            val expectedResolution = if (effect != null) {
                 rotateSize(resolution, cameraInfo.getSensorRotationDegrees(targetRotation))
             } else {
                 resolution
@@ -347,7 +352,7 @@
     @Test
     fun addUseCasesWithSurfaceProcessor_cameraIsUptime_requestIsUptime() {
         testTimebase(
-            processor = createFakeSurfaceProcessor(),
+            effect = createFakeEffect(),
             cameraTimebase = Timebase.UPTIME,
             expectedTimebase = Timebase.UPTIME
         )
@@ -356,14 +361,14 @@
     @Test
     fun addUseCasesWithSurfaceProcessor_cameraIsRealtime_requestIsRealtime() {
         testTimebase(
-            processor = createFakeSurfaceProcessor(),
+            effect = createFakeEffect(),
             cameraTimebase = Timebase.REALTIME,
             expectedTimebase = Timebase.REALTIME
         )
     }
 
     private fun testTimebase(
-        processor: SurfaceProcessorInternal? = null,
+        effect: CameraEffect? = null,
         cameraTimebase: Timebase,
         expectedTimebase: Timebase
     ) {
@@ -375,7 +380,7 @@
         val videoOutput = createVideoOutput(surfaceRequestListener = { _, tb ->
             timebase = tb
         })
-        val videoCapture = createVideoCapture(videoOutput, processor = processor)
+        val videoCapture = createVideoCapture(videoOutput, effect = effect)
 
         // Act.
         addAndAttachUseCases(videoCapture)
@@ -433,13 +438,13 @@
     fun setQualitySelector_sameCustomOrderedResolutions() {
         // Arrange.
         setupCamera(
-            profiles = arrayOf(
-                CamcorderProfileUtil.asHighQuality(PROFILE_2160P),
-                PROFILE_2160P,
-                PROFILE_1080P,
-                PROFILE_720P,
-                PROFILE_480P,
-                CamcorderProfileUtil.asLowQuality(PROFILE_480P)
+            profiles = mapOf(
+                QUALITY_HIGH to PROFILES_2160P,
+                QUALITY_2160P to PROFILES_2160P,
+                QUALITY_1080P to PROFILES_1080P,
+                QUALITY_720P to PROFILES_720P,
+                QUALITY_480P to PROFILES_480P,
+                QUALITY_LOW to PROFILES_480P
             )
         )
         createCameraUseCaseAdapter()
@@ -475,13 +480,13 @@
     fun setAspectRatio_4by3() {
         // Arrange.
         setupCamera(
-            profiles = arrayOf(
-                CamcorderProfileUtil.asHighQuality(PROFILE_2160P),
-                PROFILE_2160P,
-                PROFILE_1080P,
-                PROFILE_720P,
-                PROFILE_480P,
-                CamcorderProfileUtil.asLowQuality(PROFILE_480P)
+            profiles = mapOf(
+                QUALITY_HIGH to PROFILES_2160P,
+                QUALITY_2160P to PROFILES_2160P,
+                QUALITY_1080P to PROFILES_1080P,
+                QUALITY_720P to PROFILES_720P,
+                QUALITY_480P to PROFILES_480P,
+                QUALITY_LOW to PROFILES_480P
             )
         )
         createCameraUseCaseAdapter()
@@ -515,13 +520,13 @@
     fun setAspectRatio_16by9() {
         // Arrange.
         setupCamera(
-            profiles = arrayOf(
-                CamcorderProfileUtil.asHighQuality(PROFILE_2160P),
-                PROFILE_2160P,
-                PROFILE_1080P,
-                PROFILE_720P,
-                PROFILE_480P,
-                CamcorderProfileUtil.asLowQuality(PROFILE_480P)
+            profiles = mapOf(
+                QUALITY_HIGH to PROFILES_2160P,
+                QUALITY_2160P to PROFILES_2160P,
+                QUALITY_1080P to PROFILES_1080P,
+                QUALITY_720P to PROFILES_720P,
+                QUALITY_480P to PROFILES_480P,
+                QUALITY_LOW to PROFILES_480P
             )
         )
         createCameraUseCaseAdapter()
@@ -561,7 +566,7 @@
         val videoOutput = createVideoOutput()
         val videoCapture = createVideoCapture(
             videoOutput,
-            processor = createFakeSurfaceProcessor(),
+            effect = createFakeEffect(),
             videoEncoderInfoFinder = {
                 createVideoEncoderInfo(widthAlignment = 16, heightAlignment = 16)
             })
@@ -597,7 +602,7 @@
     @Test
     fun noSupportedQuality_supportedResolutionsIsNotSet() {
         // Arrange.
-        setupCamera(profiles = emptyArray())
+        setupCamera(profiles = emptyMap())
         createCameraUseCaseAdapter()
 
         val videoOutput = createVideoOutput(
@@ -764,7 +769,8 @@
                 appSurfaceReadyToRelease = true
             }
         })
-        val videoCapture = createVideoCapture(videoOutput, processor = processor)
+        val effect = createFakeEffect(processor = processor)
+        val videoCapture = createVideoCapture(videoOutput, effect = effect)
 
         // Act: bind and provide Surface.
         addAndAttachUseCases(videoCapture)
@@ -898,7 +904,7 @@
         )
         val videoCapture = createVideoCapture(
             videoOutput,
-            processor = createFakeSurfaceProcessor(),
+            effect = createFakeEffect(),
             videoEncoderInfoFinder = { videoEncoderInfo }
         )
         videoCapture.setViewPortCropRect(cropRect)
@@ -997,7 +1003,7 @@
         hasCameraTransform: Boolean = true,
         targetRotation: Int? = null,
         targetResolution: Size? = null,
-        processor: SurfaceProcessorInternal? = null,
+        effect: CameraEffect? = null,
         videoEncoderInfoFinder: Function<VideoEncoderConfig, VideoEncoderInfo> =
             Function { createVideoEncoderInfo() },
     ): VideoCapture<VideoOutput> = VideoCapture.Builder(videoOutput)
@@ -1007,11 +1013,18 @@
             targetResolution?.let { setTargetResolution(it) }
             setVideoEncoderInfoFinder(videoEncoderInfoFinder)
         }.build().apply {
-            setProcessor(processor)
+            setEffect(effect)
             setHasCameraTransform(hasCameraTransform)
         }
 
-    private fun createFakeSurfaceProcessor() = FakeSurfaceProcessorInternal(mainThreadExecutor())
+    private fun createFakeEffect(
+        processor: FakeSurfaceProcessorInternal = FakeSurfaceProcessorInternal(
+            mainThreadExecutor()
+        )
+    ) =
+        FakeSurfaceEffect(
+            processor
+        )
 
     private fun setSuggestedStreamSpec(quality: Quality) {
         setSuggestedStreamSpec(StreamSpec.builder(CAMERA_0_QUALITY_SIZE[quality]!!).build())
@@ -1029,15 +1042,14 @@
         cameraId: String = CAMERA_ID_0,
         sensorRotation: Int = 0,
         supportedResolutions: Map<Int, List<Size>> = CAMERA_0_SUPPORTED_RESOLUTION_MAP,
-        vararg profiles: CamcorderProfileProxy = CAMERA_0_PROFILES,
+        profiles: Map<Int, EncoderProfilesProxy> = CAMERA_0_PROFILES,
         timebase: Timebase = Timebase.UPTIME,
     ) {
         cameraInfo = FakeCameraInfoInternal(cameraId, sensorRotation, LENS_FACING_BACK).apply {
             supportedResolutions.forEach { (format, resolutions) ->
                 setSupportedResolutions(format, resolutions)
             }
-            camcorderProfileProvider =
-                FakeCamcorderProfileProvider.Builder().addProfile(*profiles).build()
+            encoderProfilesProvider = FakeEncoderProfilesProvider.Builder().addAll(profiles).build()
             setTimebase(timebase)
         }
         camera = FakeCamera(cameraId, null, cameraInfo)
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/CameraControllerDeviceTest.kt b/camera/camera-view/src/androidTest/java/androidx/camera/view/CameraControllerDeviceTest.kt
index 9476da71e..e6266ed 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/CameraControllerDeviceTest.kt
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/CameraControllerDeviceTest.kt
@@ -35,7 +35,7 @@
 import androidx.camera.testing.CoreAppTestUtil
 import androidx.camera.testing.fakes.FakeActivity
 import androidx.camera.testing.fakes.FakeLifecycleOwner
-import androidx.camera.testing.fakes.FakePreviewEffect
+import androidx.camera.testing.fakes.FakeSurfaceEffect
 import androidx.camera.testing.fakes.FakeSurfaceProcessor
 import androidx.test.core.app.ActivityScenario
 import androidx.test.core.app.ApplicationProvider
@@ -126,11 +126,11 @@
         waitUtilPreviewViewIsReady(previewView!!)
 
         // Act: set the same effect twice, which is invalid.
-        val previewEffect1 = FakePreviewEffect(
+        val previewEffect1 = FakeSurfaceEffect(
             mainThreadExecutor(),
             FakeSurfaceProcessor(mainThreadExecutor())
         )
-        val previewEffect2 = FakePreviewEffect(
+        val previewEffect2 = FakeSurfaceEffect(
             mainThreadExecutor(),
             FakeSurfaceProcessor(mainThreadExecutor())
         )
@@ -159,19 +159,19 @@
         waitUtilPreviewViewIsReady(previewView!!)
 
         // Act: set an effect
-        val effect = FakePreviewEffect(
+        val effect = FakeSurfaceEffect(
             mainThreadExecutor(), FakeSurfaceProcessor(mainThreadExecutor())
         )
         instrumentation.runOnMainSync { controller!!.setEffects(setOf(effect)) }
 
         // Assert: preview has effect
-        assertThat(controller!!.mPreview.processor).isNotNull()
+        assertThat(controller!!.mPreview.effect).isNotNull()
 
         // Act: clear the effects
         instrumentation.runOnMainSync { controller!!.setEffects(null) }
 
         // Assert: preview no longer has the effect.
-        assertThat(controller!!.mPreview.processor).isNull()
+        assertThat(controller!!.mPreview.effect).isNull()
     }
 
     @Test
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt
index d41a8ce..1b89972 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt
@@ -174,11 +174,6 @@
 
     @Test
     fun setZoomRatio_largerThanMax_zoomUnmodified() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         assumeTrue(2.0f <= cameraInfo.zoomState.value!!.maxZoomRatio + DELTA)
         cameraControl.setZoomRatio(2.0f)[5, TimeUnit.SECONDS]
 
@@ -198,11 +193,6 @@
 
     @Test
     fun setZoomRatio_largerThanMax_OutOfRangeException() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         val maxZoomRatio = cameraInfo.zoomState.value!!.maxZoomRatio
         val result = cameraControl.setZoomRatio(maxZoomRatio + 1.0f)
 
@@ -211,11 +201,6 @@
 
     @Test
     fun setZoomRatio_smallerThanMin_zoomUnmodified() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         assumeTrue(2.0f <= cameraInfo.zoomState.value!!.maxZoomRatio + DELTA)
         cameraControl.setZoomRatio(2.0f)[5, TimeUnit.SECONDS]
 
@@ -235,11 +220,6 @@
 
     @Test
     fun setZoomRatio_smallerThanMin_OutOfRangeException() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         val minZoomRatio = cameraInfo.zoomState.value!!.minZoomRatio
         val result = cameraControl.setZoomRatio(minZoomRatio - 1.0f)
 
@@ -278,7 +258,7 @@
 
     @Test
     fun setZoomRatioBy2_0_cropRegionIsSetCorrectly() = runBlocking {
-        assumeTrue(getMaxDigitalZoom() != null && getMaxDigitalZoom()!! <= 2.0f + DELTA)
+        assumeTrue(getMaxDigitalZoom() != null && getMaxDigitalZoom()!! > 2.0f + DELTA)
 
         checkTestPreconditions(isAndroidRZoom = false)
 
@@ -342,11 +322,6 @@
 
     @Test
     fun setLinearZoomBy0_5_isHalfCropWidth() = runBlocking {
-        assumeFalse(
-            "b/267665704: CameraPipe linear zoom conversion to zoom ratio is not correct",
-            implName == "CameraPipeConfig"
-        )
-
         checkTestPreconditions(isAndroidRZoom = false)
 
         // crop region in percentage == 0 may be null, need to use sensor rect instead.
@@ -363,11 +338,6 @@
     @Test
     @SdkSuppress(minSdkVersion = 30)
     fun setLinearZoomBy0_5_androidRZoomRatioUpdatedCorrectly() = runBlocking {
-        assumeFalse(
-            "b/267665704: CameraPipe linear zoom conversion to zoom ratio is not correct",
-            implName == "CameraPipeConfig"
-        )
-
         checkTestPreconditions(isAndroidRZoom = true)
 
         val cropWidth = 10000f
@@ -388,11 +358,6 @@
 
     @Test
     fun setLinearZoom_cropWidthChangedLinearly() = runBlocking {
-        assumeFalse(
-            "b/267665704: CameraPipe linear zoom conversion to zoom ratio is not correct",
-            implName == "CameraPipeConfig"
-        )
-
         checkTestPreconditions(isAndroidRZoom = false)
 
         // crop region in percentage == 0 may be null, need to use sensor rect instead.
@@ -421,11 +386,6 @@
     @RequiresApi(Build.VERSION_CODES.R)
     @Test
     fun setLinearZoom_androidRZoomRatio_cropWidthChangedLinearly() = runBlocking {
-        assumeFalse(
-            "b/267665704: CameraPipe linear zoom conversion to zoom ratio is not correct",
-            implName == "CameraPipeConfig"
-        )
-
         checkTestPreconditions(isAndroidRZoom = true)
 
         val cropWidth = 10000f
@@ -456,11 +416,6 @@
 
     @Test
     fun setLinearZoom_largerThan1_zoomUnmodified() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         cameraControl.setLinearZoom(0.5f)[5, TimeUnit.SECONDS]
 
         /**
@@ -477,11 +432,6 @@
 
     @Test
     fun setLinearZoom_largerThan1_outOfRangeException() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         val result = cameraControl.setLinearZoom(1.1f)
 
         assertFutureThrowsIllegalArgumentException(result)
@@ -489,11 +439,6 @@
 
     @Test
     fun setLinearZoom_smallerThan0_zoomUnmodified() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         cameraControl.setLinearZoom(0.5f)[5, TimeUnit.SECONDS]
 
         /**
@@ -510,11 +455,6 @@
 
     @Test
     fun setLinearZoom_smallerThan0_outOfRangeException() = runBlocking {
-        assumeFalse(
-            "b/262225455: CameraPipe does not yet handle zoom value outside available range",
-            implName == "CameraPipeConfig"
-        )
-
         val result = cameraControl.setLinearZoom(-0.1f)
 
         assertFutureThrowsIllegalArgumentException(result)
@@ -527,7 +467,7 @@
 
     @Test
     fun getZoomRatioLiveData_observerIsCalledWhenZoomRatioIsSet() = runBlocking {
-        assumeTrue(getMaxDigitalZoom() != null && getMaxDigitalZoom()!! <= 2.0f + DELTA)
+        assumeTrue(getMaxDigitalZoom() != null && getMaxDigitalZoom()!! > 2.0f + DELTA)
 
         val latch1 = CountDownLatch(1)
         val latch2 = CountDownLatch(1)
@@ -579,11 +519,6 @@
 
     @Test
     fun getZoomPercentageLiveData_observerIsCalledWhenZoomPercentageIsSet() = runBlocking {
-        assumeFalse(
-            "b/267665704: CameraPipe linear zoom conversion to zoom ratio is not correct",
-            implName == "CameraPipeConfig"
-        )
-
         val latch1 = CountDownLatch(1)
         val latch2 = CountDownLatch(1)
         val latch3 = CountDownLatch(1)
@@ -611,7 +546,7 @@
 
     @Test
     fun getZoomPercentageLiveData_observerIsCalledWhenZoomRatioIsSet() = runBlocking {
-        assumeTrue(getMaxDigitalZoom() != null && getMaxDigitalZoom()!! <= 2.0f + DELTA)
+        assumeTrue(getMaxDigitalZoom() != null && getMaxDigitalZoom()!! > 2.0f + DELTA)
 
         val latch = CountDownLatch(3)
         withContext(Dispatchers.Main) {
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/camera2/CameraControlDeviceTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/camera2/CameraControlDeviceTest.kt
index 2e1cbf7..9b35256 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/camera2/CameraControlDeviceTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/camera2/CameraControlDeviceTest.kt
@@ -84,8 +84,7 @@
     @Before
     fun setUp() {
         val context = ApplicationProvider.getApplicationContext<Context>()
-        val cameraXConfig = Camera2Config.defaultConfig()
-        CameraXUtil.initialize(context, cameraXConfig).get()
+        CameraXUtil.initialize(context, cameraConfig).get()
         val cameraX = CameraXUtil.getOrCreateInstance(context, null).get()
         Assume.assumeTrue(
             CameraAvailabilityUtil.hasCamera(
@@ -202,7 +201,7 @@
 
     private fun <T> assertFutureCompletes(future: ListenableFuture<T>) {
         try {
-            future[5, TimeUnit.SECONDS]
+            future[10, TimeUnit.SECONDS]
         } catch (e: Exception) {
             Assert.fail("future fail:$e")
         }
diff --git a/car/app/app-samples/navigation/common/src/main/java/androidx/car/app/sample/navigation/common/nav/NavigationService.java b/car/app/app-samples/navigation/common/src/main/java/androidx/car/app/sample/navigation/common/nav/NavigationService.java
index 209122c..ea47c1f 100644
--- a/car/app/app-samples/navigation/common/src/main/java/androidx/car/app/sample/navigation/common/nav/NavigationService.java
+++ b/car/app/app-samples/navigation/common/src/main/java/androidx/car/app/sample/navigation/common/nav/NavigationService.java
@@ -18,6 +18,9 @@
 
 import static android.media.AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
 
+import static androidx.car.app.model.Action.FLAG_DEFAULT;
+import static androidx.car.app.model.Action.FLAG_PRIMARY;
+
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -40,9 +43,14 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RawRes;
+import androidx.car.app.AppManager;
 import androidx.car.app.CarContext;
 import androidx.car.app.CarToast;
+import androidx.car.app.model.Action;
+import androidx.car.app.model.Alert;
+import androidx.car.app.model.AlertCallback;
 import androidx.car.app.model.CarIcon;
+import androidx.car.app.model.CarText;
 import androidx.car.app.model.Distance;
 import androidx.car.app.navigation.NavigationManager;
 import androidx.car.app.navigation.NavigationManagerCallback;
@@ -59,6 +67,7 @@
 import androidx.car.app.sample.navigation.common.model.Script;
 import androidx.core.app.NotificationCompat;
 import androidx.core.app.NotificationManagerCompat;
+import androidx.core.graphics.drawable.IconCompat;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -256,6 +265,14 @@
                                                     getTrafficAccidentWarningNotification());
                                         }
 
+                                        // Send the alert every 7-step updates. This number is
+                                        // randomly chosen to distinguish from the HUN experience
+                                        // that is triggered every 10-step updates.
+                                        if (++mStepsSent % 7 == 0) {
+                                            mCarContext.getCarService(AppManager.class)
+                                                    .showAlert(createAlert());
+                                        }
+
                                         update(
                                                 /* isNavigating= */ true,
                                                 /* isRerouting= */ false,
@@ -581,4 +598,61 @@
         intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);
         return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
     }
+
+    @NonNull
+    private Alert createAlert() {
+        CarText title =
+                CarText.create(getString(R.string.navigation_alert_title));
+        CarIcon icon = new CarIcon.Builder(
+                IconCompat.createWithResource(this, R.drawable.ic_police)).build();
+
+        CarText yesTitle = CarText.create(getString(R.string.yes_action_title));
+        Action yesAction = new Action.Builder().setTitle(yesTitle).setOnClickListener(
+                () -> CarToast.makeText(
+                                mCarContext,
+                                getString(
+                                        R.string.yes_action_toast_msg),
+                                CarToast.LENGTH_SHORT)
+                        .show()).setFlags(FLAG_PRIMARY).build();
+
+        CarText noTitle = CarText.create(getString(R.string.no_action_title));
+        Action noAction = new Action.Builder().setTitle(noTitle).setOnClickListener(
+                () -> CarToast.makeText(
+                                mCarContext,
+                                getString(
+                                        R.string.no_action_toast_msg),
+                                CarToast.LENGTH_SHORT)
+                        .show()).setFlags(FLAG_DEFAULT).build();
+
+        return new Alert.Builder(/* alertId: */ 0, title, /* durationMillis: */ 10000)
+                .setIcon(icon)
+                .addAction(yesAction)
+                .addAction(noAction)
+                .setCallback(new AlertCallback() {
+                    @Override
+                    public void onCancel(int reason) {
+                        if (reason == AlertCallback.REASON_NOT_SUPPORTED) {
+                            mNotificationManager.notify(
+                                    NOTIFICATION_ID,
+                                    getPoliceReportNotification());
+                        }
+                    }
+
+                    @Override
+                    public void onDismiss() {
+                    }
+                }).build();
+    }
+
+    private Notification getPoliceReportNotification() {
+        return new NotificationCompat.Builder(this, CHANNEL_ID)
+                .setContentTitle(getString(R.string.navigation_alert_title))
+                .setSmallIcon(R.drawable.ic_police)
+                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_police))
+                .extend(
+                        new CarAppExtender.Builder()
+                                .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
+                                .build())
+                .build();
+    }
 }
diff --git a/car/app/app-samples/navigation/common/src/main/res/drawable/ic_police.xml b/car/app/app-samples/navigation/common/src/main/res/drawable/ic_police.xml
new file mode 100644
index 0000000..2ba337c2
--- /dev/null
+++ b/car/app/app-samples/navigation/common/src/main/res/drawable/ic_police.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+    <path android:fillColor="@android:color/white" android:pathData="M18.7,30.35 L24,26.45 29.15,30.35 27,24.05 32.3,20.25H25.9L24,14L22.1,20.25H15.7L20.9,24.05ZM24,43.95Q17,42.2 12.5,35.825Q8,29.45 8,21.85V9.95L24,3.95L40,9.95V21.85Q40,29.45 35.5,35.825Q31,42.2 24,43.95ZM24,40.85Q29.75,38.95 33.375,33.675Q37,28.4 37,21.85V12.05L24,7.15L11,12.05V21.85Q11,28.4 14.625,33.675Q18.25,38.95 24,40.85ZM24,24Q24,24 24,24Q24,24 24,24Q24,24 24,24Q24,24 24,24Z"/>
+</vector>
\ No newline at end of file
diff --git a/car/app/app-samples/navigation/common/src/main/res/values/strings.xml b/car/app/app-samples/navigation/common/src/main/res/values/strings.xml
index 9d27900..27a95a0 100644
--- a/car/app/app-samples/navigation/common/src/main/res/values/strings.xml
+++ b/car/app/app-samples/navigation/common/src/main/res/values/strings.xml
@@ -38,4 +38,13 @@
   <string name="settings_five_pref" translatable="false">setting_five</string>
   <string name="settings_six_label" translatable="false">Setting Six</string>
   <string name="settings_six_pref" translatable="false">setting_six</string>
+
+  <!-- Alert card -->
+  <string name="navigation_alert_title">Is police still there?</string>
+  <string name="yes_action_title">Yes</string>
+  <string name="no_action_title">No</string>
+  <string name="yes_action_toast_msg">Yes button pressed!</string>
+  <string name="no_action_toast_msg">No button pressed!</string>
+  <string name="alert_timeout_toast_msg">Alert is timed out!</string>
+  <string name="alert_not_supported">Alert is not supported, use HUN instead</string>
 </resources>
diff --git a/car/app/app/build.gradle b/car/app/app/build.gradle
index 5807cb4..74dff68 100644
--- a/car/app/app/build.gradle
+++ b/car/app/app/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.LibraryType
 import androidx.build.Release
+import androidx.build.checkapi.LibraryApiTaskConfig
 import androidx.build.metalava.MetalavaRunnerKt
 import androidx.build.uptodatedness.EnableCachingKt
 import androidx.build.Version
@@ -29,6 +30,8 @@
 import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 
+import static androidx.build.dependencies.DependenciesKt.*
+
 buildscript {
     dependencies {
         // This dependency means that tasks in this project might become out-of-date whenever
@@ -314,14 +317,12 @@
     @Input
     String carApiLevel = project.latestCarAppApiLevel
 
-    @OutputDirectory
-    final DirectoryProperty outputDir = project.objects.directoryProperty()
+    @OutputFile
+    File apiLevelFile
 
     @TaskAction
     def exec() {
-        def outputFile = new File(outputDir.get().asFile, "car-app-api.level")
-        outputFile.parentFile.mkdirs()
-        PrintWriter writer = new PrintWriter(outputFile)
+        PrintWriter writer = new PrintWriter(apiLevelFile)
         writer.println(carApiLevel)
         writer.close()
     }
@@ -379,6 +380,9 @@
     }
 }
 
+def RESOURCE_DIRECTORY = "generatedResources"
+def API_LEVEL_FILE_PATH = "$RESOURCE_DIRECTORY/car-app-api.level"
+
 LibraryExtension library = project.extensions.getByType(LibraryExtension.class)
 
 def getLibraryExtension() {
@@ -409,15 +413,24 @@
     return sourceCollection
 }
 
-def writeCarApiLevelFileTask = tasks.register("writeCarApiLevelFile", ApiLevelFileWriterTask) { task ->
-    task.outputDir.set(new File(project.buildDir, "generatedResources"))
-}
-
-AndroidSourceDirectorySet resources = library.sourceSets.getByName("main").resources
-resources.srcDir(writeCarApiLevelFileTask.map {it.outputDir })
-
 // afterEvaluate required to read extension properties
 afterEvaluate {
+    task writeCarApiLevelFile(type: ApiLevelFileWriterTask) {
+        File artifactName = new File(buildDir, API_LEVEL_FILE_PATH)
+        apiLevelFile = artifactName
+    }
+
+    AndroidSourceDirectorySet resources = library.sourceSets.getByName("main").resources
+    Set<File> resFiles = new HashSet<>()
+    resFiles.add(resources.srcDirs)
+    resFiles.add(new File(buildDir, RESOURCE_DIRECTORY))
+    resources.srcDirs(resFiles)
+    Set<String> includes = resources.includes
+    if (!includes.isEmpty()) {
+        includes.add("*.level")
+        resources.setIncludes(includes)
+    }
+
     FileCollection sourceCollection = getSourceCollection()
     FileCollection dependencyClasspath = getLibraryVariant().getCompileClasspath(null)
     FileCollection metalavaClasspath = MetalavaRunnerKt.getMetalavaClasspath(project)
diff --git a/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java b/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
index 439cb47..26429f7 100644
--- a/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
+++ b/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
@@ -143,7 +143,7 @@
         return mReceivedTimeEpochMillis;
     }
 
-    /** Returns a {@link boolean}, indicating whether the message has been read */
+    /** Returns a {@code boolean}, indicating whether the message has been read */
     public boolean isRead() {
         return mIsRead;
     }
@@ -175,7 +175,7 @@
             return this;
         }
 
-        /** Sets a {@link boolean}, indicating whether the message has been read */
+        /** Sets a {@code boolean}, indicating whether the message has been read */
         public @NonNull Builder setRead(boolean isRead) {
             mIsRead = isRead;
             return this;
diff --git a/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/AnimationCoreIssueRegistry.kt b/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/AnimationCoreIssueRegistry.kt
index 7dce8cf..02be66d 100644
--- a/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/AnimationCoreIssueRegistry.kt
+++ b/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/AnimationCoreIssueRegistry.kt
@@ -25,7 +25,7 @@
  */
 class AnimationCoreIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         TransitionDetector.UnusedTransitionTargetStateParameter,
diff --git a/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/AnimationIssueRegistry.kt b/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/AnimationIssueRegistry.kt
index 6cff075..3884e78 100644
--- a/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/AnimationIssueRegistry.kt
+++ b/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/AnimationIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class AnimationIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         CrossfadeDetector.UnusedCrossfadeTargetStateParameter
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
index 2e337c7..dc3c333 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
@@ -58,6 +58,7 @@
 import org.junit.runner.RunWith
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
 import org.junit.Assert.assertNotEquals
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
@@ -1486,6 +1487,7 @@
         assertEquals(Offset(root.width - size.toFloat(), 0f), childPosition.value)
     }
 
+    @SdkSuppress(maxSdkVersion = 32) // b/267699626
     @Test
     fun testWrapContentSize_rtl() = with(density) {
         val sizeDp = 200.toDp()
diff --git a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt
index 9d622a1..ef9e339 100644
--- a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt
+++ b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class FoundationIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         LazyLayoutStateReadInCompositionDetector.FrequentlyChangedStateReadInComposition,
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
index 2345c6e..7f51f44 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
@@ -102,6 +102,7 @@
 import androidx.test.espresso.action.Swipe
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlin.math.abs
@@ -2341,6 +2342,7 @@
         }
     }
 
+    @SdkSuppress(maxSdkVersion = 32) // b/268753157
     @Test
     fun offsetsScrollable_velocityCalculationShouldConsiderLocalPositions() {
         // arrange
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt
index 7784e47..0a5cc61 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt
@@ -2000,6 +2000,7 @@
             .assertStartPositionInRootIsEqualTo(0.dp)
     }
 
+    @SdkSuppress(maxSdkVersion = 32) // b/269178188
     @Test
     fun assertVelocityCalculationIsSimilar_witHistoricalValues() {
         // arrange
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
index 425ef13..ff4a3e3 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
@@ -35,6 +35,7 @@
 import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
 import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import kotlin.math.absoluteValue
 import kotlinx.coroutines.runBlocking
@@ -49,6 +50,7 @@
     config: ParamConfig
 ) : BasePagerTest(config = config) {
 
+    @SdkSuppress(maxSdkVersion = 32) // b/269171814
     @OptIn(ExperimentalFoundationApi::class)
     @Test
     fun nestedScrollContent_shouldNotPropagateUnconsumedFlings() {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
index 27a097a..8aa3c7a 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
@@ -31,6 +31,7 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performTouchInput
 import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.assertFalse
 import kotlinx.coroutines.Dispatchers
@@ -85,6 +86,7 @@
         }
     }
 
+    @SdkSuppress(maxSdkVersion = 32) // b/269176638
     @Test
     fun scrollToPage_usedOffset_shouldPlacePagesCorrectly() = runBlocking {
         // Arrange
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
index dbdf686..bde8eb6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
@@ -77,8 +77,7 @@
 ) {
     val overscrollEffect = ScrollableDefaults.overscrollEffect()
     val itemProvider = rememberLazyListItemProvider(state, content)
-    val semanticState =
-        rememberLazyListSemanticState(state, itemProvider, reverseLayout, isVertical)
+    val semanticState = rememberLazyListSemanticState(state, isVertical)
     val beyondBoundsInfo = remember { LazyListBeyondBoundsInfo() }
     val scope = rememberCoroutineScope()
     val placementAnimator = remember(state, isVertical) {
@@ -112,7 +111,8 @@
                 itemProvider = itemProvider,
                 state = semanticState,
                 orientation = orientation,
-                userScrollEnabled = userScrollEnabled
+                userScrollEnabled = userScrollEnabled,
+                reverseScrolling = reverseLayout
             )
             .clipScrollableContainer(orientation)
             .lazyListBeyondBoundsModifier(state, beyondBoundsInfo, reverseLayout, orientation)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
new file mode 100644
index 0000000..d84e816
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2022 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 androidx.compose.foundation.lazy
+
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.lazy.layout.BeyondBoundsState
+import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsModifierLocal
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalLayoutDirection
+
+/**
+ * This modifier is used to measure and place additional items when the lazyList receives a
+ * request to layout items beyond the visible bounds.
+ */
+@Suppress("ComposableModifierFactory")
+@Composable
+internal fun Modifier.lazyListBeyondBoundsModifier(
+    state: LazyListState,
+    beyondBoundsInfo: LazyListBeyondBoundsInfo,
+    reverseLayout: Boolean,
+    orientation: Orientation
+): Modifier {
+    val layoutDirection = LocalLayoutDirection.current
+    val beyondBoundsState = remember(state) { LazyListBeyondBoundsState(state) }
+    return this then remember(
+        beyondBoundsState,
+        beyondBoundsInfo,
+        reverseLayout,
+        layoutDirection,
+        orientation
+    ) {
+        LazyLayoutBeyondBoundsModifierLocal(
+            beyondBoundsState,
+            beyondBoundsInfo,
+            reverseLayout,
+            layoutDirection,
+            orientation
+        )
+    }
+}
+
+internal class LazyListBeyondBoundsState(val state: LazyListState) : BeyondBoundsState {
+    override fun remeasure() {
+        state.remeasurement?.forceRemeasure()
+    }
+
+    override val itemCount: Int
+        get() = state.layoutInfo.totalItemsCount
+    override val hasVisibleItems: Boolean
+        get() = state.layoutInfo.visibleItemsInfo.isNotEmpty()
+    override val firstVisibleIndex: Int
+        get() = state.firstVisibleItemIndex
+    override val lastVisibleIndex: Int
+        get() = state.layoutInfo.visibleItemsInfo.last().index
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListSemantics.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListSemantics.kt
new file mode 100644
index 0000000..5864b07
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListSemantics.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2023 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 androidx.compose.foundation.lazy
+
+import androidx.compose.foundation.lazy.layout.LazyLayoutSemanticState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+
+@Composable
+internal fun rememberLazyListSemanticState(
+    state: LazyListState,
+    isVertical: Boolean
+): LazyLayoutSemanticState {
+    return remember(state, isVertical) {
+        LazyLayoutSemanticState(state = state, isVertical = isVertical)
+    }
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazySemantics.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazySemantics.kt
deleted file mode 100644
index 96bccd6..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazySemantics.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.foundation.lazy
-
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.gestures.animateScrollBy
-import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
-import androidx.compose.foundation.lazy.layout.LazyLayoutSemanticState
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
-import androidx.compose.ui.semantics.CollectionInfo
-import androidx.compose.ui.semantics.ScrollAxisRange
-
-@OptIn(ExperimentalFoundationApi::class)
-@Composable
-internal fun rememberLazyListSemanticState(
-    state: LazyListState,
-    itemProvider: LazyLayoutItemProvider,
-    reverseScrolling: Boolean,
-    isVertical: Boolean
-): LazyLayoutSemanticState =
-    remember(state, itemProvider, reverseScrolling, isVertical) {
-        object : LazyLayoutSemanticState {
-            override fun scrollAxisRange(): ScrollAxisRange =
-                ScrollAxisRange(
-                    value = {
-                        // This is a simple way of representing the current position without
-                        // needing any lazy items to be measured. It's good enough so far, because
-                        // screen-readers care mostly about whether scroll position changed or not
-                        // rather than the actual offset in pixels.
-                        state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset / 100_000f
-                    },
-                    maxValue = {
-                        if (state.canScrollForward) {
-                            // If we can scroll further, we don't know the end yet,
-                            // but it's upper bounded by #items + 1
-                            itemProvider.itemCount + 1f
-                        } else {
-                            // If we can't scroll further, the current value is the max
-                            state.firstVisibleItemIndex +
-                                state.firstVisibleItemScrollOffset / 100_000f
-                        }
-                    },
-                    reverseScrolling = reverseScrolling
-                )
-
-            override suspend fun animateScrollBy(delta: Float) {
-                state.animateScrollBy(delta)
-            }
-
-            override suspend fun scrollToItem(index: Int) {
-                state.scrollToItem(index)
-            }
-
-            override fun collectionInfo(): CollectionInfo =
-                if (isVertical) {
-                    CollectionInfo(rowCount = -1, columnCount = 1)
-                } else {
-                    CollectionInfo(rowCount = 1, columnCount = -1)
-                }
-        }
-    }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
index b6787df..502161e 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
@@ -77,7 +77,7 @@
 
     val itemProvider = rememberLazyGridItemProvider(state, content)
 
-    val semanticState = rememberLazyGridSemanticState(state, itemProvider, reverseLayout)
+    val semanticState = rememberLazyGridSemanticState(state, reverseLayout)
 
     val scope = rememberCoroutineScope()
     val placementAnimator = remember(state, isVertical) {
@@ -110,7 +110,8 @@
                 itemProvider = itemProvider,
                 state = semanticState,
                 orientation = orientation,
-                userScrollEnabled = userScrollEnabled
+                userScrollEnabled = userScrollEnabled,
+                reverseScrolling = reverseLayout
             )
             .clipScrollableContainer(orientation)
             .overscroll(overscrollEffect)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazySemantics.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazySemantics.kt
index 2e6d308..1f9c542 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazySemantics.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazySemantics.kt
@@ -18,45 +18,23 @@
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.animateScrollBy
-import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
 import androidx.compose.foundation.lazy.layout.LazyLayoutSemanticState
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.ui.semantics.CollectionInfo
-import androidx.compose.ui.semantics.ScrollAxisRange
 
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 internal fun rememberLazyGridSemanticState(
     state: LazyGridState,
-    itemProvider: LazyLayoutItemProvider,
     reverseScrolling: Boolean
 ): LazyLayoutSemanticState =
-    remember(state, itemProvider, reverseScrolling) {
+    remember(state, reverseScrolling) {
         object : LazyLayoutSemanticState {
-            override fun scrollAxisRange(): ScrollAxisRange =
-                ScrollAxisRange(
-                    value = {
-                        // This is a simple way of representing the current position without
-                        // needing any lazy items to be measured. It's good enough so far, because
-                        // screen-readers care mostly about whether scroll position changed or not
-                        // rather than the actual offset in pixels.
-                        state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset / 100_000f
-                    },
-                    maxValue = {
-                        if (state.canScrollForward) {
-                            // If we can scroll further, we don't know the end yet,
-                            // but it's upper bounded by #items + 1
-                            itemProvider.itemCount + 1f
-                        } else {
-                            // If we can't scroll further, the current value is the max
-                            state.firstVisibleItemIndex +
-                                state.firstVisibleItemScrollOffset / 100_000f
-                        }
-                    },
-                    reverseScrolling = reverseScrolling
-                )
+            override val currentPosition: Float
+                get() = state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset / 100_000f
+            override val canScrollForward: Boolean
+                get() = state.canScrollForward
 
             override suspend fun animateScrollBy(delta: Float) {
                 state.animateScrollBy(delta)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/BeyondBoundsState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/BeyondBoundsState.kt
new file mode 100644
index 0000000..3407f2c
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/BeyondBoundsState.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 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 androidx.compose.foundation.lazy.layout
+
+internal interface BeyondBoundsState {
+
+    fun remeasure()
+
+    val itemCount: Int
+
+    val hasVisibleItems: Boolean
+
+    val firstVisibleIndex: Int
+
+    val lastVisibleIndex: Int
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyBeyondBoundsModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
similarity index 79%
rename from compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyBeyondBoundsModifier.kt
rename to compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
index df49b4e..939fe3e 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyBeyondBoundsModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2022 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,13 +14,11 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.lazy
+package androidx.compose.foundation.lazy.layout
 
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.lazy.LazyListBeyondBoundsInfo
 import androidx.compose.foundation.lazy.LazyListBeyondBoundsInfo.Interval
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.BeyondBoundsLayout
 import androidx.compose.ui.layout.BeyondBoundsLayout.BeyondBoundsScope
 import androidx.compose.ui.layout.BeyondBoundsLayout.LayoutDirection.Companion.Above
@@ -32,43 +30,12 @@
 import androidx.compose.ui.layout.ModifierLocalBeyondBoundsLayout
 import androidx.compose.ui.modifier.ModifierLocalProvider
 import androidx.compose.ui.modifier.ProvidableModifierLocal
-import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.LayoutDirection.Ltr
 import androidx.compose.ui.unit.LayoutDirection.Rtl
 
-/**
- * This modifier is used to measure and place additional items when the lazyList receives a
- * request to layout items beyond the visible bounds.
- */
-@Suppress("ComposableModifierFactory")
-@Composable
-internal fun Modifier.lazyListBeyondBoundsModifier(
-    state: LazyListState,
-    beyondBoundsInfo: LazyListBeyondBoundsInfo,
-    reverseLayout: Boolean,
-    orientation: Orientation
-): Modifier {
-    val layoutDirection = LocalLayoutDirection.current
-    return this then remember(
-        state,
-        beyondBoundsInfo,
-        reverseLayout,
-        layoutDirection,
-        orientation
-    ) {
-        LazyListBeyondBoundsModifierLocal(
-            state,
-            beyondBoundsInfo,
-            reverseLayout,
-            layoutDirection,
-            orientation
-        )
-    }
-}
-
-private class LazyListBeyondBoundsModifierLocal(
-    private val state: LazyListState,
+internal class LazyLayoutBeyondBoundsModifierLocal(
+    private val state: BeyondBoundsState,
     private val beyondBoundsInfo: LazyListBeyondBoundsInfo,
     private val reverseLayout: Boolean,
     private val layoutDirection: LayoutDirection,
@@ -90,14 +57,14 @@
     ): T? {
         // If the lazy list is empty, or if it does not have any visible items (Which implies
         // that there isn't space to add a single item), we don't attempt to layout any more items.
-        if (state.layoutInfo.totalItemsCount <= 0 || state.layoutInfo.visibleItemsInfo.isEmpty()) {
+        if (state.itemCount <= 0 || !state.hasVisibleItems) {
             return block.invoke(emptyBeyondBoundsScope)
         }
 
         // We use a new interval each time because this function is re-entrant.
         var interval = beyondBoundsInfo.addInterval(
-            state.firstVisibleItemIndex,
-            state.layoutInfo.visibleItemsInfo.last().index
+            state.firstVisibleIndex,
+            state.lastVisibleIndex
         )
 
         var found: T? = null
@@ -107,7 +74,7 @@
             interval = addNextInterval(interval, direction).also {
                 beyondBoundsInfo.removeInterval(interval)
             }
-            state.remeasurement?.forceRemeasure()
+            state.remeasure()
 
             // When we invoke this block, the beyond bounds items are present.
             found = block.invoke(
@@ -120,7 +87,7 @@
 
         // Dispose the items that are beyond the visible bounds.
         beyondBoundsInfo.removeInterval(interval)
-        state.remeasurement?.forceRemeasure()
+        state.remeasure()
         return found
     }
 
@@ -150,7 +117,7 @@
 
     private fun Interval.hasMoreContent(direction: BeyondBoundsLayout.LayoutDirection): Boolean {
         fun hasMoreItemsBefore() = start > 0
-        fun hasMoreItemsAfter() = end < state.layoutInfo.totalItemsCount - 1
+        fun hasMoreItemsAfter() = end < state.itemCount - 1
         if (direction.isOppositeToOrientation()) return false
         return when (direction) {
             Before -> hasMoreItemsBefore()
@@ -181,4 +148,4 @@
 
 private fun unsupportedDirection(): Nothing = error(
     "Lazy list does not support beyond bounds layout for the specified direction"
-)
+)
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemanticState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemanticState.kt
new file mode 100644
index 0000000..c4e0403
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemanticState.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 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 androidx.compose.foundation.lazy.layout
+
+import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.lazy.LazyListState
+import androidx.compose.ui.semantics.CollectionInfo
+
+internal fun LazyLayoutSemanticState(
+    state: LazyListState,
+    isVertical: Boolean
+): LazyLayoutSemanticState = object : LazyLayoutSemanticState {
+
+    override val currentPosition: Float
+        get() = state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset / 100_000f
+    override val canScrollForward: Boolean
+        get() = state.canScrollForward
+
+    override suspend fun animateScrollBy(delta: Float) {
+        state.animateScrollBy(delta)
+    }
+
+    override suspend fun scrollToItem(index: Int) {
+        state.scrollToItem(index)
+    }
+
+    override fun collectionInfo(): CollectionInfo =
+        if (isVertical) {
+            CollectionInfo(rowCount = -1, columnCount = 1)
+        } else {
+            CollectionInfo(rowCount = 1, columnCount = -1)
+        }
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt
index c5e286b..1e56270 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt
@@ -41,7 +41,8 @@
     itemProvider: LazyLayoutItemProvider,
     state: LazyLayoutSemanticState,
     orientation: Orientation,
-    userScrollEnabled: Boolean
+    userScrollEnabled: Boolean,
+    reverseScrolling: Boolean
 ): Modifier {
     val coroutineScope = rememberCoroutineScope()
     return this.then(
@@ -63,7 +64,26 @@
                 result
             }
 
-            val accessibilityScrollState = state.scrollAxisRange()
+            val accessibilityScrollState = ScrollAxisRange(
+                value = {
+                    // This is a simple way of representing the current position without
+                    // needing any lazy items to be measured. It's good enough so far, because
+                    // screen-readers care mostly about whether scroll position changed or not
+                    // rather than the actual offset in pixels.
+                    state.currentPosition
+                },
+                maxValue = {
+                    if (state.canScrollForward) {
+                        // If we can scroll further, we don't know the end yet,
+                        // but it's upper bounded by #items + 1
+                        itemProvider.itemCount + 1f
+                    } else {
+                        // If we can't scroll further, the current value is the max
+                        state.currentPosition
+                    }
+                },
+                reverseScrolling = reverseScrolling
+            )
 
             val scrollByAction: ((x: Float, y: Float) -> Boolean)? = if (userScrollEnabled) {
                 { x, y ->
@@ -123,7 +143,8 @@
 }
 
 internal interface LazyLayoutSemanticState {
-    fun scrollAxisRange(): ScrollAxisRange
+    val currentPosition: Float
+    val canScrollForward: Boolean
     fun collectionInfo(): CollectionInfo
     suspend fun animateScrollBy(delta: Float)
     suspend fun scrollToItem(index: Int)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt
index 2630e7d..9525489 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt
@@ -74,7 +74,7 @@
         horizontalArrangement,
         slotSizesSums
     )
-    val semanticState = rememberLazyStaggeredGridSemanticState(state, itemProvider, reverseLayout)
+    val semanticState = rememberLazyStaggeredGridSemanticState(state, reverseLayout)
 
     ScrollPositionUpdater(itemProvider, state)
 
@@ -100,7 +100,8 @@
                 itemProvider = itemProvider,
                 state = semanticState,
                 orientation = orientation,
-                userScrollEnabled = userScrollEnabled
+                userScrollEnabled = userScrollEnabled,
+                reverseScrolling = reverseLayout
             ),
         prefetchState = state.prefetchState,
         itemProvider = itemProvider,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSemantics.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSemantics.kt
index e9b7ca7..459702f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSemantics.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSemantics.kt
@@ -18,44 +18,23 @@
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.animateScrollBy
-import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
 import androidx.compose.foundation.lazy.layout.LazyLayoutSemanticState
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.semantics.CollectionInfo
-import androidx.compose.ui.semantics.ScrollAxisRange
 
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 internal fun rememberLazyStaggeredGridSemanticState(
     state: LazyStaggeredGridState,
-    itemProvider: LazyLayoutItemProvider,
     reverseScrolling: Boolean
 ): LazyLayoutSemanticState =
-    remember(state, itemProvider, reverseScrolling) {
+    remember(state, reverseScrolling) {
         object : LazyLayoutSemanticState {
-            override fun scrollAxisRange(): ScrollAxisRange =
-                ScrollAxisRange(
-                    value = {
-                        // This is a simple way of representing the current position without
-                        // needing any lazy items to be measured. It's good enough so far, because
-                        // screen-readers care mostly about whether scroll position changed or not
-                        // rather than the actual offset in pixels.
-                        state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset / 100_000f
-                    },
-                    maxValue = {
-                        if (state.canScrollForward) {
-                            // If we can scroll further, we don't know the end yet,
-                            // but it's upper bounded by #items + 1
-                            itemProvider.itemCount + 1f
-                        } else {
-                            // If we can't scroll further, the current value is the max
-                            state.firstVisibleItemIndex +
-                                state.firstVisibleItemScrollOffset / 100_000f
-                        }
-                    },
-                    reverseScrolling = reverseScrolling
-                )
+            override val currentPosition: Float
+                get() = state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset / 100_000f
+            override val canScrollForward: Boolean
+                get() = state.canScrollForward
 
             override suspend fun animateScrollBy(delta: Float) {
                 state.animateScrollBy(delta)
diff --git a/compose/lint/internal-lint-checks/src/main/java/androidx/compose/lint/ComposeIssueRegistry.kt b/compose/lint/internal-lint-checks/src/main/java/androidx/compose/lint/ComposeIssueRegistry.kt
index 29098a8..6dd41f2 100644
--- a/compose/lint/internal-lint-checks/src/main/java/androidx/compose/lint/ComposeIssueRegistry.kt
+++ b/compose/lint/internal-lint-checks/src/main/java/androidx/compose/lint/ComposeIssueRegistry.kt
@@ -25,7 +25,7 @@
 
 class ComposeIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues get(): List<Issue> {
         return listOf(
             ListIteratorDetector.ISSUE,
diff --git a/compose/material/material-lint/src/main/java/androidx/compose/material/lint/MaterialIssueRegistry.kt b/compose/material/material-lint/src/main/java/androidx/compose/material/lint/MaterialIssueRegistry.kt
index f7b3b43..75ce926 100644
--- a/compose/material/material-lint/src/main/java/androidx/compose/material/lint/MaterialIssueRegistry.kt
+++ b/compose/material/material-lint/src/main/java/androidx/compose/material/lint/MaterialIssueRegistry.kt
@@ -25,7 +25,7 @@
  */
 class MaterialIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ColorsDetector.ConflictingOnColor,
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
index 3c60de2..cc683a3 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
@@ -107,7 +107,7 @@
             }
         }
 
-        rule.waitUntil { parent.children.all { it.isCompleted } }
+        rule.waitUntil(timeoutMillis = 5_000) { parent.children.all { it.isCompleted } }
         Truth.assertThat(resultedInvocation).isEqualTo("0123456789")
     }
 
@@ -139,7 +139,8 @@
             Truth.assertThat(result).isEqualTo(SnackbarResult.Dismissed)
         }
 
-        rule.waitUntil(timeoutMillis = 7_000) { job2.isCompleted }
+        rule.mainClock.advanceTimeBy(5_000)
+        rule.waitUntil { job2.isCompleted }
     }
 
     @Test
diff --git a/compose/material3/material3-lint/src/main/java/androidx/compose/material3/lint/Material3IssueRegistry.kt b/compose/material3/material3-lint/src/main/java/androidx/compose/material3/lint/Material3IssueRegistry.kt
index 6887bda..8529446 100644
--- a/compose/material3/material3-lint/src/main/java/androidx/compose/material3/lint/Material3IssueRegistry.kt
+++ b/compose/material3/material3-lint/src/main/java/androidx/compose/material3/lint/Material3IssueRegistry.kt
@@ -25,7 +25,7 @@
  */
 class Material3IssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ScaffoldPaddingDetector.UnusedMaterial3ScaffoldPaddingParameter
diff --git a/compose/material3/material3/api/public_plus_experimental_current.txt b/compose/material3/material3/api/public_plus_experimental_current.txt
index e1b2628..22b8041 100644
--- a/compose/material3/material3/api/public_plus_experimental_current.txt
+++ b/compose/material3/material3/api/public_plus_experimental_current.txt
@@ -340,7 +340,7 @@
   }
 
   public final class DateRangePickerKt {
-    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DateRangePicker(androidx.compose.material3.DateRangePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> dateValidator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit> headline, optional androidx.compose.material3.DatePickerColors colors);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DateRangePicker(androidx.compose.material3.DateRangePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> dateValidator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit> headline, optional boolean showModeToggle, optional androidx.compose.material3.DatePickerColors colors);
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DateRangePickerState rememberDateRangePickerState(optional Long? initialSelectedStartDateMillis, optional Long? initialSelectedEndDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode);
   }
 
diff --git a/compose/material3/material3/samples/build.gradle b/compose/material3/material3/samples/build.gradle
index ae744c3..b2707cf 100644
--- a/compose/material3/material3/samples/build.gradle
+++ b/compose/material3/material3/samples/build.gradle
@@ -41,8 +41,6 @@
     implementation("androidx.compose.ui:ui-text:1.2.1")
     implementation("androidx.savedstate:savedstate-ktx:1.2.0")
     implementation(project(":compose:ui:ui-tooling-preview"))
-    implementation(project(":lifecycle:lifecycle-runtime-ktx"))
-    implementation(project(":lifecycle:lifecycle-common-java8"))
 
     debugImplementation(project(":compose:ui:ui-tooling"))
 }
@@ -57,3 +55,11 @@
 android {
     namespace "androidx.compose.material3.samples"
 }
+
+// Workaround for https://github.com/gradle/gradle/issues/19882
+configurations.all {
+    resolutionStrategy.dependencySubstitution {
+        substitute(module("androidx.lifecycle:lifecycle-common-java8:")).
+                using project(":lifecycle:lifecycle-common-java8")
+    }
+}
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/DatePickerSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/DatePickerSamples.kt
index 66f3939..3888e13 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/DatePickerSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/DatePickerSamples.kt
@@ -30,7 +30,6 @@
 import androidx.compose.material3.DatePickerDialog
 import androidx.compose.material3.DateRangePicker
 import androidx.compose.material3.DisplayMode
-import androidx.compose.material3.Divider
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.SnackbarHost
@@ -48,6 +47,7 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.zIndex
 import java.time.DayOfWeek
 import java.time.Instant
 import java.time.ZoneId
@@ -166,7 +166,11 @@
 @Sampled
 @Composable
 fun DateRangePickerSample() {
-    val savedRange = remember { mutableStateOf(LongRange.EMPTY) }
+    // Decoupled snackbar host state from scaffold state for demo purposes.
+    val snackState = remember { SnackbarHostState() }
+    val snackScope = rememberCoroutineScope()
+    SnackbarHost(hostState = snackState, Modifier.zIndex(1f))
+
     val state = rememberDateRangePickerState()
     Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Top) {
         // Add a row with "Save" and dismiss actions.
@@ -182,8 +186,12 @@
             }
             TextButton(
                 onClick = {
-                    savedRange.value =
-                        state.selectedStartDateMillis!!..state.selectedEndDateMillis!!
+                    snackScope.launch {
+                        snackState.showSnackbar(
+                            "Saved range (timestamps): " +
+                                "${state.selectedStartDateMillis!!..state.selectedEndDateMillis!!}"
+                        )
+                    }
                 },
                 enabled = state.selectedEndDateMillis != null
             ) {
@@ -192,8 +200,5 @@
         }
 
         DateRangePicker(state = state, modifier = Modifier.weight(1f))
-
-        Divider()
-        Text("Saved range of timestamps: ${savedRange.value}")
     }
 }
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DatePickerTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DatePickerTest.kt
index 27760ff..0d32838 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DatePickerTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DatePickerTest.kt
@@ -355,7 +355,7 @@
                 stateData.calendarModel.getCanonicalDate(1649721600000L) // 04/12/2022
             val displayedMonth = stateData.calendarModel.getMonth(date)
             rule.runOnIdle {
-                stateData.selectedStartDate = date
+                stateData.selectedStartDate.value = date
                 stateData.displayedMonth = displayedMonth
             }
 
@@ -364,7 +364,7 @@
             restorationTester.emulateSavedInstanceStateRestore()
 
             rule.runOnIdle {
-                assertThat(stateData.selectedStartDate).isEqualTo(date)
+                assertThat(stateData.selectedStartDate.value).isEqualTo(date)
                 assertThat(stateData.displayedMonth).isEqualTo(displayedMonth)
                 assertThat(datePickerState!!.selectedDateMillis).isEqualTo(1649721600000L)
             }
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangeInputScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangeInputScreenshotTest.kt
new file mode 100644
index 0000000..fc637de
--- /dev/null
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangeInputScreenshotTest.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2023 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 androidx.compose.material3
+
+import android.os.Build
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.screenshot.AndroidXScreenshotTestRule
+import java.time.LocalDate
+import java.time.LocalTime
+import java.time.ZoneId
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@LargeTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+@OptIn(ExperimentalMaterial3Api::class)
+class DateRangeInputScreenshotTest(private val scheme: ColorSchemeWrapper) {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    @get:Rule
+    val screenshotRule = AndroidXScreenshotTestRule(GOLDEN_MATERIAL3)
+
+    private val wrap = Modifier.wrapContentSize(Alignment.Center)
+    private val wrapperTestTag = "dateRangeInputWrapper"
+
+    @Test
+    fun dateRangeInput_initialState() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                DateRangePicker(
+                    state = rememberDateRangePickerState(initialDisplayMode = DisplayMode.Input),
+                    showModeToggle = false
+                )
+            }
+        }
+        assertAgainstGolden("dateRangeInput_initialState_${scheme.name}")
+    }
+
+    @Test
+    fun dateRangeInput_withModeToggle() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                DateRangePicker(
+                    state = rememberDateRangePickerState(initialDisplayMode = DisplayMode.Input)
+                )
+            }
+        }
+        assertAgainstGolden("dateRangeInput_withModeToggle_${scheme.name}")
+    }
+
+    @Test
+    fun dateRangeInput_withEnteredDates() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                val startDayMillis = dayInUtcMilliseconds(year = 2021, month = 3, dayOfMonth = 6)
+                val endDayMillis = dayInUtcMilliseconds(year = 2022, month = 1, dayOfMonth = 10)
+                DateRangePicker(
+                    state = rememberDateRangePickerState(
+                        initialSelectedStartDateMillis = startDayMillis,
+                        initialSelectedEndDateMillis = endDayMillis,
+                        initialDisplayMode = DisplayMode.Input
+                    ),
+                    showModeToggle = false
+                )
+            }
+        }
+        assertAgainstGolden("dateRangeInput_withEnteredDates_${scheme.name}")
+    }
+
+    // Returns the given date's day as milliseconds from epoch. The returned value is for the day's
+    // start on midnight.
+    private fun dayInUtcMilliseconds(year: Int, month: Int, dayOfMonth: Int): Long =
+        LocalDate.of(year, month, dayOfMonth)
+            .atTime(LocalTime.MIDNIGHT)
+            .atZone(ZoneId.of("UTC"))
+            .toInstant()
+            .toEpochMilli()
+
+    private fun assertAgainstGolden(goldenName: String) {
+        rule.onNodeWithTag(wrapperTestTag)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, goldenName)
+    }
+
+    // Provide the ColorScheme and their name parameter in a ColorSchemeWrapper.
+    // This makes sure that the default method name and the initial Scuba image generated
+    // name is as expected.
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun parameters() = arrayOf(
+            ColorSchemeWrapper("lightTheme", lightColorScheme()),
+            ColorSchemeWrapper("darkTheme", darkColorScheme()),
+        )
+    }
+
+    class ColorSchemeWrapper(val name: String, val colorScheme: ColorScheme) {
+        override fun toString(): String {
+            return name
+        }
+    }
+}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangeInputTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangeInputTest.kt
new file mode 100644
index 0000000..aa623b5
--- /dev/null
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangeInputTest.kt
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2023 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 androidx.compose.material3
+
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.test.SemanticsMatcher.Companion.expectValue
+import androidx.compose.ui.test.SemanticsMatcher.Companion.keyIsDefined
+import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onAllNodesWithText
+import androidx.compose.ui.test.onFirst
+import androidx.compose.ui.test.onLast
+import androidx.compose.ui.test.onNodeWithContentDescription
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.test.performTextInput
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import java.util.Calendar
+import java.util.Locale
+import java.util.TimeZone
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalMaterial3Api::class)
+class DateRangeInputTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    @Test
+    fun dateRangeInput() {
+        lateinit var dateRangeInputLabel: String
+        lateinit var state: DateRangePickerState
+        lateinit var pickerStartDateHeadline: String
+        lateinit var pickerEndDateHeadline: String
+        rule.setMaterialContent(lightColorScheme()) {
+            pickerStartDateHeadline = getString(string = Strings.DateRangePickerStartHeadline)
+            pickerEndDateHeadline = getString(string = Strings.DateRangePickerEndHeadline)
+            dateRangeInputLabel = getString(string = Strings.DateInputLabel)
+            val monthInUtcMillis = dayInUtcMilliseconds(year = 2019, month = 1, dayOfMonth = 1)
+            state = rememberDateRangePickerState(
+                initialDisplayedMonthMillis = monthInUtcMillis,
+                initialDisplayMode = DisplayMode.Input
+            )
+            DateRangePicker(state = state)
+        }
+
+        rule.onNodeWithText(pickerStartDateHeadline, useUnmergedTree = true).assertExists()
+        rule.onNodeWithText(pickerEndDateHeadline, useUnmergedTree = true).assertExists()
+
+        // Enter dates.
+        rule.onAllNodesWithText(dateRangeInputLabel).onFirst().performClick()
+            .performTextInput("01272019")
+        rule.onAllNodesWithText(dateRangeInputLabel).onLast().performClick()
+            .performTextInput("05102020")
+
+        rule.runOnIdle {
+            assertThat(state.selectedStartDateMillis).isEqualTo(
+                dayInUtcMilliseconds(
+                    year = 2019,
+                    month = 1,
+                    dayOfMonth = 27
+                )
+            )
+            assertThat(state.selectedEndDateMillis).isEqualTo(
+                dayInUtcMilliseconds(
+                    year = 2020,
+                    month = 5,
+                    dayOfMonth = 10
+                )
+            )
+        }
+
+        rule.onNodeWithText(pickerStartDateHeadline, useUnmergedTree = true).assertDoesNotExist()
+        rule.onNodeWithText(pickerEndDateHeadline, useUnmergedTree = true).assertDoesNotExist()
+        rule.onNodeWithText("Jan 27, 2019", useUnmergedTree = true).assertExists()
+        rule.onNodeWithText("May 10, 2020", useUnmergedTree = true).assertExists()
+    }
+
+    @Test
+    fun dateRangeInputWithInitialDates() {
+        lateinit var state: DateRangePickerState
+        rule.setMaterialContent(lightColorScheme()) {
+            val initialStartDateMillis =
+                dayInUtcMilliseconds(year = 2010, month = 5, dayOfMonth = 11)
+            val initialEndDateMillis =
+                dayInUtcMilliseconds(year = 2020, month = 10, dayOfMonth = 20)
+            state = rememberDateRangePickerState(
+                initialSelectedStartDateMillis = initialStartDateMillis,
+                initialSelectedEndDateMillis = initialEndDateMillis,
+                initialDisplayMode = DisplayMode.Input
+            )
+            DateRangePicker(state = state)
+        }
+
+        rule.onNodeWithText("05/11/2010").assertExists()
+        rule.onNodeWithText("10/20/2020").assertExists()
+        rule.onNodeWithText("May 11, 2010", useUnmergedTree = true).assertExists()
+        rule.onNodeWithText("Oct 20, 2020", useUnmergedTree = true).assertExists()
+    }
+
+    @Test
+    fun inputDateNotAllowed() {
+        lateinit var dateRangeInputLabel: String
+        lateinit var errorMessage: String
+        lateinit var state: DateRangePickerState
+        rule.setMaterialContent(lightColorScheme()) {
+            dateRangeInputLabel = getString(string = Strings.DateInputLabel)
+            errorMessage = getString(string = Strings.DateInputInvalidNotAllowed)
+            state = rememberDateRangePickerState(initialDisplayMode = DisplayMode.Input)
+            DateRangePicker(state = state,
+                // All dates are invalid for the sake of this test.
+                dateValidator = { false }
+            )
+        }
+
+        // Enter dates.
+        rule.onAllNodesWithText(dateRangeInputLabel).onFirst().performClick()
+            .performTextInput("01272019")
+        rule.onAllNodesWithText(dateRangeInputLabel).onLast().performClick()
+            .performTextInput("05102020")
+
+        rule.runOnIdle {
+            assertThat(state.selectedStartDateMillis).isNull()
+            assertThat(state.selectedEndDateMillis).isNull()
+        }
+        rule.onNodeWithText("01/27/2019")
+            .assert(keyIsDefined(SemanticsProperties.Error))
+            .assert(
+                expectValue(
+                    SemanticsProperties.Error,
+                    errorMessage.format("Jan 27, 2019")
+                )
+            )
+        rule.onNodeWithText("05/10/2020")
+            .assert(keyIsDefined(SemanticsProperties.Error))
+            .assert(
+                expectValue(
+                    SemanticsProperties.Error,
+                    errorMessage.format("May 10, 2020")
+                )
+            )
+    }
+
+    @Test
+    fun outOfOrderDateRange() {
+        lateinit var dateRangeInputLabel: String
+        lateinit var errorMessage: String
+        lateinit var state: DateRangePickerState
+        rule.setMaterialContent(lightColorScheme()) {
+            dateRangeInputLabel = getString(string = Strings.DateInputLabel)
+            errorMessage = getString(string = Strings.DateRangeInputInvalidRangeInput)
+            state = rememberDateRangePickerState(
+                // Limit the years selection to 2018-2023
+                yearRange = IntRange(2018, 2023),
+                initialDisplayMode = DisplayMode.Input
+            )
+            DateRangePicker(state = state)
+        }
+
+        // Enter dates where the start date is later than the end date.
+        rule.onAllNodesWithText(dateRangeInputLabel).onFirst().performClick()
+            .performTextInput("01272020")
+        rule.onAllNodesWithText(dateRangeInputLabel).onLast().performClick()
+            .performTextInput("05102019")
+
+        rule.runOnIdle {
+            // Expecting the first stored date to still be valid, and the second one to be null.
+            assertThat(state.selectedStartDateMillis).isNotNull()
+            assertThat(state.selectedEndDateMillis).isNull()
+        }
+        rule.onNodeWithText("05/10/2019")
+            .assert(keyIsDefined(SemanticsProperties.Error))
+            .assert(expectValue(SemanticsProperties.Error, errorMessage))
+    }
+
+    @Test
+    fun switchToDateRangePicker() {
+        lateinit var switchToPickerDescription: String
+        lateinit var dateRangeInputLabel: String
+        lateinit var pickerStartDateHeadline: String
+        lateinit var pickerEndDateHeadline: String
+        rule.setMaterialContent(lightColorScheme()) {
+            switchToPickerDescription = getString(string = Strings.DatePickerSwitchToCalendarMode)
+            dateRangeInputLabel = getString(string = Strings.DateInputLabel)
+            pickerStartDateHeadline = getString(string = Strings.DateRangePickerStartHeadline)
+            pickerEndDateHeadline = getString(string = Strings.DateRangePickerEndHeadline)
+            DateRangePicker(
+                state = rememberDateRangePickerState(initialDisplayMode = DisplayMode.Input)
+            )
+        }
+
+        // Click to switch to DateRangePicker.
+        rule.onNodeWithContentDescription(label = switchToPickerDescription).performClick()
+
+        rule.waitForIdle()
+        rule.onNodeWithText(pickerStartDateHeadline, useUnmergedTree = true).assertIsDisplayed()
+        rule.onNodeWithText(pickerEndDateHeadline, useUnmergedTree = true).assertIsDisplayed()
+        rule.onNodeWithText(dateRangeInputLabel).assertDoesNotExist()
+    }
+
+    @Test
+    fun defaultSemantics() {
+        val startDateMillis = dayInUtcMilliseconds(year = 2010, month = 5, dayOfMonth = 11)
+        val endDateMillis = dayInUtcMilliseconds(year = 2010, month = 6, dayOfMonth = 12)
+        lateinit var pickerStartDateHeadline: String
+        lateinit var pickerEndDateHeadline: String
+        rule.setMaterialContent(lightColorScheme()) {
+            pickerStartDateHeadline = getString(string = Strings.DateRangePickerStartHeadline)
+            pickerEndDateHeadline = getString(string = Strings.DateRangePickerEndHeadline)
+            DateRangePicker(
+                state = rememberDateRangePickerState(
+                    initialSelectedStartDateMillis = startDateMillis,
+                    initialSelectedEndDateMillis = endDateMillis,
+                    initialDisplayMode = DisplayMode.Input
+                )
+            )
+        }
+
+        val fullStartDateDescription = formatWithSkeleton(
+            startDateMillis,
+            DatePickerDefaults.YearMonthWeekdayDaySkeleton,
+            Locale.US
+        )
+        val fullEndDateDescription = formatWithSkeleton(
+            endDateMillis,
+            DatePickerDefaults.YearMonthWeekdayDaySkeleton,
+            Locale.US
+        )
+
+        val startHeadlineDescription = "$pickerStartDateHeadline: $fullStartDateDescription"
+        val endHeadlineDescription = "$pickerEndDateHeadline: $fullEndDateDescription"
+        rule.onNodeWithContentDescription("$startHeadlineDescription, $endHeadlineDescription")
+            .assertExists()
+    }
+
+    // Returns the given date's day as milliseconds from epoch. The returned value is for the day's
+    // start on midnight.
+    private fun dayInUtcMilliseconds(year: Int, month: Int, dayOfMonth: Int): Long {
+        val firstDayCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
+        firstDayCalendar.clear()
+        firstDayCalendar[Calendar.YEAR] = year
+        firstDayCalendar[Calendar.MONTH] = month - 1
+        firstDayCalendar[Calendar.DAY_OF_MONTH] = dayOfMonth
+        return firstDayCalendar.timeInMillis
+    }
+}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerScreenshotTest.kt
index 0b46437..2e96eb2 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerScreenshotTest.kt
@@ -62,7 +62,8 @@
                 DateRangePicker(
                     state = rememberDateRangePickerState(
                         initialDisplayedMonthMillis = monthInUtcMillis
-                    )
+                    ),
+                    showModeToggle = false
                 )
             }
         }
@@ -83,7 +84,8 @@
                         initialDisplayedMonthMillis = monthInUtcMillis,
                         initialSelectedStartDateMillis = startSelectionMillis,
                         initialSelectedEndDateMillis = endSelectionMillis
-                    )
+                    ),
+                    showModeToggle = false
                 )
             }
         }
@@ -104,7 +106,8 @@
                         initialDisplayedMonthMillis = monthInUtcMillis,
                         initialSelectedStartDateMillis = startSelectionMillis,
                         initialSelectedEndDateMillis = endSelectionMillis
-                    )
+                    ),
+                    showModeToggle = false
                 )
             }
         }
@@ -126,13 +129,29 @@
                                 .toLocalDate()
                         val dayOfWeek = localDate.dayOfWeek
                         dayOfWeek != DayOfWeek.SUNDAY
-                    }
+                    },
+                    showModeToggle = false
                 )
             }
         }
         assertAgainstGolden("dateRangePicker_invalidSundaySelection_${scheme.name}")
     }
 
+    @Test
+    fun dateRangePicker_withModeToggle() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                val monthInUtcMillis = dayInUtcMilliseconds(year = 2021, month = 1, dayOfMonth = 1)
+                DateRangePicker(
+                    state = rememberDateRangePickerState(
+                        initialDisplayedMonthMillis = monthInUtcMillis
+                    )
+                )
+            }
+        }
+        assertAgainstGolden("dateRangePicker_withModeToggle_${scheme.name}")
+    }
+
     // Returns the given date's day as milliseconds from epoch. The returned value is for the day's
     // start on midnight.
     private fun dayInUtcMilliseconds(year: Int, month: Int, dayOfMonth: Int): Long =
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerTest.kt
index 351f502..feecc3a 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DateRangePickerTest.kt
@@ -302,8 +302,8 @@
                 stateData.calendarModel.getCanonicalDate(1649721600000L + MillisecondsIn24Hours)
             val displayedMonth = stateData.calendarModel.getMonth(startDate)
             rule.runOnIdle {
-                stateData.selectedStartDate = startDate
-                stateData.selectedEndDate = endDate
+                stateData.selectedStartDate.value = startDate
+                stateData.selectedEndDate.value = endDate
                 stateData.displayedMonth = displayedMonth
             }
 
@@ -312,8 +312,8 @@
             restorationTester.emulateSavedInstanceStateRestore()
 
             rule.runOnIdle {
-                assertThat(stateData.selectedStartDate).isEqualTo(startDate)
-                assertThat(stateData.selectedEndDate).isEqualTo(endDate)
+                assertThat(stateData.selectedStartDate.value).isEqualTo(startDate)
+                assertThat(stateData.selectedEndDate.value).isEqualTo(endDate)
                 assertThat(stateData.displayedMonth).isEqualTo(displayedMonth)
                 assertThat(dateRangePickerState!!.selectedStartDateMillis)
                     .isEqualTo(1649721600000L)
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
index 8201b0a..14e22c4 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
@@ -141,7 +141,8 @@
             Truth.assertThat(result).isEqualTo(SnackbarResult.Dismissed)
         }
 
-        rule.waitUntil(timeoutMillis = 10_000) { job2.isCompleted }
+        rule.mainClock.advanceTimeBy(5_000)
+        rule.waitUntil { job2.isCompleted }
     }
 
     @Test
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipScreenshotTest.kt
index eafc433..bbffc0f5 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipScreenshotTest.kt
@@ -17,20 +17,22 @@
 package androidx.compose.material3
 
 import android.os.Build
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Favorite
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.testutils.assertAgainstGolden
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.longClick
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performTouchInput
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
-import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -48,44 +50,98 @@
 
     @Test
     fun plainTooltip_lightTheme() {
-        rule.setMaterialContent(lightColorScheme()) { TestPlainTooltips() }
+        rule.setMaterialContent(lightColorScheme()) { PlainTooltipTest() }
+
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         assertAgainstGolden("plainTooltip_lightTheme")
     }
 
     @Test
     fun plainTooltip_darkTheme() {
-        rule.setMaterialContent(darkColorScheme()) { TestPlainTooltips() }
+        rule.setMaterialContent(darkColorScheme()) { PlainTooltipTest() }
+
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         assertAgainstGolden("plainTooltip_darkTheme")
     }
 
     @Test
     fun richTooltip_lightTheme() {
-        rule.setMaterialContent(lightColorScheme()) { TestRichTooltips() }
+        rule.setMaterialContent(lightColorScheme()) { RichTooltipTest() }
+
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         assertAgainstGolden("richTooltip_lightTheme")
     }
 
     @Test
     fun richTooltip_darkTheme() {
-        rule.setMaterialContent(darkColorScheme()) { TestRichTooltips() }
+        rule.setMaterialContent(darkColorScheme()) { RichTooltipTest() }
+
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         assertAgainstGolden("richTooltip_darkTheme")
     }
 
+    private fun assertAgainstGolden(goldenName: String) {
+        rule.onNodeWithTag(TooltipTestTag)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, goldenName)
+    }
+
     @Composable
-    private fun TestPlainTooltips() {
-        val scope = rememberCoroutineScope()
+    private fun PlainTooltipTest() {
         val tooltipState = remember { PlainTooltipState() }
         PlainTooltipBox(
             tooltip = { Text("Tooltip Text") },
             modifier = Modifier.testTag(TooltipTestTag),
             tooltipState = tooltipState
-        ) {}
-
-        scope.launch { tooltipState.show() }
+        ) {
+            Icon(
+                Icons.Filled.Favorite,
+                contentDescription = null,
+                modifier = Modifier
+                    .testTag(AnchorTestTag)
+                    .tooltipAnchor()
+            )
+        }
     }
 
     @Composable
-    private fun TestRichTooltips() {
-        val scope = rememberCoroutineScope()
+    private fun RichTooltipTest() {
         val tooltipState = remember { RichTooltipState() }
         RichTooltipBox(
             title = { Text("Title") },
@@ -98,16 +154,17 @@
             action = { Text("Action Text") },
             tooltipState = tooltipState,
             modifier = Modifier.testTag(TooltipTestTag)
-        ) {}
-
-        scope.launch { tooltipState.show() }
-    }
-
-    private fun assertAgainstGolden(goldenName: String) {
-        rule.onNodeWithTag(TooltipTestTag)
-            .captureToImage()
-            .assertAgainstGolden(screenshotRule, goldenName)
+        ) {
+            Icon(
+                Icons.Filled.Favorite,
+                contentDescription = null,
+                modifier = Modifier
+                    .testTag(AnchorTestTag)
+                    .tooltipAnchor()
+            )
+        }
     }
 }
 
+private const val AnchorTestTag = "Anchor"
 private const val TooltipTestTag = "tooltip"
\ No newline at end of file
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipTest.kt
index 666507d..848bfb6 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TooltipTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.compose.material3
 
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.layout.size
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Favorite
@@ -41,7 +39,6 @@
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.launch
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -56,8 +53,18 @@
 
     @Test
     fun plainTooltip_noContent_size() {
-        rule.setMaterialContent(lightColorScheme()) { TestPlainTooltip() }
+        rule.setMaterialContent(lightColorScheme()) { PlainTooltipTest() }
 
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         rule.onNodeWithTag(ContainerTestTag)
             .assertHeightIsEqualTo(TooltipMinHeight)
             .assertWidthIsEqualTo(TooltipMinWidth)
@@ -65,7 +72,18 @@
 
     @Test
     fun richTooltip_noContent_size() {
-        rule.setMaterialContent(lightColorScheme()) { TestRichTooltip() }
+        rule.setMaterialContent(lightColorScheme()) { RichTooltipTest() }
+
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         rule.onNodeWithTag(ContainerTestTag)
             .assertHeightIsEqualTo(TooltipMinHeight)
             .assertWidthIsEqualTo(TooltipMinWidth)
@@ -75,11 +93,22 @@
     fun plainTooltip_customSize_size() {
         val customWidth = 100.dp
         val customHeight = 100.dp
-
         rule.setMaterialContent(lightColorScheme()) {
-            TestPlainTooltip(modifier = Modifier.size(customWidth, customHeight))
+            PlainTooltipTest(
+                modifier = Modifier.size(customWidth, customHeight)
+            )
         }
 
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         rule.onNodeWithTag(ContainerTestTag)
             .assertHeightIsEqualTo(customHeight)
             .assertWidthIsEqualTo(customWidth)
@@ -89,21 +118,31 @@
     fun richTooltip_customSize_size() {
         val customWidth = 100.dp
         val customHeight = 100.dp
-
         rule.setMaterialContent(lightColorScheme()) {
-            TestRichTooltip(modifier = Modifier.size(customWidth, customHeight))
+            RichTooltipTest(
+                modifier = Modifier.size(customWidth, customHeight)
+            )
         }
 
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         rule.onNodeWithTag(ContainerTestTag)
             .assertHeightIsEqualTo(customHeight)
             .assertWidthIsEqualTo(customWidth)
     }
 
-    @Ignore // b/264907895
     @Test
     fun plainTooltip_content_padding() {
         rule.setMaterialContent(lightColorScheme()) {
-            TestPlainTooltip(
+            PlainTooltipTest(
                 tooltipContent = {
                     Text(
                         text = "Test",
@@ -113,6 +152,16 @@
             )
         }
 
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         rule.onNodeWithTag(TextTestTag)
             .assertLeftPositionInRootIsEqualTo(8.dp)
             .assertTopPositionInRootIsEqualTo(4.dp)
@@ -121,13 +170,23 @@
     @Test
     fun richTooltip_content_padding() {
         rule.setMaterialContent(lightColorScheme()) {
-            TestRichTooltip(
+            RichTooltipTest(
                 title = { Text(text = "Subhead", modifier = Modifier.testTag(SubheadTestTag)) },
                 text = { Text(text = "Text", modifier = Modifier.testTag(TextTestTag)) },
-                action = { Text(text = "Action", modifier = Modifier.testTag(ActionTestTag)) },
+                action = { Text(text = "Action", modifier = Modifier.testTag(ActionTestTag)) }
             )
         }
 
+        // Stop auto advance for test consistency
+        rule.mainClock.autoAdvance = false
+
+        rule.onNodeWithTag(AnchorTestTag)
+            .performTouchInput { longClick() }
+
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
+        rule.waitForIdle()
         val subhead = rule.onNodeWithTag(SubheadTestTag)
         val text = rule.onNodeWithTag(TextTestTag)
 
@@ -154,23 +213,25 @@
     fun plainTooltip_behavior() {
         val tooltipState = PlainTooltipState()
         rule.setMaterialContent(lightColorScheme()) {
-            PlainTooltipBox(
-                tooltip = { Text(text = "Test", modifier = Modifier.testTag(TextTestTag)) },
-                tooltipState = tooltipState,
-                modifier = Modifier.testTag(ContainerTestTag)
-            ) { Anchor(tooltipState) }
+            PlainTooltipTest(
+                tooltipContent = { Text(text = "Test", modifier = Modifier.testTag(TextTestTag)) },
+                tooltipState = tooltipState
+            )
         }
 
-        // Tooltip should initially be not visible
-        assertThat(tooltipState.isVisible).isFalse()
-
         // Test will manually advance the time to check the timeout
         rule.mainClock.autoAdvance = false
 
+        // Tooltip should initially be not visible
+        assertThat(tooltipState.isVisible).isFalse()
+
         // Long press the icon
         rule.onNodeWithTag(AnchorTestTag)
             .performTouchInput { longClick() }
 
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
         // Check that the tooltip is now showing
         rule.waitForIdle()
         assertThat(tooltipState.isVisible).isTrue()
@@ -185,24 +246,26 @@
     fun richTooltip_behavior_noAction() {
         val tooltipState = RichTooltipState()
         rule.setMaterialContent(lightColorScheme()) {
-            RichTooltipBox(
+            RichTooltipTest(
                 title = { Text(text = "Subhead", modifier = Modifier.testTag(SubheadTestTag)) },
                 text = { Text(text = "Text", modifier = Modifier.testTag(TextTestTag)) },
-                tooltipState = tooltipState,
-                modifier = Modifier.testTag(ContainerTestTag)
-            ) { Anchor(tooltipState) }
+                tooltipState = tooltipState
+            )
         }
 
-        // Tooltip should initially be not visible
-        assertThat(tooltipState.isVisible).isFalse()
-
         // Test will manually advance the time to check the timeout
         rule.mainClock.autoAdvance = false
 
+        // Tooltip should initially be not visible
+        assertThat(tooltipState.isVisible).isFalse()
+
         // Long press the icon
         rule.onNodeWithTag(AnchorTestTag)
             .performTouchInput { longClick() }
 
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
         // Check that the tooltip is now showing
         rule.waitForIdle()
         assertThat(tooltipState.isVisible).isTrue()
@@ -218,7 +281,7 @@
         val tooltipState = RichTooltipState()
         rule.setMaterialContent(lightColorScheme()) {
             val scope = rememberCoroutineScope()
-            RichTooltipBox(
+            RichTooltipTest(
                 title = { Text(text = "Subhead", modifier = Modifier.testTag(SubheadTestTag)) },
                 text = { Text(text = "Text", modifier = Modifier.testTag(TextTestTag)) },
                 action = {
@@ -227,21 +290,23 @@
                         modifier = Modifier.testTag(ActionTestTag)
                     ) { Text(text = "Action") }
                 },
-                tooltipState = tooltipState,
-                modifier = Modifier.testTag(ContainerTestTag)
-            ) { Anchor(tooltipState) }
+                tooltipState = tooltipState
+            )
         }
 
-        // Tooltip should initially be not visible
-        assertThat(tooltipState.isVisible).isFalse()
-
         // Test will manually advance the time to check the timeout
         rule.mainClock.autoAdvance = false
 
+        // Tooltip should initially be not visible
+        assertThat(tooltipState.isVisible).isFalse()
+
         // Long press the icon
         rule.onNodeWithTag(AnchorTestTag)
             .performTouchInput { longClick() }
 
+        // Advance by the fade in time
+        rule.mainClock.advanceTimeBy(TooltipFadeInDuration.toLong())
+
         // Check that the tooltip is now showing
         rule.waitForIdle()
         assertThat(tooltipState.isVisible).isTrue()
@@ -258,64 +323,49 @@
     }
 
     @Composable
-    private fun TestPlainTooltip(
+    private fun PlainTooltipTest(
         modifier: Modifier = Modifier,
+        tooltipContent: @Composable () -> Unit = {},
         tooltipState: PlainTooltipState = remember { PlainTooltipState() },
-        tooltipContent: @Composable () -> Unit = {}
     ) {
-        val scope = rememberCoroutineScope()
-
         PlainTooltipBox(
             tooltip = tooltipContent,
-            modifier = modifier.testTag(ContainerTestTag),
-            tooltipState = tooltipState
-        ) {}
-
-        scope.launch { tooltipState.show() }
+            tooltipState = tooltipState,
+            modifier = modifier.testTag(ContainerTestTag)
+        ) {
+            Icon(
+                Icons.Filled.Favorite,
+                contentDescription = null,
+                modifier = Modifier
+                    .testTag(AnchorTestTag)
+                    .tooltipAnchor()
+            )
+        }
     }
 
     @Composable
-    private fun TestRichTooltip(
+    private fun RichTooltipTest(
         modifier: Modifier = Modifier,
         tooltipState: RichTooltipState = remember { RichTooltipState() },
         text: @Composable () -> Unit = {},
-        action: (@Composable () -> Unit)? = null,
-        title: (@Composable () -> Unit)? = null
+        title: (@Composable () -> Unit)? = null,
+        action: (@Composable () -> Unit)? = null
     ) {
-        val scope = rememberCoroutineScope()
-
         RichTooltipBox(
             text = text,
-            action = action,
             title = title,
-            modifier = modifier.testTag(ContainerTestTag),
-            tooltipState = tooltipState
-        ) {}
-
-        scope.launch { tooltipState.show() }
-    }
-
-    @OptIn(ExperimentalFoundationApi::class)
-    @Composable
-    private fun Anchor(
-        tooltipState: TooltipState
-    ) {
-        val scope = rememberCoroutineScope()
-
-        Icon(
-            Icons.Filled.Favorite,
-            contentDescription = null,
-            modifier = Modifier
-                .testTag(AnchorTestTag)
-                .combinedClickable(
-                    onClick = {},
-                    onLongClick = {
-                        scope.launch {
-                            tooltipState.show()
-                        }
-                    }
-                )
-        )
+            action = action,
+            tooltipState = tooltipState,
+            modifier = modifier.testTag(ContainerTestTag)
+        ) {
+            Icon(
+                Icons.Filled.Favorite,
+                contentDescription = null,
+                modifier = Modifier
+                    .testTag(AnchorTestTag)
+                    .tooltipAnchor()
+            )
+        }
     }
 }
 
@@ -323,4 +373,4 @@
 private const val TextTestTag = "Text"
 private const val SubheadTestTag = "Subhead"
 private const val ActionTestTag = "Action"
-private const val AnchorTestTag = "Anchor'"
\ No newline at end of file
+private const val AnchorTestTag = "Anchor"
\ No newline at end of file
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Strings.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Strings.android.kt
index eb02073..731e5348 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Strings.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Strings.android.kt
@@ -93,6 +93,12 @@
         Strings.DatePickerTodayDescription -> resources.getString(
             androidx.compose.material3.R.string.date_picker_today_description
         )
+        Strings.DatePickerScrollToShowLaterYears -> resources.getString(
+            androidx.compose.material3.R.string.date_picker_scroll_to_later_years
+        )
+        Strings.DatePickerScrollToShowEarlierYears -> resources.getString(
+            androidx.compose.material3.R.string.date_picker_scroll_to_earlier_years
+        )
         Strings.DateInputTitle -> resources.getString(
             androidx.compose.material3.R.string.date_input_title
         )
@@ -129,11 +135,20 @@
         Strings.DateRangePickerStartHeadline -> resources.getString(
             androidx.compose.material3.R.string.date_range_picker_start_headline
         )
+        Strings.DateRangePickerEndHeadline -> resources.getString(
+            androidx.compose.material3.R.string.date_range_picker_end_headline
+        )
+        Strings.DateRangePickerScrollToShowNextMonth -> resources.getString(
+            androidx.compose.material3.R.string.date_range_picker_scroll_to_next_month
+        )
+        Strings.DateRangePickerScrollToShowPreviousMonth -> resources.getString(
+            androidx.compose.material3.R.string.date_range_picker_scroll_to_previous_month
+        )
         Strings.DateRangeInputTitle -> resources.getString(
             androidx.compose.material3.R.string.date_range_input_title
         )
-        Strings.DateRangePickerEndHeadline -> resources.getString(
-            androidx.compose.material3.R.string.date_range_picker_end_headline
+        Strings.DateRangeInputInvalidRangeInput -> resources.getString(
+            androidx.compose.material3.R.string.date_range_input_invalid_range_input
         )
         Strings.TooltipLongPressLabel -> resources.getString(
             androidx.compose.material3.R.string.tooltip_long_press_label
diff --git a/compose/material3/material3/src/androidMain/res/values/strings.xml b/compose/material3/material3/src/androidMain/res/values/strings.xml
index a7eadde..465ed75 100644
--- a/compose/material3/material3/src/androidMain/res/values/strings.xml
+++ b/compose/material3/material3/src/androidMain/res/values/strings.xml
@@ -54,10 +54,22 @@
     </string>
     <string name="date_picker_switch_to_calendar_mode">Switch to calendar input mode</string>
     <string name="date_picker_switch_to_input_mode">Switch to text input mode</string>
+    <!-- Spoken description for scrolling to display later years -->
+    <string name="date_picker_scroll_to_later_years">Scroll to show later years</string>
+    <!-- Spoken description for scrolling to display earlier years -->
+    <string name="date_picker_scroll_to_earlier_years">Scroll to show earlier years</string>
     <string name="date_range_picker_title">Select dates</string>
     <string name="date_range_picker_start_headline">Start date</string>
     <string name="date_range_picker_end_headline">End date</string>
+    <!-- Spoken description for scrolling to the next month -->
+    <string name="date_range_picker_scroll_to_next_month">Scroll to show the next month</string>
+    <!-- Spoken description for scrolling to the previous month -->
+    <string name="date_range_picker_scroll_to_previous_month">Scroll to show the previous month</string>
     <string name="date_range_input_title">Enter dates</string>
+    <!--
+    Describes an invalid date range input when a user enters a start or end date [CHAR_LIMIT=NONE]
+    -->
+    <string name="date_range_input_invalid_range_input">Invalid date range input</string>
     <!-- Spoken description of a tooltip -->
     <string name="tooltip_long_press_label">Show tooltip</string>
     <!-- Suffix for time in 12-hour standard, after noon. [CHAR_LIMIT=2]" -->
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/CalendarModel.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/CalendarModel.kt
index d513a40..9291197 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/CalendarModel.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/CalendarModel.kt
@@ -17,6 +17,7 @@
 package androidx.compose.material3
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ReadOnlyComposable
 import java.util.Locale
 
@@ -285,6 +286,7 @@
  * in a short format, as well as a date pattern with and without a delimiter.
  */
 @ExperimentalMaterial3Api
+@Immutable
 internal data class DateInputFormat(
     val patternWithDelimiters: String,
     val delimiter: Char
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
index 129ac14..42b31c0 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
@@ -21,6 +21,8 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.Stable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -38,6 +40,7 @@
 import androidx.compose.ui.text.input.TransformedText
 import androidx.compose.ui.text.input.VisualTransformation
 import androidx.compose.ui.unit.dp
+import java.util.Locale
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
@@ -46,39 +49,62 @@
     dateFormatter: DatePickerFormatter,
     dateValidator: (Long) -> Boolean,
 ) {
-    DateInputTextField(
-        modifier = Modifier
-            .fillMaxWidth()
-            .padding(InputTextFieldPadding),
-        stateData = stateData,
-        dateFormatter = dateFormatter,
-        dateValidator = dateValidator
-    )
-}
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-private fun DateInputTextField(
-    modifier: Modifier,
-    stateData: StateData,
-    dateFormatter: DatePickerFormatter,
-    dateValidator: (Long) -> Boolean
-) {
     // Obtain the DateInputFormat for the default Locale.
     val defaultLocale = defaultLocale()
     val dateInputFormat = remember(defaultLocale) {
         stateData.calendarModel.getDateInputFormat(defaultLocale)
     }
-    var errorText by rememberSaveable { mutableStateOf("") }
+    val errorDatePattern = getString(Strings.DateInputInvalidForPattern)
+    val errorDateOutOfYearRange = getString(Strings.DateInputInvalidYearRange)
+    val errorInvalidNotAllowed = getString(Strings.DateInputInvalidNotAllowed)
+    val dateInputValidator = remember(dateInputFormat, dateFormatter) {
+        DateInputValidator(
+            stateData = stateData,
+            dateInputFormat = dateInputFormat,
+            dateFormatter = dateFormatter,
+            dateValidator = dateValidator,
+            errorDatePattern = errorDatePattern,
+            errorDateOutOfYearRange = errorDateOutOfYearRange,
+            errorInvalidNotAllowed = errorInvalidNotAllowed,
+            errorInvalidRangeInput = "" // Not used for a single date input
+        )
+    }
+    DateInputTextField(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(InputTextFieldPadding),
+        stateData = stateData,
+        initialDate = stateData.selectedStartDate.value,
+        onDateChanged = { date -> stateData.selectedStartDate.value = date },
+        inputIdentifier = InputIdentifier.SingleDateInput,
+        dateInputValidator = dateInputValidator,
+        dateInputFormat = dateInputFormat,
+        locale = defaultLocale
+    )
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun DateInputTextField(
+    modifier: Modifier,
+    stateData: StateData,
+    initialDate: CalendarDate?,
+    onDateChanged: (CalendarDate?) -> Unit,
+    inputIdentifier: InputIdentifier,
+    dateInputValidator: DateInputValidator,
+    dateInputFormat: DateInputFormat,
+    locale: Locale
+) {
+    val errorText = rememberSaveable { mutableStateOf("") }
     var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
         mutableStateOf(
             TextFieldValue(
                 text = with(stateData) {
-                    selectedStartDate?.let {
+                    initialDate?.let {
                         calendarModel.formatWithPattern(
                             it.utcTimeMillis,
                             dateInputFormat.patternWithoutDelimiters,
-                            defaultLocale
+                            locale
                         )
                     } ?: ""
                 },
@@ -87,57 +113,6 @@
         )
     }
 
-    // Holds a string for displaying an error message when an input does not match the expected date
-    // pattern. The string expects a date pattern string as an argument to be formatted into it.
-    val errorDatePattern = getString(Strings.DateInputInvalidForPattern)
-    // Holds a string for displaying an error message when an input date exceeds the year-range
-    // defined at the DateInput's state. The string expects a start and end year as arguments to
-    // be formatted into it.
-    val errorDateOutOfYearRange = getString(Strings.DateInputInvalidYearRange)
-    // Holds a string for displaying an error message when an input date does not pass the
-    // DateInput's validator check. The string expects a date argument to be formatted into it.
-    val errorInvalidNotAllowed = getString(Strings.DateInputInvalidNotAllowed)
-
-    // Validates the input. Sets an error message at the errorText, or return a non-null
-    // CalendarDate that represents a validated date.
-    fun validate(input: TextFieldValue): CalendarDate? {
-        val dateInputText = input.text.trim()
-        if (dateInputText.isEmpty() ||
-            dateInputText.length < dateInputFormat.patternWithoutDelimiters.length
-        ) {
-            errorText = ""
-            return null
-        }
-        val parsedDate = stateData.calendarModel.parse(
-            dateInputText,
-            dateInputFormat.patternWithoutDelimiters
-        )
-        if (parsedDate == null) {
-            errorText = errorDatePattern.format(dateInputFormat.patternWithDelimiters.uppercase())
-            return null
-        }
-        // Check that the date is within the valid range of years.
-        if (!stateData.yearRange.contains(parsedDate.year)) {
-            errorText = errorDateOutOfYearRange.format(
-                stateData.yearRange.first,
-                stateData.yearRange.last
-            )
-            return null
-        }
-        // Check that the provided date validator allows this date to be selected.
-        if (!dateValidator.invoke(parsedDate.utcTimeMillis)) {
-            errorText = errorInvalidNotAllowed.format(
-                dateFormatter.formatDate(
-                    date = parsedDate,
-                    calendarModel = stateData.calendarModel,
-                    locale = defaultLocale
-                )
-            )
-            return null
-        }
-        return parsedDate
-    }
-
     OutlinedTextField(
         value = text,
         onValueChange = { input ->
@@ -145,26 +120,45 @@
                 input.text.all { it.isDigit() }
             ) {
                 text = input
-                stateData.selectedStartDate = validate(input)
+                val trimmedText = input.text.trim()
+                if (trimmedText.isEmpty() ||
+                    trimmedText.length < dateInputFormat.patternWithoutDelimiters.length
+                ) {
+                    errorText.value = ""
+                    onDateChanged(null)
+                } else {
+                    val parsedDate = stateData.calendarModel.parse(
+                        trimmedText,
+                        dateInputFormat.patternWithoutDelimiters
+                    )
+                    errorText.value = dateInputValidator.validate(
+                        calendarDate = parsedDate,
+                        inputIdentifier = inputIdentifier,
+                        locale = locale
+                    )
+                    // Set the parsed date only if the error validation returned an empty string.
+                    // Otherwise, set it to null, as the validation failed.
+                    onDateChanged(if (errorText.value.isEmpty()) parsedDate else null)
+                }
             }
         },
         modifier = modifier
             // Add bottom padding when there is no error. Otherwise, remove it as the error text
             // will take additional height.
             .padding(
-                bottom = if (errorText.isNotBlank()) {
+                bottom = if (errorText.value.isNotBlank()) {
                     0.dp
                 } else {
                     InputTextNonErroneousBottomPadding
                 }
             )
             .semantics {
-                if (errorText.isNotBlank()) error(errorText)
+                if (errorText.value.isNotBlank()) error(errorText.value)
             },
         label = { Text(getString(string = Strings.DateInputLabel)) },
         placeholder = { Text(dateInputFormat.patternWithDelimiters.uppercase()) },
-        supportingText = { if (errorText.isNotBlank()) Text(errorText) },
-        isError = errorText.isNotBlank(),
+        supportingText = { if (errorText.value.isNotBlank()) Text(errorText.value) },
+        isError = errorText.value.isNotBlank(),
         visualTransformation = DateVisualTransformation(dateInputFormat),
         keyboardOptions = KeyboardOptions(
             autoCorrect = false,
@@ -176,6 +170,118 @@
 }
 
 /**
+ * A date input validator class.
+ *
+ * @param stateData the [StateData] that holds the selected dates info
+ * @param dateInputFormat a [DateInputFormat] that holds date patterns information
+ * @param dateFormatter a [DatePickerFormatter]
+ * @param dateValidator a lambda that takes a date timestamp and return true if the date is a valid
+ * one for selection.
+ * @param errorDatePattern a string for displaying an error message when an input does not match the
+ * expected date pattern. The string expects a date pattern string as an argument to be formatted
+ * into it.
+ * @param errorDateOutOfYearRange a string for displaying an error message when an input date
+ * exceeds the year-range defined at the DateInput's state. The string expects a start and end year
+ * as arguments to be formatted into it.
+ * @param errorInvalidNotAllowed a string for displaying an error message when an input date does
+ * not pass the DateInput's validator check. The string expects a date argument to be formatted into
+ * it.
+ * @param errorInvalidRangeInput a string for displaying an error message when in a range input mode
+ * and one of the input dates is out of order (i.e. the user inputs a start date that is after the
+ * end date, or an end date that is before the start date)
+ */
+@OptIn(ExperimentalMaterial3Api::class)
+@Stable
+internal class DateInputValidator(
+    private val stateData: StateData,
+    private val dateInputFormat: DateInputFormat,
+    private val dateFormatter: DatePickerFormatter,
+    private val dateValidator: (Long) -> Boolean,
+    private val errorDatePattern: String,
+    private val errorDateOutOfYearRange: String,
+    private val errorInvalidNotAllowed: String,
+    private val errorInvalidRangeInput: String
+) {
+
+    /**
+     * Validates a [CalendarDate] input and returns an error string in case an issue with the given
+     * date is detected, or an empty string in case there are no issues.
+     *
+     * @param calendarDate a [CalendarDate] input
+     * @param inputIdentifier an [InputIdentifier] that provides information about the input field
+     * that is supposed to hold the date.
+     * @param locale the current [Locale]
+     */
+    fun validate(
+        calendarDate: CalendarDate?,
+        inputIdentifier: InputIdentifier,
+        locale: Locale
+    ): String {
+        if (calendarDate == null) {
+            return errorDatePattern.format(dateInputFormat.patternWithDelimiters.uppercase())
+        }
+        // Check that the date is within the valid range of years.
+        if (!stateData.yearRange.contains(calendarDate.year)) {
+            return errorDateOutOfYearRange.format(
+                stateData.yearRange.first.toLocalString(),
+                stateData.yearRange.last.toLocalString()
+            )
+        }
+        // Check that the provided date validator allows this date to be selected.
+        if (!dateValidator.invoke(calendarDate.utcTimeMillis)) {
+            return errorInvalidNotAllowed.format(
+                dateFormatter.formatDate(
+                    date = calendarDate,
+                    calendarModel = stateData.calendarModel,
+                    locale = locale
+                )
+            )
+        }
+
+        // Additional validation when the InputIdentifier is for start of end dates in a range input
+        if ((inputIdentifier == InputIdentifier.StartDateInput &&
+                calendarDate.utcTimeMillis >= (stateData.selectedEndDate.value?.utcTimeMillis
+                ?: Long.MAX_VALUE)) ||
+            (inputIdentifier == InputIdentifier.EndDateInput &&
+                calendarDate.utcTimeMillis <= (stateData.selectedStartDate.value?.utcTimeMillis
+                ?: Long.MIN_VALUE))
+        ) {
+            // The input start date is after the end date, or the end date is before the start date.
+            return errorInvalidRangeInput
+        }
+
+        return ""
+    }
+}
+
+/**
+ * Represents different input identifiers for the [DateInputTextField]. An `InputIdentifier` is used
+ * when validating the user input, and especially when validating an input range.
+ */
+@Immutable
+@JvmInline
+internal value class InputIdentifier internal constructor(internal val value: Int) {
+
+    companion object {
+        /** Single date input */
+        val SingleDateInput = InputIdentifier(0)
+
+        /** A start date input */
+        val StartDateInput = InputIdentifier(1)
+
+        /** An end date input */
+        val EndDateInput = InputIdentifier(2)
+    }
+
+    override fun toString() = when (this) {
+        SingleDateInput -> "SingleDateInput"
+        StartDateInput -> "StartDateInput"
+        EndDateInput -> "EndDateInput"
+        else -> "Unknown"
+    }
+}
+
+/**
  * A [VisualTransformation] for date input. The transformation will automatically display the date
  * delimiters provided by the [DateInputFormat] as the date is being entered into the text field.
  */
@@ -228,7 +334,7 @@
     }
 }
 
-private val InputTextFieldPadding = PaddingValues(
+internal val InputTextFieldPadding = PaddingValues(
     start = 12.dp,
     end = 12.dp,
     top = 10.dp
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
index a900775..6df721d 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
@@ -48,6 +48,7 @@
 import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.lazy.LazyRow
 import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyGridState
 import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
 import androidx.compose.foundation.lazy.grid.rememberLazyGridState
 import androidx.compose.foundation.lazy.rememberLazyListState
@@ -86,12 +87,15 @@
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.semantics.CustomAccessibilityAction
 import androidx.compose.ui.semantics.LiveRegionMode
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.ScrollAxisRange
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.customActions
 import androidx.compose.ui.semantics.horizontalScrollAxisRange
+import androidx.compose.ui.semantics.isContainer
 import androidx.compose.ui.semantics.liveRegion
 import androidx.compose.ui.semantics.paneTitle
 import androidx.compose.ui.semantics.role
@@ -105,6 +109,7 @@
 import java.lang.Integer.max
 import java.text.NumberFormat
 import java.util.Locale
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 
 // TODO: External preview image.
@@ -160,7 +165,16 @@
         title = title,
         headline = headline,
         modeToggleButton = if (showModeToggle) {
-            { DateEntryModeToggleButton(stateData = state.stateData) }
+            {
+                DisplayModeToggleButton(
+                    displayMode = state.displayMode,
+                    onDisplayModeChange = { displayMode ->
+                        state.stateData.switchDisplayMode(
+                            displayMode
+                        )
+                    },
+                )
+            }
         } else {
             null
         },
@@ -262,7 +276,7 @@
      */
     @get:Suppress("AutoBoxing")
     val selectedDateMillis by derivedStateOf {
-        stateData.selectedStartDate?.utcTimeMillis
+        stateData.selectedStartDate.value?.utcTimeMillis
     }
 
     /**
@@ -413,12 +427,12 @@
         with(state.stateData) {
             val defaultLocale = defaultLocale()
             val formattedDate = dateFormatter.formatDate(
-                date = selectedStartDate,
+                date = selectedStartDate.value,
                 calendarModel = calendarModel,
                 locale = defaultLocale
             )
             val verboseDateDescription = dateFormatter.formatDate(
-                date = selectedStartDate,
+                date = selectedStartDate.value,
                 calendarModel = calendarModel,
                 locale = defaultLocale,
                 forContentDescription = true
@@ -810,7 +824,7 @@
     /**
      * A mutable state of [CalendarDate] that represents the start date for a selection.
      */
-    var selectedStartDate by mutableStateOf(
+    var selectedStartDate = mutableStateOf(
         if (initialSelectedStartDateMillis != null) {
             val date = calendarModel.getCanonicalDate(
                 initialSelectedStartDateMillis
@@ -830,7 +844,7 @@
      *
      * Single date selection states that use this [StateData] should always have this as `null`.
      */
-    var selectedEndDate by mutableStateOf(
+    var selectedEndDate = mutableStateOf(
         // Set to null in case the provided value is "undefined" or <= than the start date.
         if (initialSelectedEndDateMillis != null &&
             initialSelectedStartDateMillis != null &&
@@ -896,8 +910,22 @@
         get() = (yearRange.last - yearRange.first + 1) * 12
 
     fun isInRange(date: Long): Boolean {
-        return date >= (selectedStartDate?.utcTimeMillis ?: Long.MAX_VALUE) &&
-            date <= (selectedEndDate?.utcTimeMillis ?: Long.MIN_VALUE)
+        return date >= (selectedStartDate.value?.utcTimeMillis ?: Long.MAX_VALUE) &&
+            date <= (selectedEndDate.value?.utcTimeMillis ?: Long.MIN_VALUE)
+    }
+
+    fun switchDisplayMode(displayMode: DisplayMode) {
+        // Update the displayed month, if needed, and change the mode to a  date-picker.
+        selectedStartDate.value?.let {
+            displayedMonth = calendarModel.getMonth(it)
+        }
+        // When toggling back from an input mode, it's possible that the user input an invalid
+        // start date and a valid end date. If this is the case, and the start date is null, ensure
+        // that the end date is also null.
+        if (selectedStartDate.value == null && selectedEndDate.value != null) {
+            selectedEndDate.value = null
+        }
+        this.displayMode.value = displayMode
     }
 
     companion object {
@@ -907,8 +935,8 @@
         fun Saver(): Saver<StateData, Any> = listSaver(
             save = {
                 listOf(
-                    it.selectedStartDate?.utcTimeMillis,
-                    it.selectedEndDate?.utcTimeMillis,
+                    it.selectedStartDate.value?.utcTimeMillis,
+                    it.selectedEndDate.value?.utcTimeMillis,
                     it.displayedMonth.startUtcTimeMillis,
                     it.yearRange.first,
                     it.yearRange.last,
@@ -949,6 +977,7 @@
         modifier = modifier
             .sizeIn(minWidth = DatePickerModalTokens.ContainerWidth)
             .padding(DatePickerHorizontalPadding)
+            .semantics { isContainer = true }
     ) {
         DatePickerHeader(
             modifier = Modifier,
@@ -968,31 +997,25 @@
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
-internal fun DateEntryModeToggleButton(stateData: StateData) {
-    with(stateData) {
-        if (displayMode.value == DisplayMode.Picker) {
-            IconButton(onClick = {
-                displayMode.value = DisplayMode.Input
-            }) {
-                Icon(
-                    imageVector = Icons.Filled.Edit,
-                    contentDescription = getString(Strings.DatePickerSwitchToInputMode)
-                )
-            }
-        } else {
-            IconButton(
-                onClick = {
-                    // Update the displayed month, if needed, and change the mode to a
-                    // date-picker.
-                    selectedStartDate?.let { displayedMonth = calendarModel.getMonth(it) }
-                    displayMode.value = DisplayMode.Picker
-                }
-            ) {
-                Icon(
-                    imageVector = Icons.Filled.DateRange,
-                    contentDescription = getString(Strings.DatePickerSwitchToCalendarMode)
-                )
-            }
+internal fun DisplayModeToggleButton(
+    displayMode: DisplayMode,
+    onDisplayModeChange: (DisplayMode) -> Unit
+) {
+    if (displayMode == DisplayMode.Picker) {
+        IconButton(onClick = { onDisplayModeChange(DisplayMode.Input) }) {
+            Icon(
+                imageVector = Icons.Filled.Edit,
+                contentDescription = getString(Strings.DatePickerSwitchToInputMode)
+            )
+        }
+    } else {
+        IconButton(
+            onClick = { onDisplayModeChange(DisplayMode.Picker) }
+        ) {
+            Icon(
+                imageVector = Icons.Filled.DateRange,
+                contentDescription = getString(Strings.DatePickerSwitchToCalendarMode)
+            )
         }
     }
 }
@@ -1011,7 +1034,10 @@
 ) {
     // TODO(b/266480386): Apply the motion spec for this once we have it. Consider replacing this
     //  with AnimatedContent when it's out of experimental.
-    Crossfade(targetState = state.displayMode, animationSpec = spring()) { mode ->
+    Crossfade(
+        targetState = state.displayMode,
+        animationSpec = spring(),
+        modifier = Modifier.semantics { isContainer = true }) { mode ->
         when (mode) {
             DisplayMode.Picker -> DatePickerContent(
                 stateData = state.stateData,
@@ -1042,7 +1068,7 @@
     val coroutineScope = rememberCoroutineScope()
 
     val onDateSelected = { dateInMillis: Long ->
-        stateData.selectedStartDate =
+        stateData.selectedStartDate.value =
             stateData.calendarModel.getCanonicalDate(dateInMillis)
     }
 
@@ -1334,8 +1360,8 @@
             if (rangeSelectionEnabled) {
                 SelectedRangeInfo.calculateRangeInfo(
                     month,
-                    stateData.selectedStartDate,
-                    stateData.selectedEndDate
+                    stateData.selectedStartDate.value,
+                    stateData.selectedEndDate.value
                 )
             } else {
                 null
@@ -1389,8 +1415,9 @@
                             val dateInMillis = month.startUtcTimeMillis +
                                 (dayNumber * MillisecondsIn24Hours)
                             val isToday = dateInMillis == today.utcTimeMillis
-                            val startDateSelected = dateInMillis == startSelection?.utcTimeMillis
-                            val endDateSelected = dateInMillis == endSelection?.utcTimeMillis
+                            val startDateSelected =
+                                dateInMillis == startSelection.value?.utcTimeMillis
+                            val endDateSelected = dateInMillis == endSelection.value?.utcTimeMillis
                             val dayContentDescription = dayContentDescription(
                                 rangeSelectionEnabled = rangeSelectionEnabled,
                                 isToday = isToday,
@@ -1482,7 +1509,7 @@
         // In the `Month` function above, the implementation checks whether the day is today and
         // sets the content description differently.
         modifier = modifier
-        .minimumInteractiveComponentSize()
+            .minimumInteractiveComponentSize()
             .requiredSize(
                 DatePickerModalTokens.DateStateLayerWidth,
                 DatePickerModalTokens.DateStateLayerHeight
@@ -1542,6 +1569,9 @@
         } else {
             colors.containerColor
         }
+        val coroutineScope = rememberCoroutineScope()
+        val scrollToEarlierYearsLabel = getString(Strings.DatePickerScrollToShowEarlierYears)
+        val scrollToLaterYearsLabel = getString(Strings.DatePickerScrollToShowLaterYears)
         LazyVerticalGrid(
             columns = GridCells.Fixed(YearsInRow),
             modifier = modifier
@@ -1562,7 +1592,24 @@
                         .requiredSize(
                             width = DatePickerModalTokens.SelectionYearContainerWidth,
                             height = DatePickerModalTokens.SelectionYearContainerHeight
-                        ),
+                        )
+                        .semantics {
+                            // Apply a11y custom actions to the first and last items in the years
+                            // grid. The actions will suggest to scroll to earlier or later years in
+                            // the grid.
+                            customActions = if (lazyGridState.firstVisibleItemIndex == it ||
+                                lazyGridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index == it
+                            ) {
+                                customScrollActions(
+                                    state = lazyGridState,
+                                    coroutineScope = coroutineScope,
+                                    scrollUpLabel = scrollToEarlierYearsLabel,
+                                    scrollDownLabel = scrollToLaterYearsLabel
+                                )
+                            } else {
+                                emptyList()
+                            }
+                        },
                     selected = selectedYear == displayedYear,
                     currentYear = selectedYear == currentYear,
                     onClick = { onYearSelected(selectedYear) },
@@ -1721,10 +1768,48 @@
     }
 }
 
+private fun customScrollActions(
+    state: LazyGridState,
+    coroutineScope: CoroutineScope,
+    scrollUpLabel: String,
+    scrollDownLabel: String
+): List<CustomAccessibilityAction> {
+    val scrollUpAction = {
+        if (!state.canScrollBackward) {
+            false
+        } else {
+            coroutineScope.launch {
+                state.scrollToItem(state.firstVisibleItemIndex - YearsInRow)
+            }
+            true
+        }
+    }
+    val scrollDownAction = {
+        if (!state.canScrollForward) {
+            false
+        } else {
+            coroutineScope.launch {
+                state.scrollToItem(state.firstVisibleItemIndex + YearsInRow)
+            }
+            true
+        }
+    }
+    return listOf(
+        CustomAccessibilityAction(
+            label = scrollUpLabel,
+            action = scrollUpAction
+        ),
+        CustomAccessibilityAction(
+            label = scrollDownLabel,
+            action = scrollDownAction
+        )
+    )
+}
+
 /**
  * Returns a string representation of an integer at the current Locale.
  */
-private fun Int.toLocalString(): String {
+internal fun Int.toLocalString(): String {
     val formatter = NumberFormat.getIntegerInstance()
     // Eliminate any use of delimiters when formatting the integer.
     formatter.isGroupingUsed = false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt
new file mode 100644
index 0000000..19f4293
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2023 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 androidx.compose.material3
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun DateRangeInputContent(
+    stateData: StateData,
+    dateFormatter: DatePickerFormatter,
+    dateValidator: (Long) -> Boolean,
+) {
+    // Obtain the DateInputFormat for the default Locale.
+    val defaultLocale = defaultLocale()
+    val dateInputFormat = remember(defaultLocale) {
+        stateData.calendarModel.getDateInputFormat(defaultLocale)
+    }
+    val errorDatePattern = getString(Strings.DateInputInvalidForPattern)
+    val errorDateOutOfYearRange = getString(Strings.DateInputInvalidYearRange)
+    val errorInvalidNotAllowed = getString(Strings.DateInputInvalidNotAllowed)
+    val errorInvalidRange = getString(Strings.DateRangeInputInvalidRangeInput)
+    val dateInputValidator = remember(dateInputFormat, dateFormatter) {
+        DateInputValidator(
+            stateData = stateData,
+            dateInputFormat = dateInputFormat,
+            dateFormatter = dateFormatter,
+            dateValidator = dateValidator,
+            errorDatePattern = errorDatePattern,
+            errorDateOutOfYearRange = errorDateOutOfYearRange,
+            errorInvalidNotAllowed = errorInvalidNotAllowed,
+            errorInvalidRangeInput = errorInvalidRange
+        )
+    }
+    Row(
+        modifier = Modifier.padding(paddingValues = InputTextFieldPadding),
+        horizontalArrangement = Arrangement.spacedBy(TextFieldSpacing)
+    ) {
+        DateInputTextField(
+            modifier = Modifier.weight(0.5f),
+            stateData = stateData,
+            initialDate = stateData.selectedStartDate.value,
+            onDateChanged = { date -> stateData.selectedStartDate.value = date },
+            inputIdentifier = InputIdentifier.StartDateInput,
+            dateInputValidator = dateInputValidator,
+            dateInputFormat = dateInputFormat,
+            locale = defaultLocale
+        )
+        DateInputTextField(
+            modifier = Modifier.weight(0.5f),
+            stateData = stateData,
+            initialDate = stateData.selectedEndDate.value,
+            onDateChanged = { date -> stateData.selectedEndDate.value = date },
+            inputIdentifier = InputIdentifier.EndDateInput,
+            dateInputValidator = dateInputValidator,
+            dateInputFormat = dateInputFormat,
+            locale = defaultLocale
+        )
+    }
+}
+
+private val TextFieldSpacing = 8.dp
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt
index e855829..c8d83ef 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt
@@ -16,6 +16,9 @@
 
 package androidx.compose.material3
 
+import androidx.compose.animation.Crossfade
+import androidx.compose.animation.core.spring
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
@@ -31,6 +34,7 @@
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
@@ -41,12 +45,20 @@
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.semantics.CustomAccessibilityAction
 import androidx.compose.ui.semantics.LiveRegionMode
+import androidx.compose.ui.semantics.ScrollAxisRange
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.customActions
+import androidx.compose.ui.semantics.isContainer
 import androidx.compose.ui.semantics.liveRegion
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.verticalScrollAxisRange
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 /**
  * <a href="https://m3.material.io/components/date-pickers/overview" class="external" target="_blank">Material Design date range picker</a>.
@@ -63,6 +75,8 @@
  * one for selection. Invalid dates will appear disabled in the UI.
  * @param title the title to be displayed in the date range picker
  * @param headline the headline to be displayed in the date range picker
+ * @param showModeToggle indicates if this DateRangePicker should show a mode toggle action that
+ * transforms it into a date range input
  * @param colors [DatePickerColors] that will be used to resolve the colors used for this date
  * range picker in different states. See [DatePickerDefaults.colors].
  */
@@ -82,14 +96,27 @@
             dateFormatter
         )
     },
+    showModeToggle: Boolean = true,
     colors: DatePickerColors = DatePickerDefaults.colors()
 ) {
     DateEntryContainer(
         modifier = modifier,
         title = title,
         headline = headline,
-        // TODO(b/245821979): Add showModeToggle param and us it here for DateEntryModeToggleButton
-        modeToggleButton = null,
+        modeToggleButton = if (showModeToggle) {
+            {
+                DisplayModeToggleButton(
+                    displayMode = state.displayMode,
+                    onDisplayModeChange = { displayMode ->
+                        state.stateData.switchDisplayMode(
+                            displayMode
+                        )
+                    }
+                )
+            }
+        } else {
+            null
+        },
         headlineTextStyle = MaterialTheme.typography.fromToken(
             DatePickerModalTokens.RangeSelectionHeaderHeadlineFont
         ),
@@ -98,9 +125,8 @@
         headerContentPadding = DateRangePickerHeaderPadding,
         colors = colors
     ) {
-        // TODO(b/245821979): Implement using a SwitchableDateEntryContent similar to the DatePicker
-        DateRangePickerContent(
-            stateData = state.stateData,
+        SwitchableDateEntryContent(
+            state = state,
             dateFormatter = dateFormatter,
             dateValidator = dateValidator,
             colors = colors
@@ -200,7 +226,7 @@
      */
     @get:Suppress("AutoBoxing")
     val selectedStartDateMillis by derivedStateOf {
-        stateData.selectedStartDate?.utcTimeMillis
+        stateData.selectedStartDate.value?.utcTimeMillis
     }
 
     /**
@@ -213,7 +239,7 @@
      */
     @get:Suppress("AutoBoxing")
     val selectedEndDateMillis by derivedStateOf {
-        stateData.selectedEndDate?.utcTimeMillis
+        stateData.selectedEndDate.value?.utcTimeMillis
     }
 
     /**
@@ -335,19 +361,19 @@
         with(state.stateData) {
             val defaultLocale = defaultLocale()
             val formatterStartDate = dateFormatter.formatDate(
-                date = selectedStartDate,
+                date = selectedStartDate.value,
                 calendarModel = calendarModel,
                 locale = defaultLocale
             )
 
             val formatterEndDate = dateFormatter.formatDate(
-                date = selectedEndDate,
+                date = selectedEndDate.value,
                 calendarModel = calendarModel,
                 locale = defaultLocale
             )
 
             val verboseStartDateDescription = dateFormatter.formatDate(
-                date = selectedStartDate,
+                date = selectedStartDate.value,
                 calendarModel = calendarModel,
                 locale = defaultLocale,
                 forContentDescription = true
@@ -358,7 +384,7 @@
             }
 
             val verboseEndDateDescription = dateFormatter.formatDate(
-                date = selectedEndDate,
+                date = selectedEndDate.value,
                 calendarModel = calendarModel,
                 locale = defaultLocale,
                 forContentDescription = true
@@ -397,6 +423,41 @@
     }
 }
 
+/**
+ * Date entry content that displays a [DateRangePickerContent] or a [DateRangeInputContent]
+ * according to the state's display mode.
+ */
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+private fun SwitchableDateEntryContent(
+    state: DateRangePickerState,
+    dateFormatter: DatePickerFormatter,
+    dateValidator: (Long) -> Boolean,
+    colors: DatePickerColors
+) {
+    // TODO(b/266480386): Apply the motion spec for this once we have it. Consider replacing this
+    //  with AnimatedContent when it's out of experimental.
+    Crossfade(
+        targetState = state.displayMode,
+        animationSpec = spring(),
+        modifier = Modifier.semantics { isContainer = true }) { mode ->
+        when (mode) {
+            DisplayMode.Picker -> DateRangePickerContent(
+                stateData = state.stateData,
+                dateFormatter = dateFormatter,
+                dateValidator = dateValidator,
+                colors = colors
+            )
+
+            DisplayMode.Input -> DateRangeInputContent(
+                stateData = state.stateData,
+                dateFormatter = dateFormatter,
+                dateValidator = dateValidator,
+            )
+        }
+    }
+}
+
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 private fun DateRangePickerContent(
@@ -452,7 +513,17 @@
             DatePickerModalTokens.RangeSelectionMonthSubheadFont
         )
     ) {
-        LazyColumn(state = lazyListState) {
+        val coroutineScope = rememberCoroutineScope()
+        val scrollToPreviousMonthLabel = getString(Strings.DateRangePickerScrollToShowPreviousMonth)
+        val scrollToNextMonthLabel = getString(Strings.DateRangePickerScrollToShowNextMonth)
+        LazyColumn(
+            // Apply this to have the screen reader traverse outside the visible list of months
+            // and not scroll them by default.
+            modifier = Modifier.semantics {
+                verticalScrollAxisRange = ScrollAxisRange(value = { 0f }, maxValue = { 0f })
+            },
+            state = lazyListState
+        ) {
             items(stateData.totalMonthsInRange) {
                 val month =
                     stateData.calendarModel.plusMonths(
@@ -468,7 +539,17 @@
                             stateData.calendarModel,
                             defaultLocale()
                         ) ?: "-",
-                        modifier = Modifier.padding(paddingValues = CalendarMonthSubheadPadding),
+                        modifier = Modifier
+                            .padding(paddingValues = CalendarMonthSubheadPadding)
+                            .clickable { /* no-op (needed for customActions to operate */ }
+                            .semantics {
+                                customActions = customScrollActions(
+                                    state = lazyListState,
+                                    coroutineScope = coroutineScope,
+                                    scrollUpLabel = scrollToPreviousMonthLabel,
+                                    scrollDownLabel = scrollToNextMonthLabel
+                                )
+                            },
                         color = colors.subheadContentColor
                     )
                     Month(
@@ -497,17 +578,17 @@
 ) {
     with(stateData) {
         val date = calendarModel.getCanonicalDate(dateInMillis)
-        val currentStart = selectedStartDate
-        val currentEnd = selectedEndDate
+        val currentStart = selectedStartDate.value
+        val currentEnd = selectedEndDate.value
         if ((currentStart == null && currentEnd == null) ||
             (currentStart != null && currentEnd != null) ||
             (currentStart != null && date < currentStart)
         ) {
             // Reset the selection to "start" only.
-            selectedStartDate = date
-            selectedEndDate = null
+            selectedStartDate.value = date
+            selectedEndDate.value = null
         } else if (currentStart != null && date > currentStart) {
-            selectedEndDate = date
+            selectedEndDate.value = date
         }
     }
 }
@@ -650,6 +731,44 @@
     }
 }
 
+private fun customScrollActions(
+    state: LazyListState,
+    coroutineScope: CoroutineScope,
+    scrollUpLabel: String,
+    scrollDownLabel: String
+): List<CustomAccessibilityAction> {
+    val scrollUpAction = {
+        if (!state.canScrollBackward) {
+            false
+        } else {
+            coroutineScope.launch {
+                state.scrollToItem(state.firstVisibleItemIndex - 1)
+            }
+            true
+        }
+    }
+    val scrollDownAction = {
+        if (!state.canScrollForward) {
+            false
+        } else {
+            coroutineScope.launch {
+                state.scrollToItem(state.firstVisibleItemIndex + 1)
+            }
+            true
+        }
+    }
+    return listOf(
+        CustomAccessibilityAction(
+            label = scrollUpLabel,
+            action = scrollUpAction
+        ),
+        CustomAccessibilityAction(
+            label = scrollDownLabel,
+            action = scrollDownAction
+        )
+    )
+}
+
 // Base header paddings that are used for the header part (title + headline). Note that for the
 // range picker default title and headline we add additional start padding. The additional paddings
 // are added there to allow more flexibility when those composables are provided by a developer.
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Strings.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Strings.kt
index c2d0a66..2b4c752 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Strings.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Strings.kt
@@ -50,29 +50,34 @@
         val DatePickerHeadlineDescription = Strings(21)
         val DatePickerNoSelectionDescription = Strings(22)
         val DatePickerTodayDescription = Strings(23)
-        val DateInputTitle = Strings(24)
-        val DateInputHeadline = Strings(25)
-        val DateInputLabel = Strings(26)
-        val DateInputHeadlineDescription = Strings(27)
-        val DateInputNoInputDescription = Strings(28)
-        val DateInputInvalidNotAllowed = Strings(29)
-        val DateInputInvalidForPattern = Strings(30)
-        val DateInputInvalidYearRange = Strings(31)
-        val DatePickerSwitchToCalendarMode = Strings(32)
-        val DatePickerSwitchToInputMode = Strings(33)
-        val DateRangePickerTitle = Strings(34)
-        val DateRangePickerStartHeadline = Strings(35)
-        val DateRangePickerEndHeadline = Strings(36)
-        val DateRangeInputTitle = Strings(37)
-        val TooltipLongPressLabel = Strings(38)
-        val TimePickerAM = Strings(39)
-        val TimePickerPM = Strings(40)
-        val TimePickerPeriodToggle = Strings(41)
-        val TimePickerHourSelection = Strings(42)
-        val TimePickerMinuteSelection = Strings(43)
-        val TimePickerHourSuffix = Strings(44)
-        val TimePicker24HourSuffix = Strings(45)
-        val TimePickerMinuteSuffix = Strings(46)
+        val DatePickerScrollToShowLaterYears = Strings(24)
+        val DatePickerScrollToShowEarlierYears = Strings(25)
+        val DateInputTitle = Strings(26)
+        val DateInputHeadline = Strings(27)
+        val DateInputLabel = Strings(28)
+        val DateInputHeadlineDescription = Strings(29)
+        val DateInputNoInputDescription = Strings(30)
+        val DateInputInvalidNotAllowed = Strings(31)
+        val DateInputInvalidForPattern = Strings(32)
+        val DateInputInvalidYearRange = Strings(33)
+        val DatePickerSwitchToCalendarMode = Strings(34)
+        val DatePickerSwitchToInputMode = Strings(35)
+        val DateRangePickerTitle = Strings(36)
+        val DateRangePickerStartHeadline = Strings(37)
+        val DateRangePickerEndHeadline = Strings(38)
+        val DateRangePickerScrollToShowNextMonth = Strings(39)
+        val DateRangePickerScrollToShowPreviousMonth = Strings(40)
+        val DateRangeInputTitle = Strings(41)
+        val DateRangeInputInvalidRangeInput = Strings(42)
+        val TooltipLongPressLabel = Strings(43)
+        val TimePickerAM = Strings(44)
+        val TimePickerPM = Strings(45)
+        val TimePickerPeriodToggle = Strings(46)
+        val TimePickerHourSelection = Strings(47)
+        val TimePickerMinuteSelection = Strings(48)
+        val TimePickerHourSuffix = Strings(49)
+        val TimePicker24HourSuffix = Strings(50)
+        val TimePickerMinuteSuffix = Strings(51)
     }
 }
 
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt
index 302f4c8..841dd47 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.LinearOutSlowInEasing
+import androidx.compose.animation.core.Transition
 import androidx.compose.animation.core.animateFloat
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
@@ -46,6 +47,7 @@
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
 import androidx.compose.ui.graphics.Color
@@ -245,30 +247,33 @@
         }
     }
 
-    Box {
-        Popup(
-            popupPositionProvider = tooltipPositionProvider,
-            onDismissRequest = {
-                if (tooltipState.isVisible) {
-                    coroutineScope.launch { tooltipState.dismiss() }
+    Box(contentAlignment = Alignment.TopCenter) {
+        val transition = updateTransition(tooltipState.isVisible, label = "Tooltip transition")
+        if (transition.currentState || transition.targetState) {
+            Popup(
+                popupPositionProvider = tooltipPositionProvider,
+                onDismissRequest = {
+                    if (tooltipState.isVisible) {
+                        coroutineScope.launch { tooltipState.dismiss() }
+                    }
                 }
+            ) {
+                Surface(
+                    modifier = modifier
+                        .sizeIn(
+                            minWidth = TooltipMinWidth,
+                            maxWidth = maxWidth,
+                            minHeight = TooltipMinHeight
+                        )
+                        .animateTooltip(transition)
+                        .focusable()
+                        .semantics { liveRegion = LiveRegionMode.Polite },
+                    shape = shape,
+                    color = containerColor,
+                    shadowElevation = elevation,
+                    content = tooltipContent
+                )
             }
-        ) {
-            Surface(
-                modifier = modifier
-                    .sizeIn(
-                        minWidth = TooltipMinWidth,
-                        maxWidth = maxWidth,
-                        minHeight = TooltipMinHeight
-                    )
-                    .animateTooltip(tooltipState.isVisible)
-                    .focusable()
-                    .semantics { liveRegion = LiveRegionMode.Polite },
-                shape = shape,
-                color = containerColor,
-                shadowElevation = elevation,
-                content = tooltipContent
-            )
         }
 
         scope.content()
@@ -484,15 +489,13 @@
 }
 
 private fun Modifier.animateTooltip(
-    showTooltip: Boolean
+    transition: Transition<Boolean>
 ): Modifier = composed(
     inspectorInfo = debugInspectorInfo {
         name = "animateTooltip"
-        properties["showTooltip"] = showTooltip
+        properties["transition"] = transition
     }
 ) {
-    val transition = updateTransition(showTooltip, label = "Tooltip transition")
-
     val scale by transition.animateFloat(
         transitionSpec = {
             if (false isTransitioningTo true) {
@@ -760,5 +763,5 @@
 private val ActionLabelBottomPadding = 8.dp
 internal const val TooltipDuration = 1500L
 // No specification for fade in and fade out duration, so aligning it with the behavior for snack bar
-private const val TooltipFadeInDuration = 150
+internal const val TooltipFadeInDuration = 150
 private const val TooltipFadeOutDuration = 75
\ No newline at end of file
diff --git a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material/Strings.desktop.kt b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material/Strings.desktop.kt
index 6a51fad..b9161ce7 100644
--- a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material/Strings.desktop.kt
+++ b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material/Strings.desktop.kt
@@ -49,6 +49,8 @@
         Strings.DatePickerHeadlineDescription -> "Current selection: %1$"
         Strings.DatePickerNoSelectionDescription -> "None"
         Strings.DatePickerTodayDescription -> "Today"
+        Strings.DatePickerScrollToShowLaterYears -> "Scroll to show later years"
+        Strings.DatePickerScrollToShowEarlierYears -> "Scroll to show earlier years"
         Strings.DateInputTitle -> "Select date"
         Strings.DateInputHeadline -> "Entered date"
         Strings.DateInputLabel -> "Date"
@@ -62,7 +64,10 @@
         Strings.DateRangePickerTitle -> "Select dates"
         Strings.DateRangePickerStartHeadline -> "Start date"
         Strings.DateRangePickerEndHeadline -> "End date"
+        Strings.DateRangePickerScrollToShowNextMonth -> "Scroll to show the next month"
+        Strings.DateRangePickerScrollToShowPreviousMonth -> "Scroll to show the previous month"
         Strings.DateRangeInputTitle -> "Enter dates"
+        Strings.DateRangeInputInvalidRangeInput -> "Invalid date range input"
         Strings.TooltipLongPressLabel -> "Show tooltip"
         Strings.TimePickerAM -> "AM"
         Strings.TimePickerPM -> "PM"
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
index edc16ae..bd97ea2 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class RuntimeIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ComposableCoroutineCreationDetector.CoroutineCreationDuringComposition,
diff --git a/compose/runtime/runtime-livedata/src/androidTest/java/androidx/compose/runtime/livedata/LiveDataAdapterTest.kt b/compose/runtime/runtime-livedata/src/androidTest/java/androidx/compose/runtime/livedata/LiveDataAdapterTest.kt
index 352ea84..9733e52 100644
--- a/compose/runtime/runtime-livedata/src/androidTest/java/androidx/compose/runtime/livedata/LiveDataAdapterTest.kt
+++ b/compose/runtime/runtime-livedata/src/androidTest/java/androidx/compose/runtime/livedata/LiveDataAdapterTest.kt
@@ -63,6 +63,21 @@
     }
 
     @Test
+    fun preferInitializedValueInFirstComposition() {
+        val liveData = MutableLiveData("value")
+        var firstComposition by mutableStateOf(true)
+        var realValue: String? = null
+        rule.setContent {
+            if (firstComposition) {
+                realValue = liveData.observeAsState("initial").value
+                firstComposition = false
+            }
+        }
+
+        assertThat(realValue).isEqualTo("value")
+    }
+
+    @Test
     fun weReceiveUpdates() {
         val liveData = MutableLiveData<String>()
         liveData.postValue("value")
diff --git a/compose/runtime/runtime-livedata/src/main/java/androidx/compose/runtime/livedata/LiveDataAdapter.kt b/compose/runtime/runtime-livedata/src/main/java/androidx/compose/runtime/livedata/LiveDataAdapter.kt
index 289a4d0..e077036 100644
--- a/compose/runtime/runtime-livedata/src/main/java/androidx/compose/runtime/livedata/LiveDataAdapter.kt
+++ b/compose/runtime/runtime-livedata/src/main/java/androidx/compose/runtime/livedata/LiveDataAdapter.kt
@@ -45,6 +45,10 @@
  * be new value posted into the [LiveData] the returned [State] will be updated causing
  * recomposition of every [State.value] usage.
  *
+ * The [initial] value will be used only if this LiveData is not already
+ * [initialized][isInitialized]. Note that if [T] is a non-null type, it is your
+ * responsibility to ensure that any value you set on this LiveData is also non-null.
+ *
  * The inner observer will automatically be removed when this composable disposes or the current
  * [LifecycleOwner] moves to the [Lifecycle.State.DESTROYED] state.
  *
@@ -53,7 +57,10 @@
 @Composable
 fun <R, T : R> LiveData<T>.observeAsState(initial: R): State<R> {
     val lifecycleOwner = LocalLifecycleOwner.current
-    val state = remember { mutableStateOf(initial) }
+    val state = remember {
+        @Suppress("UNCHECKED_CAST") /* Initialized values of a LiveData<T> must be a T */
+        mutableStateOf(if (isInitialized) value as T else initial)
+    }
     DisposableEffect(this, lifecycleOwner) {
         val observer = Observer<T> { state.value = it }
         observe(lifecycleOwner, observer)
diff --git a/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RuntimeSaveableIssueRegistry.kt b/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RuntimeSaveableIssueRegistry.kt
index 60bbfa0..ce3e102 100644
--- a/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RuntimeSaveableIssueRegistry.kt
+++ b/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RuntimeSaveableIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class RuntimeSaveableIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         RememberSaveableDetector.RememberSaveableSaverParameter
diff --git a/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/UiGraphicsIssueRegistry.kt b/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/UiGraphicsIssueRegistry.kt
index 065492c4..bff18de 100644
--- a/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/UiGraphicsIssueRegistry.kt
+++ b/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/UiGraphicsIssueRegistry.kt
@@ -25,7 +25,7 @@
  */
 class UiGraphicsIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ColorDetector.MissingColorAlphaChannel,
diff --git a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/UiIssueRegistry.kt b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/UiIssueRegistry.kt
index d296f22..1a5b343 100644
--- a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/UiIssueRegistry.kt
+++ b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/UiIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class UiIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ComposedModifierDetector.UnnecessaryComposedModifier,
diff --git a/compose/ui/ui-test-manifest-lint/src/main/java/androidx/compose/ui/test/manifest/lint/TestManifestIssueRegistry.kt b/compose/ui/ui-test-manifest-lint/src/main/java/androidx/compose/ui/test/manifest/lint/TestManifestIssueRegistry.kt
index a0b10da..5879da0b 100644
--- a/compose/ui/ui-test-manifest-lint/src/main/java/androidx/compose/ui/test/manifest/lint/TestManifestIssueRegistry.kt
+++ b/compose/ui/ui-test-manifest-lint/src/main/java/androidx/compose/ui/test/manifest/lint/TestManifestIssueRegistry.kt
@@ -21,7 +21,7 @@
 import com.android.tools.lint.detector.api.CURRENT_API
 
 class TestManifestIssueRegistry : IssueRegistry() {
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(GradleDebugConfigurationDetector.ISSUE)
     override val vendor = Vendor(
diff --git a/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutComposeIssueRegistry.kt b/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutComposeIssueRegistry.kt
index f81e031..1aa437d 100644
--- a/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutComposeIssueRegistry.kt
+++ b/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutComposeIssueRegistry.kt
@@ -25,12 +25,14 @@
 private const val CL_COMPOSE_NEW_ISSUE = "new?component=323867&template=1023345"
 
 class ConstraintLayoutComposeIssueRegistry : IssueRegistry() {
-    override val api = 14
+    override val api = 13
 
     override val minApi = CURRENT_API
 
     override val issues = listOf(
-        ConstraintLayoutDslDetector.IncorrectReferencesDeclarationIssue
+        ConstraintLayoutDslDetector.IncorrectReferencesDeclarationIssue,
+        ConstraintLayoutDslDetector.IncorrectMatchParentUsageIssue,
+        ConstraintLayoutDslDetector.IncorrectChainMarginsUsageIssue
     )
 
     override val vendor = Vendor(
diff --git a/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetector.kt b/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetector.kt
index 647017d..81058d4 100644
--- a/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetector.kt
+++ b/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetector.kt
@@ -24,32 +24,231 @@
 import com.android.tools.lint.detector.api.Implementation
 import com.android.tools.lint.detector.api.Issue
 import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.LintFix
 import com.android.tools.lint.detector.api.Scope
 import com.android.tools.lint.detector.api.Severity
 import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.android.tools.lint.detector.api.UastLintUtils.Companion.tryResolveUDeclaration
 import java.util.EnumSet
 import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
 import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
+import org.jetbrains.uast.UBinaryExpression
+import org.jetbrains.uast.UBlockExpression
 import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UExpression
+import org.jetbrains.uast.ULambdaExpression
+import org.jetbrains.uast.UQualifiedReferenceExpression
+import org.jetbrains.uast.USimpleNameReferenceExpression
+import org.jetbrains.uast.getContainingUClass
+import org.jetbrains.uast.getParentOfType
+import org.jetbrains.uast.visitor.UastVisitor
+
+private const val CREATE_REFS_FOR_NAME = "createRefsFor"
+private const val MATCH_PARENT_NAME = "matchParent"
+private const val LINK_TO_NAME = "linkTo"
+private const val CENTER_TO_NAME = "centerTo"
+private const val CENTER_HORIZONTALLY_TO_NAME = "centerHorizontallyTo"
+private const val CENTER_VERTICALLY_TO_NAME = "centerVerticallyTo"
+private const val WIDTH_NAME = "width"
+private const val HEIGHT_NAME = "height"
+private const val PARENT_NAME = "parent"
+private const val CONSTRAIN_NAME = "constrain"
+private const val MARGIN_INDEX_IN_LINK_TO = 1
+private const val GONE_MARGIN_INDEX_IN_LINK_TO = 2
+private const val CREATE_HORIZONTAL_CHAIN_NAME = "createHorizontalChain"
+private const val CREATE_VERTICAL_CHAIN_NAME = "createVerticalChain"
+private const val WITH_CHAIN_PARAMS_NAME = "withChainParams"
+private const val CHAIN_PARAM_START_MARGIN_NAME = "startMargin"
+private const val CHAIN_PARAM_TOP_MARGIN_NAME = "topMargin"
+private const val CHAIN_PARAM_END_MARGIN_NAME = "endMargin"
+private const val CHAIN_PARAM_BOTTOM_MARGIN_NAME = "bottomMargin"
+private const val CHAIN_PARAM_START_GONE_MARGIN_NAME = "startGoneMargin"
+private const val CHAIN_PARAM_TOP_GONE_MARGIN_NAME = "topGoneMargin"
+private const val CHAIN_PARAM_END_GONE_MARGIN_NAME = "endGoneMargin"
+private const val CHAIN_PARAM_BOTTOM_GONE_MARGIN_NAME = "bottomGoneMargin"
+
+private const val CL_COMPOSE_DIMENSION_CLASS_NAME = "Dimension"
+
+private const val DIMENSION_MATCH_PARENT_EXPRESSION_NAME =
+    "$CL_COMPOSE_DIMENSION_CLASS_NAME.$MATCH_PARENT_NAME"
 
 private const val CL_COMPOSE_PACKAGE = "androidx.constraintlayout.compose"
 private const val CONSTRAINT_SET_SCOPE_CLASS_FQ = "$CL_COMPOSE_PACKAGE.ConstraintSetScope"
 private const val MOTION_SCENE_SCOPE_CLASS_FQ = "$CL_COMPOSE_PACKAGE.MotionSceneScope"
-private const val CREATE_REFS_FOR_NAME = "createRefsFor"
+private const val CONSTRAIN_SCOPE_CLASS_FQ = "$CL_COMPOSE_PACKAGE.ConstrainScope"
+private const val CONSTRAINED_LAYOUT_REFERENCE_CLASS_FQ =
+    "$CL_COMPOSE_PACKAGE.ConstrainedLayoutReference"
+private const val LAYOUT_REFERENCE_CLASS_FQ = "$CL_COMPOSE_PACKAGE.LayoutReference"
 
-class ConstraintLayoutDslDetector : Detector(), SourceCodeScanner {
-    private val knownOwnersOfCreateRefsFor = setOf(
+private val knownOwnersOfCreateRefsFor by lazy(LazyThreadSafetyMode.NONE) {
+    setOf(
         CONSTRAINT_SET_SCOPE_CLASS_FQ,
         MOTION_SCENE_SCOPE_CLASS_FQ
     )
+}
 
-    override fun getApplicableUastTypes() = listOf(UCallExpression::class.java)
+private val horizontalConstraintAnchors by lazy(LazyThreadSafetyMode.NONE) {
+    setOf(
+        "start",
+        "end",
+        "absoluteLeft",
+        "absoluteRight"
+    )
+}
+
+private val verticalConstraintAnchors by lazy(LazyThreadSafetyMode.NONE) {
+    setOf(
+        "top",
+        "bottom",
+    )
+}
+
+private val horizontalCenterMethodNames by lazy(LazyThreadSafetyMode.NONE) {
+    setOf(
+        CENTER_TO_NAME,
+        CENTER_HORIZONTALLY_TO_NAME,
+    )
+}
+
+private val verticalCenterMethodNames by lazy(LazyThreadSafetyMode.NONE) {
+    setOf(
+        CENTER_TO_NAME,
+        CENTER_VERTICALLY_TO_NAME,
+    )
+}
+
+class ConstraintLayoutDslDetector : Detector(), SourceCodeScanner {
+
+    // TODO: Add a case to detect use cases for `ConstrainedLayoutReference.withChainParams()`
+
+    override fun getApplicableUastTypes() =
+        listOf(UCallExpression::class.java, UBinaryExpression::class.java)
 
     override fun createUastHandler(context: JavaContext) = object : UElementHandler() {
+
+        /**
+         * Binary expressions are of the form `foo = bar`.
+         */
+        override fun visitBinaryExpression(node: UBinaryExpression) {
+            val assignedReferenceText = node.rightOperand.sourcePsi?.text ?: return
+
+            when (assignedReferenceText) {
+                DIMENSION_MATCH_PARENT_EXPRESSION_NAME -> detectMatchParentUsage(node)
+            }
+        }
+
         override fun visitCallExpression(node: UCallExpression) {
-            if (node.methodName != CREATE_REFS_FOR_NAME) {
+            when (node.methodName) {
+                CREATE_REFS_FOR_NAME -> detectCreateRefsForUsage(node)
+                CREATE_HORIZONTAL_CHAIN_NAME -> detectChainParamsUsage(node, true)
+                CREATE_VERTICAL_CHAIN_NAME -> detectChainParamsUsage(node, false)
+                // TODO: Detect that `withChainParams` is not called after chains are created
+            }
+        }
+
+        /**
+         * Verify correct usage of `Dimension.matchParent`.
+         *
+         * &nbsp;
+         *
+         * When using `Dimension.matchParent`, the user must be careful to not have custom
+         * constraints that result in different behavior from `centerTo(parent)`, otherwise, they
+         * should use `Dimension.percent(1f)` instead.
+         * ```
+         *  val (text, button) = createRefsFor("text", "button")
+         *  constrain(text) {
+         *      width = Dimension.matchParent
+         *
+         *      // Correct
+         *      start.linkTo(parent.start)
+         *      centerTo(parent)
+         *      centerHorizontallyTo(parent)
+         *
+         *      // Incorrect
+         *      start.linkTo(parent.end)
+         *      start.linkTo(button.start)
+         *      centerHorizontallyTo(button)
+         *      centerTo(button)
+         *  }
+         * ```
+         *
+         */
+        private fun detectMatchParentUsage(node: UBinaryExpression) {
+            val assigneeNode = node.leftOperand
+            val assigneeName = assigneeNode.sourcePsi?.text ?: return
+
+            // Must be assigned to either `width` or `height`
+            val isHorizontal: Boolean = when (assigneeName) {
+                WIDTH_NAME -> true
+                HEIGHT_NAME -> false
+                else -> return
+            }
+
+            // Verify that the context of this Expression is within ConstrainScope
+            if (assigneeNode.tryResolveUDeclaration()
+                    ?.getContainingUClass()?.qualifiedName != CONSTRAIN_SCOPE_CLASS_FQ
+            ) {
                 return
             }
+
+            val containingBlock = node.getParentOfType<UBlockExpression>() ?: return
+
+            // Within the Block, look for expressions supported for the check and immediately return
+            // if any of those expressions indicate bad usage of `Dimension.matchParent`
+            val containsErrorProneUsage = containingBlock.expressions.asSequence()
+                .mapNotNull { expression ->
+                    EvaluateableExpression.createForMatchParentUsage(
+                        expression = expression,
+                        isHorizontal = isHorizontal
+                    )
+                }
+                .any(EvaluateableExpression::isErrorProneForMatchParentUsage)
+
+            if (!containsErrorProneUsage) {
+                return
+            }
+
+            val overrideMethodName =
+                if (isHorizontal) CENTER_HORIZONTALLY_TO_NAME else CENTER_VERTICALLY_TO_NAME
+
+            context.report(
+                issue = IncorrectMatchParentUsageIssue,
+                scope = node.rightOperand,
+                location = context.getNameLocation(node.rightOperand),
+                message = "`Dimension.matchParent` will override constraints to an equivalent of " +
+                    "`$overrideMethodName(parent)`.\nUse `Dimension.percent(1f)` to respect " +
+                    "constraints.",
+                quickfixData = LintFix.create()
+                    .replace()
+                    .name("Replace `matchParent` with `percent(1f)`.")
+                    .range(context.getNameLocation(node.rightOperand))
+                    .all()
+                    .with("Dimension.percent(1f)")
+                    .autoFix()
+                    .build()
+            )
+        }
+
+        /**
+         * Verify correct usage of `createRefsFor("a", "b", "c")`.
+         *
+         * &nbsp;
+         *
+         * The number of assigned variables should match the number of given arguments:
+         * ```
+         * // Correct
+         * val (a, b, c) = createRefsFor("a", "b", "c")
+         *
+         * // Incorrect: Fewer variables than arguments
+         * val (a) = createRefsFor("a", "b", "c")
+         *
+         * // Incorrect: More variables than arguments
+         * val (a, b, c, d) = createRefsFor("a", "b", "c")
+         *
+         * ```
+         */
+        private fun detectCreateRefsForUsage(node: UCallExpression) {
             val destructuringDeclarationElement =
                 node.sourcePsi?.getParentOfType<KtDestructuringDeclaration>(true) ?: return
 
@@ -84,6 +283,140 @@
                     "assigned variables ($varsReceived)"
             )
         }
+
+        /**
+         * Verify that margins for chains are applied correctly.
+         *
+         * &nbsp;
+         *
+         * Margins for elements in chains should be applied with `LayoutReference.withChainParams()`
+         * instinctively, users may want to create constraints with margins that mimic the chain
+         * behavior expecting those margins to be reflected in the chain. But that is not the
+         * correct way to do it.
+         *
+         * So this check detects when users create chain-like constraints, and suggests to use
+         * `withChainParams()` and delete conflicting constraints, keeping the intended margins.
+         *
+         * &nbsp;
+         *
+         * Example:
+         *
+         * Before
+         * ```
+         * val (button, text) = createRefs()
+         * createHorizontalChain(button, text)
+         *
+         * constrain(button) {
+         *  end.linkTo(text.start, 8.dp)
+         *  end.linkTo(text.start, goneMargin = 16.dp)
+         * }
+         * ```
+         *
+         * After
+         * ```
+         * val (button, text) = createRefs()
+         * createHorizontalChain(button.withChainParams(endMargin = 8.dp, endGoneMargin = 16.dp), text)
+         *
+         * constrain(button) {
+         * }
+         * ```
+         */
+        private fun detectChainParamsUsage(node: UCallExpression, isHorizontal: Boolean) {
+            // TODO(b/268213648): Don't attempt to fix chain elements that already have
+            //  `withChainParams` that may have been defined elsewhere out of scope. A safe
+            //  path to take would be to look for the layout reference declaration, and skip this
+            //  check if it cannot be found within the current scope (code block). We could also try
+            //  to search within the shared scope of the layout reference and chain declarations,
+            //  but there's no straight-forward way to do it.
+
+            val containingBlock = node.getParentOfType<UBlockExpression>() ?: return
+
+            var previousNode: ChainNode? = null
+            val chainNodes = node.valueArguments
+                .filter(UExpression::isOfLayoutReferenceType)
+                .mapNotNull { argumentExpression ->
+                    argumentExpression.findChildIdentifier()?.let { identifier ->
+                        val chainNode = ChainNode(
+                            expression = identifier,
+                            hasChainParams = argumentExpression is UQualifiedReferenceExpression ||
+                                containingBlock.isChainParamsCalledInIdentifier(identifier)
+                        )
+                        previousNode?.let { prevNode ->
+                            chainNode.prev = prevNode
+                            prevNode.next = chainNode
+                        }
+                        previousNode = chainNode
+                        chainNode
+                    }
+                }
+
+            val resolvedChainLikeConstraintsPerNode = chainNodes.map {
+                if (it.hasChainParams) {
+                    emptyList()
+                } else {
+                    findChainLikeConstraints(containingBlock, it, isHorizontal)
+                }
+            }
+            resolvedChainLikeConstraintsPerNode.forEachIndexed { index, chainLikeExpressions ->
+                val chainParamsBuilder = ChainParamsMethodBuilder()
+                val removeLinkToFixes = chainLikeExpressions.map { resolvedExpression ->
+                    resolvedExpression.marginExpression?.let {
+                        chainParamsBuilder.append(
+                            resolvedExpression.marginParamName,
+                            resolvedExpression.marginExpression
+                        )
+                    }
+                    resolvedExpression.marginGoneExpression?.let {
+                        chainParamsBuilder.append(
+                            resolvedExpression.marginGoneParamName,
+                            resolvedExpression.marginGoneExpression
+                        )
+                    }
+                    val expressionToDelete =
+                        resolvedExpression
+                            .fullExpression
+                            .getParentOfType<UQualifiedReferenceExpression>()
+                    LintFix.create()
+                        .replace()
+                        .name("Remove conflicting `linkTo` declaration.")
+                        .range(context.getLocation(expressionToDelete))
+                        .all()
+                        .with("")
+                        .autoFix()
+                        .build()
+                }
+                val chainNode = chainNodes[index]
+                if (!chainParamsBuilder.isEmpty() && removeLinkToFixes.isNotEmpty()) {
+                    context.report(
+                        issue = IncorrectChainMarginsUsageIssue,
+                        scope = node,
+                        location = context.getLocation(chainNode.expression.sourcePsi),
+                        message = "Margins for elements in a Chain should be applied with " +
+                            "`LayoutReference.withChainParams(...)`.",
+                        quickfixData = LintFix.create()
+                            .composite()
+                            .name(
+                                "Add `.withChainParams(...)` and remove " +
+                                    "(${removeLinkToFixes.size}) conflicting `linkTo` declarations."
+                            )
+                            // `join` might overwrite previously added fixes, so add grouped fixes
+                            // first, then, add the remaining fixes individually with `add`
+                            .join(*removeLinkToFixes.toTypedArray())
+                            .add(
+                                LintFix.create()
+                                    .replace()
+                                    .name("Add `.withChainParams(...)`.")
+                                    .range(context.getLocation(chainNode.expression.sourcePsi))
+                                    .end()
+                                    .with(chainParamsBuilder.build())
+                                    .autoFix()
+                                    .build()
+                            )
+                            .build()
+                    )
+                }
+            }
+        }
     }
 
     companion object {
@@ -103,5 +436,328 @@
                 EnumSet.of(Scope.JAVA_FILE)
             )
         )
+
+        val IncorrectMatchParentUsageIssue = Issue.create(
+            id = "IncorrectMatchParentUsage",
+            briefDescription = "Prefer using `Dimension.percent(1f)` when defining custom " +
+                "constraints.",
+            explanation = "`Dimension.matchParent` forces the constraints to be an equivalent of " +
+                "`centerHorizontallyTo(parent)` or `centerVerticallyTo(parent)` according to the " +
+                "assigned dimension which can lead to unexpected behavior. To avoid that, prefer " +
+                "using `Dimension.percent(1f)`",
+            category = Category.CORRECTNESS,
+            priority = 5,
+            severity = Severity.WARNING,
+            implementation = Implementation(
+                ConstraintLayoutDslDetector::class.java,
+                EnumSet.of(Scope.JAVA_FILE)
+            )
+        )
+
+        val IncorrectChainMarginsUsageIssue = Issue.create(
+            id = "IncorrectChainMarginsUsage",
+            briefDescription = "Use `LayoutReference.withChainParams()` to define margins for " +
+                "elements in a Chain.",
+            explanation = "If you understand how a chain works, it might seem obvious to add " +
+                "margins by re-creating the constraints with the desired margin. However, in " +
+                "Compose, helpers will ignore custom constraints in favor of their layout " +
+                "implementation. So instead, use `LayoutReference.withChainParams()` " +
+                "to define margins for Chains.",
+            category = Category.CORRECTNESS,
+            priority = 5,
+            severity = Severity.WARNING,
+            implementation = Implementation(
+                ConstraintLayoutDslDetector::class.java,
+                EnumSet.of(Scope.JAVA_FILE)
+            )
+        )
     }
+}
+
+internal class EvaluateableExpression(
+    private val expectedArgumentText: String,
+    private val expression: UCallExpression
+) {
+    /**
+     * Should only return `true` when we know for certain that there's wrong usage.
+     *
+     * &nbsp;
+     *
+     * E.g.: For the following snippet we can't know if usage is incorrect since we don't know what
+     * the variable `targetAnchor` represents.
+     * ```
+     * width = Dimension.matchParent
+     *
+     * var targetAnchor: HorizontalAnchor
+     * start.linkTo(targetAnchor)
+     * ```
+     */
+    fun isErrorProneForMatchParentUsage(): Boolean {
+        val argumentText = expression.valueArguments.firstOrNull()?.sourcePsi?.text ?: return false
+        return argumentText != expectedArgumentText
+    }
+
+    companion object {
+        fun createForMatchParentUsage(
+            expression: UExpression,
+            isHorizontal: Boolean
+        ): EvaluateableExpression? {
+            if (expression is UQualifiedReferenceExpression) {
+                // For the form of `start.linkTo(parent.start)`
+
+                val callExpression = (expression.selector as? UCallExpression) ?: return null
+                if (callExpression.methodName != LINK_TO_NAME) {
+                    return null
+                }
+                val receiverAnchorName = expression.receiver.sourcePsi?.text ?: return null
+                val supportedAnchors =
+                    if (isHorizontal) horizontalConstraintAnchors else verticalConstraintAnchors
+                if (!supportedAnchors.contains(receiverAnchorName)) {
+                    return null
+                }
+                return EvaluateableExpression(
+                    expectedArgumentText = "$PARENT_NAME.$receiverAnchorName",
+                    expression = callExpression
+                )
+            } else if (expression is UCallExpression) {
+                // For the form of `centerTo(parent)`
+
+                val supportedMethodNames =
+                    if (isHorizontal) horizontalCenterMethodNames else verticalCenterMethodNames
+                val methodName = expression.methodName ?: return null
+                if (!supportedMethodNames.contains(methodName)) {
+                    return null
+                }
+                return EvaluateableExpression(
+                    expectedArgumentText = PARENT_NAME,
+                    expression = expression
+                )
+            }
+            return null
+        }
+    }
+}
+
+internal fun findChainLikeConstraints(
+    constraintSetBlock: UBlockExpression,
+    chainNode: ChainNode,
+    isHorizontal: Boolean
+): List<ResolvedChainLikeExpression> {
+    val identifier = chainNode.expression
+    val constrainTargetExpressions = constraintSetBlock.expressions.filter { cSetExpression ->
+        cSetExpression is UCallExpression && cSetExpression.methodName == CONSTRAIN_NAME &&
+            cSetExpression.valueArguments.any { argument ->
+                argument.sourcePsi?.text == identifier.identifier
+            }
+    }
+
+    val expectedAnchors =
+        if (isHorizontal) horizontalConstraintAnchors else verticalConstraintAnchors
+
+    return constrainTargetExpressions.asSequence().mapNotNull { constrainExpression ->
+        (constrainExpression as? UCallExpression)
+            ?.valueArguments
+            ?.filterIsInstance<ULambdaExpression>()
+            ?.lastOrNull()?.body as? UBlockExpression
+    }.flatMap {
+        it.expressions
+    }.filterIsInstance<UQualifiedReferenceExpression>().map {
+        it.selector
+    }.filterIsInstance<UCallExpression>().filter {
+        // No point in considering it if there's no margins applied
+        it.methodName == LINK_TO_NAME && it.valueArgumentCount >= 2
+    }.mapNotNull {
+        it.receiver?.sourcePsi?.text?.let { anchorName ->
+            if (expectedAnchors.contains(anchorName)) {
+                Pair(it, anchorName)
+            } else {
+                null
+            }
+        }
+    }.mapNotNull { (linkCallExpression, anchorName) ->
+        val nextIdentifier = chainNode.next?.expression?.identifier
+        val isNextParent = nextIdentifier == null
+
+        val prevIdentifier = chainNode.prev?.expression?.identifier
+        val isPrevParent = prevIdentifier == null
+        val expectedNextAnchorTo =
+            if (isNextParent) {
+                "parent.$anchorName"
+            } else {
+                "${nextIdentifier!!}.${anchorName.getOppositeAnchorName()}"
+            }
+        val expectedPrevAnchorTo =
+            if (isPrevParent) {
+                "parent.$anchorName"
+            } else {
+                "${prevIdentifier!!}.${anchorName.getOppositeAnchorName()}"
+            }
+
+        val targetAnchorExpressionText =
+            linkCallExpression.valueArguments[0].sourcePsi?.text
+        if (targetAnchorExpressionText == expectedPrevAnchorTo ||
+            targetAnchorExpressionText == expectedNextAnchorTo
+        ) {
+            ResolvedChainLikeExpression(
+                linkCallExpression,
+                anchorName,
+                linkCallExpression.getArgumentForParameter(MARGIN_INDEX_IN_LINK_TO),
+                linkCallExpression.getArgumentForParameter(GONE_MARGIN_INDEX_IN_LINK_TO)
+            )
+        } else {
+            null
+        }
+    }.toList()
+}
+
+internal class ChainNode(
+    val expression: USimpleNameReferenceExpression,
+    val hasChainParams: Boolean
+) {
+    var prev: ChainNode? = null
+    var next: ChainNode? = null
+}
+
+internal class ResolvedChainLikeExpression(
+    val fullExpression: UCallExpression,
+    anchorName: String,
+    val marginExpression: UExpression?,
+    val marginGoneExpression: UExpression?
+) {
+    val marginParamName: String = anchorName.asChainParamsArgument(false)
+    val marginGoneParamName: String = anchorName.asChainParamsArgument(true)
+}
+
+private fun String.getOppositeAnchorName() =
+    when (this) {
+        "start" -> "end"
+        "end" -> "start"
+        "absoluteLeft" -> "absoluteRight"
+        "absoluteRight" -> "absoluteLeft"
+        "top" -> "bottom"
+        "bottom" -> "top"
+        else -> "start"
+    }
+
+internal fun String.asChainParamsArgument(isGone: Boolean = false) =
+    if (!isGone) {
+        when (this) {
+            "absoluteLeft",
+            "start" -> CHAIN_PARAM_START_MARGIN_NAME
+
+            "absoluteRight",
+            "end" -> CHAIN_PARAM_END_MARGIN_NAME
+
+            "top" -> CHAIN_PARAM_TOP_MARGIN_NAME
+            "bottom" -> CHAIN_PARAM_BOTTOM_MARGIN_NAME
+            else -> CHAIN_PARAM_START_MARGIN_NAME
+        }
+    } else {
+        when (this) {
+            "absoluteLeft",
+            "start" -> CHAIN_PARAM_START_GONE_MARGIN_NAME
+
+            "absoluteRight",
+            "end" -> CHAIN_PARAM_END_GONE_MARGIN_NAME
+
+            "top" -> CHAIN_PARAM_TOP_GONE_MARGIN_NAME
+            "bottom" -> CHAIN_PARAM_BOTTOM_GONE_MARGIN_NAME
+            else -> CHAIN_PARAM_START_GONE_MARGIN_NAME
+        }
+    }
+
+internal fun UBlockExpression.isChainParamsCalledInIdentifier(
+    target: USimpleNameReferenceExpression
+): Boolean {
+    var found = false
+    this.accept(
+        object : UastVisitor {
+            override fun visitQualifiedReferenceExpression(
+                node: UQualifiedReferenceExpression
+            ): Boolean {
+                val identifier = (node.receiver as? USimpleNameReferenceExpression) ?: return true
+                if (identifier.identifier == target.identifier &&
+                    identifier.getExpressionType() == target.getExpressionType()) {
+                    val selector = node.selector
+                    if (selector is UCallExpression &&
+                        selector.methodName == WITH_CHAIN_PARAMS_NAME) {
+                        found = true
+                    } else {
+                        // skip
+                        return true
+                    }
+                } else {
+                    // skip
+                    return true
+                }
+                return super.visitQualifiedReferenceExpression(node)
+            }
+
+            override fun visitElement(node: UElement): Boolean {
+                return found
+            }
+        }
+    )
+    return found
+}
+
+internal class ChainParamsMethodBuilder {
+    private val modificationMap = mutableMapOf<String, UExpression>()
+
+    fun append(paramName: String, paramExpression: UExpression) {
+        modificationMap[paramName] = paramExpression
+    }
+
+    fun isEmpty() = modificationMap.isEmpty()
+
+    fun build(): String =
+        StringBuilder().apply {
+            append('.')
+            append(WITH_CHAIN_PARAMS_NAME)
+            append('(')
+            modificationMap.forEach { (paramName, uExpression) ->
+                uExpression.sourcePsi?.text?.let {
+                    append("$paramName = $it")
+                    append(", ")
+                }
+            }
+            deleteCharAt(this.lastIndex)
+            deleteCharAt(this.lastIndex)
+            append(')')
+        }.toString()
+}
+
+internal fun UExpression.findChildIdentifier(): USimpleNameReferenceExpression? {
+    var identifier: USimpleNameReferenceExpression? = null
+    this.accept(
+        object : UastVisitor {
+            override fun visitSimpleNameReferenceExpression(
+                node: USimpleNameReferenceExpression
+            ): Boolean {
+                if (node.isOfLayoutReferenceType()) {
+                    identifier = node
+                }
+                return true
+            }
+
+            // Only supported element to visit recursively, for the form of `textRef.withChainParams()`
+            override fun visitQualifiedReferenceExpression(
+                node: UQualifiedReferenceExpression
+            ): Boolean = false
+
+            override fun visitElement(node: UElement): Boolean = true
+        }
+    )
+    return identifier
+}
+
+/**
+ * Simple way to check if the Reference has a supported LayoutReference type. Note it does not do
+ * expression resolution and takes the type as is. So we have to manually check for inheritors of
+ * LayoutReference.
+ */
+internal fun UExpression.isOfLayoutReferenceType(): Boolean {
+    val typeName = this.getExpressionType()?.canonicalText ?: return false
+    return typeName == CONSTRAINED_LAYOUT_REFERENCE_CLASS_FQ ||
+        typeName == LAYOUT_REFERENCE_CLASS_FQ
 }
\ No newline at end of file
diff --git a/core/core-ktx/api/1.10.0-beta01.txt b/core/core-ktx/api/1.10.0-beta01.txt
new file mode 100644
index 0000000..801b56b
--- /dev/null
+++ b/core/core-ktx/api/1.10.0-beta01.txt
@@ -0,0 +1,634 @@
+// Signature format: 4.0
+package androidx.core.animation {
+
+  public final class AnimatorKt {
+    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onRepeat);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener addPauseListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onPause);
+    method public static inline android.animation.Animator.AnimatorListener doOnCancel(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnEnd(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener doOnPause(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnRepeat(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener doOnResume(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnStart(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content {
+
+  public final class ContentValuesKt {
+    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class ContextKt {
+    method public static inline <reified T> T! getSystemService(android.content.Context);
+    method public static inline void withStyledAttributes(android.content.Context, optional android.util.AttributeSet? set, int[] attrs, optional @AttrRes int defStyleAttr, optional @StyleRes int defStyleRes, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
+    method public static inline void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
+  }
+
+  public final class SharedPreferencesKt {
+    method public static inline void edit(android.content.SharedPreferences, optional boolean commit, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class TypedArrayKt {
+    method public static boolean getBooleanOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @ColorInt public static int getColorOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static android.content.res.ColorStateList getColorStateListOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static float getDimensionOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @Dimension public static int getDimensionPixelOffsetOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @Dimension public static int getDimensionPixelSizeOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static android.graphics.drawable.Drawable getDrawableOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static float getFloatOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @RequiresApi(26) public static android.graphics.Typeface getFontOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static int getIntOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static int getIntegerOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @AnyRes public static int getResourceIdOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+  }
+
+}
+
+package androidx.core.database {
+
+  public final class CursorKt {
+    method public static inline byte[]? getBlobOrNull(android.database.Cursor, int index);
+    method public static inline Double? getDoubleOrNull(android.database.Cursor, int index);
+    method public static inline Float? getFloatOrNull(android.database.Cursor, int index);
+    method public static inline Integer? getIntOrNull(android.database.Cursor, int index);
+    method public static inline Long? getLongOrNull(android.database.Cursor, int index);
+    method public static inline Short? getShortOrNull(android.database.Cursor, int index);
+    method public static inline String? getStringOrNull(android.database.Cursor, int index);
+  }
+
+}
+
+package androidx.core.database.sqlite {
+
+  public final class SQLiteDatabaseKt {
+    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapKt {
+    method public static inline android.graphics.Bitmap applyCanvas(android.graphics.Bitmap, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.Point p);
+    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.PointF p);
+    method public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config);
+    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config, optional boolean hasAlpha, optional android.graphics.ColorSpace colorSpace);
+    method public static inline operator int get(android.graphics.Bitmap, int x, int y);
+    method public static inline android.graphics.Bitmap scale(android.graphics.Bitmap, int width, int height, optional boolean filter);
+    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
+  }
+
+  public final class CanvasKt {
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.Rect clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.RectF clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, int left, int top, int right, int bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, float left, float top, float right, float bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.Path clipPath, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withMatrix(android.graphics.Canvas, optional android.graphics.Matrix matrix, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withRotation(android.graphics.Canvas, optional float degrees, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSave(android.graphics.Canvas, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withScale(android.graphics.Canvas, optional float x, optional float y, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSkew(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withTranslation(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class ColorKt {
+    method @RequiresApi(26) public static inline operator float component1(android.graphics.Color);
+    method public static inline operator int component1(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component1(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component2(android.graphics.Color);
+    method public static inline operator int component2(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component2(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component3(android.graphics.Color);
+    method public static inline operator int component3(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component3(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component4(android.graphics.Color);
+    method public static inline operator int component4(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component4(@ColorLong long);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace.Named colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace.Named colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace colorSpace);
+    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace.Named colorSpace);
+    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace colorSpace);
+    method public static inline int getAlpha(@ColorInt int);
+    method @RequiresApi(26) public static inline float getAlpha(@ColorLong long);
+    method public static inline int getBlue(@ColorInt int);
+    method @RequiresApi(26) public static inline float getBlue(@ColorLong long);
+    method @RequiresApi(26) public static inline android.graphics.ColorSpace getColorSpace(@ColorLong long);
+    method public static inline int getGreen(@ColorInt int);
+    method @RequiresApi(26) public static inline float getGreen(@ColorLong long);
+    method @RequiresApi(26) public static inline float getLuminance(@ColorInt int);
+    method @RequiresApi(26) public static inline float getLuminance(@ColorLong long);
+    method public static inline int getRed(@ColorInt int);
+    method @RequiresApi(26) public static inline float getRed(@ColorLong long);
+    method @RequiresApi(26) public static inline boolean isSrgb(@ColorLong long);
+    method @RequiresApi(26) public static inline boolean isWideGamut(@ColorLong long);
+    method @RequiresApi(26) public static operator android.graphics.Color plus(android.graphics.Color, android.graphics.Color c);
+    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorInt int);
+    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorLong long);
+    method @ColorInt @RequiresApi(26) public static inline int toColorInt(@ColorLong long);
+    method @ColorInt public static inline int toColorInt(String);
+    method @ColorLong @RequiresApi(26) public static inline long toColorLong(@ColorInt int);
+  }
+
+  public final class ImageDecoderKt {
+    method @RequiresApi(28) public static inline android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
+    method @RequiresApi(28) public static inline android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
+  }
+
+  public final class MatrixKt {
+    method public static android.graphics.Matrix rotationMatrix(float degrees, optional float px, optional float py);
+    method public static android.graphics.Matrix scaleMatrix(optional float sx, optional float sy);
+    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
+    method public static android.graphics.Matrix translationMatrix(optional float tx, optional float ty);
+    method public static inline float[] values(android.graphics.Matrix);
+  }
+
+  public final class PaintKt {
+    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+  }
+
+  public final class PathKt {
+    method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(26) public static Iterable<androidx.core.graphics.PathSegment> flatten(android.graphics.Path, optional float error);
+    method @RequiresApi(19) public static inline operator android.graphics.Path minus(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline infix android.graphics.Path or(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline operator android.graphics.Path plus(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline infix android.graphics.Path xor(android.graphics.Path, android.graphics.Path p);
+  }
+
+  public final class PictureKt {
+    method public static inline android.graphics.Picture record(android.graphics.Picture, int width, int height, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class PointKt {
+    method public static inline operator int component1(android.graphics.Point);
+    method public static inline operator float component1(android.graphics.PointF);
+    method public static inline operator int component2(android.graphics.Point);
+    method public static inline operator float component2(android.graphics.PointF);
+    method public static inline operator android.graphics.Point div(android.graphics.Point, float scalar);
+    method public static inline operator android.graphics.PointF div(android.graphics.PointF, float scalar);
+    method public static inline operator android.graphics.Point minus(android.graphics.Point, android.graphics.Point p);
+    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Point minus(android.graphics.Point, int xy);
+    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, float xy);
+    method public static inline operator android.graphics.Point plus(android.graphics.Point, android.graphics.Point p);
+    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Point plus(android.graphics.Point, int xy);
+    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, float xy);
+    method public static inline operator android.graphics.Point times(android.graphics.Point, float scalar);
+    method public static inline operator android.graphics.PointF times(android.graphics.PointF, float scalar);
+    method public static inline android.graphics.Point toPoint(android.graphics.PointF);
+    method public static inline android.graphics.PointF toPointF(android.graphics.Point);
+    method public static inline operator android.graphics.Point unaryMinus(android.graphics.Point);
+    method public static inline operator android.graphics.PointF unaryMinus(android.graphics.PointF);
+  }
+
+  public final class PorterDuffKt {
+    method public static inline android.graphics.PorterDuffColorFilter toColorFilter(android.graphics.PorterDuff.Mode, int color);
+    method public static inline android.graphics.PorterDuffXfermode toXfermode(android.graphics.PorterDuff.Mode);
+  }
+
+  public final class RectKt {
+    method public static inline infix android.graphics.Rect and(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.RectF and(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator int component1(android.graphics.Rect);
+    method public static inline operator float component1(android.graphics.RectF);
+    method public static inline operator int component2(android.graphics.Rect);
+    method public static inline operator float component2(android.graphics.RectF);
+    method public static inline operator int component3(android.graphics.Rect);
+    method public static inline operator float component3(android.graphics.RectF);
+    method public static inline operator int component4(android.graphics.Rect);
+    method public static inline operator float component4(android.graphics.RectF);
+    method public static inline operator boolean contains(android.graphics.Rect, android.graphics.Point p);
+    method public static inline operator boolean contains(android.graphics.RectF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Region minus(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region minus(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, int xy);
+    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, float xy);
+    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, android.graphics.Point xy);
+    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, android.graphics.PointF xy);
+    method public static inline infix android.graphics.Rect or(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.RectF or(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, int xy);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, float xy);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Point xy);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.PointF xy);
+    method public static inline operator android.graphics.Rect times(android.graphics.Rect, int factor);
+    method public static inline operator android.graphics.RectF times(android.graphics.RectF, int factor);
+    method public static inline operator android.graphics.RectF times(android.graphics.RectF, float factor);
+    method public static inline android.graphics.Rect toRect(android.graphics.RectF);
+    method public static inline android.graphics.RectF toRectF(android.graphics.Rect);
+    method public static inline android.graphics.Region toRegion(android.graphics.Rect);
+    method public static inline android.graphics.Region toRegion(android.graphics.RectF);
+    method public static inline android.graphics.RectF transform(android.graphics.RectF, android.graphics.Matrix m);
+    method public static inline infix android.graphics.Region xor(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region xor(android.graphics.RectF, android.graphics.RectF r);
+  }
+
+  public final class RegionKt {
+    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator boolean contains(android.graphics.Region, android.graphics.Point p);
+    method public static inline void forEach(android.graphics.Region, kotlin.jvm.functions.Function1<? super android.graphics.Rect,kotlin.Unit> action);
+    method public static operator java.util.Iterator<android.graphics.Rect> iterator(android.graphics.Region);
+    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region not(android.graphics.Region);
+    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region unaryMinus(android.graphics.Region);
+    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Region r);
+  }
+
+  public final class ShaderKt {
+    method public static inline void transform(android.graphics.Shader, kotlin.jvm.functions.Function1<? super android.graphics.Matrix,kotlin.Unit> block);
+  }
+
+}
+
+package androidx.core.graphics.drawable {
+
+  public final class BitmapDrawableKt {
+    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
+  }
+
+  public final class ColorDrawableKt {
+    method public static inline android.graphics.drawable.ColorDrawable toDrawable(@ColorInt int);
+    method @RequiresApi(26) public static inline android.graphics.drawable.ColorDrawable toDrawable(android.graphics.Color);
+  }
+
+  public final class DrawableKt {
+    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
+    method public static android.graphics.Bitmap? toBitmapOrNull(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
+    method public static void updateBounds(android.graphics.drawable.Drawable, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+  }
+
+  public final class IconKt {
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toAdaptiveIcon(android.graphics.Bitmap);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.graphics.Bitmap);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.net.Uri);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(byte[]);
+  }
+
+}
+
+package androidx.core.location {
+
+  public final class LocationKt {
+    method public static inline operator double component1(android.location.Location);
+    method public static inline operator double component2(android.location.Location);
+  }
+
+}
+
+package androidx.core.net {
+
+  public final class UriKt {
+    method public static java.io.File toFile(android.net.Uri);
+    method public static inline android.net.Uri toUri(String);
+    method public static inline android.net.Uri toUri(java.io.File);
+  }
+
+}
+
+package androidx.core.os {
+
+  public final class BundleKt {
+    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+    method public static android.os.Bundle bundleOf();
+  }
+
+  public final class HandlerKt {
+    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+  }
+
+  @RequiresApi(31) public final class OutcomeReceiverKt {
+    method @RequiresApi(31) public static <R, E extends java.lang.Throwable> android.os.OutcomeReceiver<R,E> asOutcomeReceiver(kotlin.coroutines.Continuation<? super R>);
+  }
+
+  public final class PersistableBundleKt {
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf();
+    method @RequiresApi(21) public static android.os.PersistableBundle toPersistableBundle(java.util.Map<java.lang.String,?>);
+  }
+
+  public final class TraceKt {
+    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class CharSequenceKt {
+    method public static inline boolean isDigitsOnly(CharSequence);
+    method public static inline int trimmedLength(CharSequence);
+  }
+
+  public final class HtmlKt {
+    method public static inline android.text.Spanned parseAsHtml(String, optional int flags, optional android.text.Html.ImageGetter? imageGetter, optional android.text.Html.TagHandler? tagHandler);
+    method public static inline String toHtml(android.text.Spanned, optional int option);
+  }
+
+  public final class LocaleKt {
+    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
+  }
+
+  public final class SpannableStringBuilderKt {
+    method public static inline android.text.SpannableStringBuilder backgroundColor(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder bold(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannedString buildSpannedString(kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder color(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object![] spans, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object span, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+  }
+
+  public final class SpannableStringKt {
+    method public static inline void clearSpans(android.text.Spannable);
+    method public static inline operator void set(android.text.Spannable, int start, int end, Object span);
+    method public static inline operator void set(android.text.Spannable, kotlin.ranges.IntRange range, Object span);
+    method public static inline android.text.Spannable toSpannable(CharSequence);
+  }
+
+  public final class SpannedStringKt {
+    method public static inline <reified T> T![] getSpans(android.text.Spanned, optional int start, optional int end);
+    method public static inline android.text.Spanned toSpanned(CharSequence);
+  }
+
+  public final class StringKt {
+    method public static inline String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.transition {
+
+  public final class TransitionKt {
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onPause);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnCancel(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnEnd(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnPause(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnResume(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnStart(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.util {
+
+  public final class AndroidXConsumerKt {
+    method public static <T> androidx.core.util.Consumer<T> asAndroidXConsumer(kotlin.coroutines.Continuation<? super T>);
+  }
+
+  public final class AtomicFileKt {
+    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
+    method @RequiresApi(17) public static String readText(android.util.AtomicFile, optional java.nio.charset.Charset charset);
+    method @RequiresApi(17) public static inline void tryWrite(android.util.AtomicFile, kotlin.jvm.functions.Function1<? super java.io.FileOutputStream,kotlin.Unit> block);
+    method @RequiresApi(17) public static void writeBytes(android.util.AtomicFile, byte[] array);
+    method @RequiresApi(17) public static void writeText(android.util.AtomicFile, String text, optional java.nio.charset.Charset charset);
+  }
+
+  @RequiresApi(24) public final class ConsumerKt {
+    method @RequiresApi(24) public static <T> java.util.function.Consumer<T> asConsumer(kotlin.coroutines.Continuation<? super T>);
+  }
+
+  public final class HalfKt {
+    method @RequiresApi(26) public static inline android.util.Half toHalf(@HalfFloat short);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(float);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(double);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(String);
+  }
+
+  public final class LongSparseArrayKt {
+    method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
+    method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
+    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+    method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
+    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
+    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
+    method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
+    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
+  }
+
+  public final class LruCacheKt {
+    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
+  }
+
+  public final class PairKt {
+    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
+    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+    method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
+    method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
+    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
+    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
+  }
+
+  public final class RangeKt {
+    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> and(android.util.Range<T>, android.util.Range<T> other);
+    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, T value);
+    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, android.util.Range<T> other);
+    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> rangeTo(T, T that);
+    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> kotlin.ranges.ClosedRange<T> toClosedRange(android.util.Range<T>);
+    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> android.util.Range<T> toRange(kotlin.ranges.ClosedRange<T>);
+  }
+
+  public final class RunnableKt {
+    method public static Runnable asRunnable(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class SizeKt {
+    method @RequiresApi(21) public static inline operator int component1(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component1(android.util.SizeF);
+    method public static inline operator float component1(androidx.core.util.SizeFCompat);
+    method @RequiresApi(21) public static inline operator int component2(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
+    method public static inline operator float component2(androidx.core.util.SizeFCompat);
+  }
+
+  public final class SparseArrayKt {
+    method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
+    method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
+    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+    method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
+    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
+    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> int getSize(android.util.SparseArray<T>);
+    method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
+    method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
+    method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
+    method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
+    method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
+    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
+    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+    method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
+  }
+
+  public final class SparseBooleanArrayKt {
+    method public static inline operator boolean contains(android.util.SparseBooleanArray, int key);
+    method public static inline boolean containsKey(android.util.SparseBooleanArray, int key);
+    method public static inline boolean containsValue(android.util.SparseBooleanArray, boolean value);
+    method public static inline void forEach(android.util.SparseBooleanArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,kotlin.Unit> action);
+    method public static inline boolean getOrDefault(android.util.SparseBooleanArray, int key, boolean defaultValue);
+    method public static inline boolean getOrElse(android.util.SparseBooleanArray, int key, kotlin.jvm.functions.Function0<java.lang.Boolean> defaultValue);
+    method public static inline int getSize(android.util.SparseBooleanArray);
+    method public static inline boolean isEmpty(android.util.SparseBooleanArray);
+    method public static inline boolean isNotEmpty(android.util.SparseBooleanArray);
+    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseBooleanArray);
+    method public static operator android.util.SparseBooleanArray plus(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
+    method public static void putAll(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
+    method public static boolean remove(android.util.SparseBooleanArray, int key, boolean value);
+    method public static inline operator void set(android.util.SparseBooleanArray, int key, boolean value);
+    method public static kotlin.collections.BooleanIterator valueIterator(android.util.SparseBooleanArray);
+  }
+
+  public final class SparseIntArrayKt {
+    method public static inline operator boolean contains(android.util.SparseIntArray, int key);
+    method public static inline boolean containsKey(android.util.SparseIntArray, int key);
+    method public static inline boolean containsValue(android.util.SparseIntArray, int value);
+    method public static inline void forEach(android.util.SparseIntArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+    method public static inline int getOrDefault(android.util.SparseIntArray, int key, int defaultValue);
+    method public static inline int getOrElse(android.util.SparseIntArray, int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public static inline int getSize(android.util.SparseIntArray);
+    method public static inline boolean isEmpty(android.util.SparseIntArray);
+    method public static inline boolean isNotEmpty(android.util.SparseIntArray);
+    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseIntArray);
+    method public static operator android.util.SparseIntArray plus(android.util.SparseIntArray, android.util.SparseIntArray other);
+    method public static void putAll(android.util.SparseIntArray, android.util.SparseIntArray other);
+    method public static boolean remove(android.util.SparseIntArray, int key, int value);
+    method public static inline operator void set(android.util.SparseIntArray, int key, int value);
+    method public static kotlin.collections.IntIterator valueIterator(android.util.SparseIntArray);
+  }
+
+  public final class SparseLongArrayKt {
+    method @RequiresApi(18) public static inline operator boolean contains(android.util.SparseLongArray, int key);
+    method @RequiresApi(18) public static inline boolean containsKey(android.util.SparseLongArray, int key);
+    method @RequiresApi(18) public static inline boolean containsValue(android.util.SparseLongArray, long value);
+    method @RequiresApi(18) public static inline void forEach(android.util.SparseLongArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> action);
+    method @RequiresApi(18) public static inline long getOrDefault(android.util.SparseLongArray, int key, long defaultValue);
+    method @RequiresApi(18) public static inline long getOrElse(android.util.SparseLongArray, int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method @RequiresApi(18) public static inline int getSize(android.util.SparseLongArray);
+    method @RequiresApi(18) public static inline boolean isEmpty(android.util.SparseLongArray);
+    method @RequiresApi(18) public static inline boolean isNotEmpty(android.util.SparseLongArray);
+    method @RequiresApi(18) public static kotlin.collections.IntIterator keyIterator(android.util.SparseLongArray);
+    method @RequiresApi(18) public static operator android.util.SparseLongArray plus(android.util.SparseLongArray, android.util.SparseLongArray other);
+    method @RequiresApi(18) public static void putAll(android.util.SparseLongArray, android.util.SparseLongArray other);
+    method @RequiresApi(18) public static boolean remove(android.util.SparseLongArray, int key, long value);
+    method @RequiresApi(18) public static inline operator void set(android.util.SparseLongArray, int key, long value);
+    method @RequiresApi(18) public static kotlin.collections.LongIterator valueIterator(android.util.SparseLongArray);
+  }
+
+}
+
+package androidx.core.view {
+
+  public final class MenuKt {
+    method public static operator boolean contains(android.view.Menu, android.view.MenuItem item);
+    method public static inline void forEach(android.view.Menu, kotlin.jvm.functions.Function1<? super android.view.MenuItem,kotlin.Unit> action);
+    method public static inline void forEachIndexed(android.view.Menu, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.MenuItem,kotlin.Unit> action);
+    method public static inline operator android.view.MenuItem get(android.view.Menu, int index);
+    method public static kotlin.sequences.Sequence<android.view.MenuItem> getChildren(android.view.Menu);
+    method public static inline int getSize(android.view.Menu);
+    method public static inline boolean isEmpty(android.view.Menu);
+    method public static inline boolean isNotEmpty(android.view.Menu);
+    method public static operator java.util.Iterator<android.view.MenuItem> iterator(android.view.Menu);
+    method public static inline operator void minusAssign(android.view.Menu, android.view.MenuItem item);
+    method public static inline void removeItemAt(android.view.Menu, int index);
+  }
+
+  public final class ViewGroupKt {
+    method public static inline operator boolean contains(android.view.ViewGroup, android.view.View view);
+    method public static inline void forEach(android.view.ViewGroup, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void forEachIndexed(android.view.ViewGroup, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.View,kotlin.Unit> action);
+    method public static operator android.view.View get(android.view.ViewGroup, int index);
+    method public static kotlin.sequences.Sequence<android.view.View> getChildren(android.view.ViewGroup);
+    method public static kotlin.sequences.Sequence<android.view.View> getDescendants(android.view.ViewGroup);
+    method public static inline kotlin.ranges.IntRange getIndices(android.view.ViewGroup);
+    method public static inline int getSize(android.view.ViewGroup);
+    method public static inline boolean isEmpty(android.view.ViewGroup);
+    method public static inline boolean isNotEmpty(android.view.ViewGroup);
+    method public static operator java.util.Iterator<android.view.View> iterator(android.view.ViewGroup);
+    method public static inline operator void minusAssign(android.view.ViewGroup, android.view.View view);
+    method public static inline operator void plusAssign(android.view.ViewGroup, android.view.View view);
+    method public static inline void setMargins(android.view.ViewGroup.MarginLayoutParams, @Px int size);
+    method public static inline void updateMargins(android.view.ViewGroup.MarginLayoutParams, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
+  }
+
+  public final class ViewKt {
+    method public static inline void doOnAttach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnDetach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnNextLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline androidx.core.view.OneShotPreDrawListener doOnPreDraw(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static android.graphics.Bitmap drawToBitmap(android.view.View, optional android.graphics.Bitmap.Config config);
+    method public static kotlin.sequences.Sequence<android.view.View> getAllViews(android.view.View);
+    method public static kotlin.sequences.Sequence<android.view.ViewParent> getAncestors(android.view.View);
+    method public static inline int getMarginBottom(android.view.View);
+    method public static inline int getMarginEnd(android.view.View);
+    method public static inline int getMarginLeft(android.view.View);
+    method public static inline int getMarginRight(android.view.View);
+    method public static inline int getMarginStart(android.view.View);
+    method public static inline int getMarginTop(android.view.View);
+    method public static inline boolean isGone(android.view.View);
+    method public static inline boolean isInvisible(android.view.View);
+    method public static inline boolean isVisible(android.view.View);
+    method public static inline Runnable postDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method @RequiresApi(16) public static Runnable postOnAnimationDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline void setGone(android.view.View, boolean);
+    method public static inline void setInvisible(android.view.View, boolean);
+    method public static inline void setPadding(android.view.View, @Px int size);
+    method public static inline void setVisible(android.view.View, boolean);
+    method public static inline void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super android.view.ViewGroup.LayoutParams,kotlin.Unit> block);
+    method public static inline <reified T extends android.view.ViewGroup.LayoutParams> void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> block);
+    method public static inline void updatePadding(android.view.View, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public final class TextViewKt {
+    method public static inline android.text.TextWatcher addTextChangedListener(android.widget.TextView, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> beforeTextChanged, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged, optional kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> afterTextChanged);
+    method public static inline android.text.TextWatcher doAfterTextChanged(android.widget.TextView, kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> action);
+    method public static inline android.text.TextWatcher doBeforeTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+    method public static inline android.text.TextWatcher doOnTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+  }
+
+}
+
diff --git a/core/core-ktx/api/public_plus_experimental_1.10.0-beta01.txt b/core/core-ktx/api/public_plus_experimental_1.10.0-beta01.txt
new file mode 100644
index 0000000..801b56b
--- /dev/null
+++ b/core/core-ktx/api/public_plus_experimental_1.10.0-beta01.txt
@@ -0,0 +1,634 @@
+// Signature format: 4.0
+package androidx.core.animation {
+
+  public final class AnimatorKt {
+    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onRepeat);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener addPauseListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onPause);
+    method public static inline android.animation.Animator.AnimatorListener doOnCancel(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnEnd(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener doOnPause(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnRepeat(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener doOnResume(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnStart(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content {
+
+  public final class ContentValuesKt {
+    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class ContextKt {
+    method public static inline <reified T> T! getSystemService(android.content.Context);
+    method public static inline void withStyledAttributes(android.content.Context, optional android.util.AttributeSet? set, int[] attrs, optional @AttrRes int defStyleAttr, optional @StyleRes int defStyleRes, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
+    method public static inline void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
+  }
+
+  public final class SharedPreferencesKt {
+    method public static inline void edit(android.content.SharedPreferences, optional boolean commit, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class TypedArrayKt {
+    method public static boolean getBooleanOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @ColorInt public static int getColorOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static android.content.res.ColorStateList getColorStateListOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static float getDimensionOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @Dimension public static int getDimensionPixelOffsetOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @Dimension public static int getDimensionPixelSizeOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static android.graphics.drawable.Drawable getDrawableOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static float getFloatOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @RequiresApi(26) public static android.graphics.Typeface getFontOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static int getIntOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static int getIntegerOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @AnyRes public static int getResourceIdOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+  }
+
+}
+
+package androidx.core.database {
+
+  public final class CursorKt {
+    method public static inline byte[]? getBlobOrNull(android.database.Cursor, int index);
+    method public static inline Double? getDoubleOrNull(android.database.Cursor, int index);
+    method public static inline Float? getFloatOrNull(android.database.Cursor, int index);
+    method public static inline Integer? getIntOrNull(android.database.Cursor, int index);
+    method public static inline Long? getLongOrNull(android.database.Cursor, int index);
+    method public static inline Short? getShortOrNull(android.database.Cursor, int index);
+    method public static inline String? getStringOrNull(android.database.Cursor, int index);
+  }
+
+}
+
+package androidx.core.database.sqlite {
+
+  public final class SQLiteDatabaseKt {
+    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapKt {
+    method public static inline android.graphics.Bitmap applyCanvas(android.graphics.Bitmap, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.Point p);
+    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.PointF p);
+    method public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config);
+    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config, optional boolean hasAlpha, optional android.graphics.ColorSpace colorSpace);
+    method public static inline operator int get(android.graphics.Bitmap, int x, int y);
+    method public static inline android.graphics.Bitmap scale(android.graphics.Bitmap, int width, int height, optional boolean filter);
+    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
+  }
+
+  public final class CanvasKt {
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.Rect clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.RectF clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, int left, int top, int right, int bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, float left, float top, float right, float bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.Path clipPath, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withMatrix(android.graphics.Canvas, optional android.graphics.Matrix matrix, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withRotation(android.graphics.Canvas, optional float degrees, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSave(android.graphics.Canvas, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withScale(android.graphics.Canvas, optional float x, optional float y, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSkew(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withTranslation(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class ColorKt {
+    method @RequiresApi(26) public static inline operator float component1(android.graphics.Color);
+    method public static inline operator int component1(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component1(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component2(android.graphics.Color);
+    method public static inline operator int component2(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component2(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component3(android.graphics.Color);
+    method public static inline operator int component3(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component3(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component4(android.graphics.Color);
+    method public static inline operator int component4(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component4(@ColorLong long);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace.Named colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace.Named colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace colorSpace);
+    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace.Named colorSpace);
+    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace colorSpace);
+    method public static inline int getAlpha(@ColorInt int);
+    method @RequiresApi(26) public static inline float getAlpha(@ColorLong long);
+    method public static inline int getBlue(@ColorInt int);
+    method @RequiresApi(26) public static inline float getBlue(@ColorLong long);
+    method @RequiresApi(26) public static inline android.graphics.ColorSpace getColorSpace(@ColorLong long);
+    method public static inline int getGreen(@ColorInt int);
+    method @RequiresApi(26) public static inline float getGreen(@ColorLong long);
+    method @RequiresApi(26) public static inline float getLuminance(@ColorInt int);
+    method @RequiresApi(26) public static inline float getLuminance(@ColorLong long);
+    method public static inline int getRed(@ColorInt int);
+    method @RequiresApi(26) public static inline float getRed(@ColorLong long);
+    method @RequiresApi(26) public static inline boolean isSrgb(@ColorLong long);
+    method @RequiresApi(26) public static inline boolean isWideGamut(@ColorLong long);
+    method @RequiresApi(26) public static operator android.graphics.Color plus(android.graphics.Color, android.graphics.Color c);
+    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorInt int);
+    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorLong long);
+    method @ColorInt @RequiresApi(26) public static inline int toColorInt(@ColorLong long);
+    method @ColorInt public static inline int toColorInt(String);
+    method @ColorLong @RequiresApi(26) public static inline long toColorLong(@ColorInt int);
+  }
+
+  public final class ImageDecoderKt {
+    method @RequiresApi(28) public static inline android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
+    method @RequiresApi(28) public static inline android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
+  }
+
+  public final class MatrixKt {
+    method public static android.graphics.Matrix rotationMatrix(float degrees, optional float px, optional float py);
+    method public static android.graphics.Matrix scaleMatrix(optional float sx, optional float sy);
+    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
+    method public static android.graphics.Matrix translationMatrix(optional float tx, optional float ty);
+    method public static inline float[] values(android.graphics.Matrix);
+  }
+
+  public final class PaintKt {
+    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+  }
+
+  public final class PathKt {
+    method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(26) public static Iterable<androidx.core.graphics.PathSegment> flatten(android.graphics.Path, optional float error);
+    method @RequiresApi(19) public static inline operator android.graphics.Path minus(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline infix android.graphics.Path or(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline operator android.graphics.Path plus(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline infix android.graphics.Path xor(android.graphics.Path, android.graphics.Path p);
+  }
+
+  public final class PictureKt {
+    method public static inline android.graphics.Picture record(android.graphics.Picture, int width, int height, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class PointKt {
+    method public static inline operator int component1(android.graphics.Point);
+    method public static inline operator float component1(android.graphics.PointF);
+    method public static inline operator int component2(android.graphics.Point);
+    method public static inline operator float component2(android.graphics.PointF);
+    method public static inline operator android.graphics.Point div(android.graphics.Point, float scalar);
+    method public static inline operator android.graphics.PointF div(android.graphics.PointF, float scalar);
+    method public static inline operator android.graphics.Point minus(android.graphics.Point, android.graphics.Point p);
+    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Point minus(android.graphics.Point, int xy);
+    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, float xy);
+    method public static inline operator android.graphics.Point plus(android.graphics.Point, android.graphics.Point p);
+    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Point plus(android.graphics.Point, int xy);
+    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, float xy);
+    method public static inline operator android.graphics.Point times(android.graphics.Point, float scalar);
+    method public static inline operator android.graphics.PointF times(android.graphics.PointF, float scalar);
+    method public static inline android.graphics.Point toPoint(android.graphics.PointF);
+    method public static inline android.graphics.PointF toPointF(android.graphics.Point);
+    method public static inline operator android.graphics.Point unaryMinus(android.graphics.Point);
+    method public static inline operator android.graphics.PointF unaryMinus(android.graphics.PointF);
+  }
+
+  public final class PorterDuffKt {
+    method public static inline android.graphics.PorterDuffColorFilter toColorFilter(android.graphics.PorterDuff.Mode, int color);
+    method public static inline android.graphics.PorterDuffXfermode toXfermode(android.graphics.PorterDuff.Mode);
+  }
+
+  public final class RectKt {
+    method public static inline infix android.graphics.Rect and(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.RectF and(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator int component1(android.graphics.Rect);
+    method public static inline operator float component1(android.graphics.RectF);
+    method public static inline operator int component2(android.graphics.Rect);
+    method public static inline operator float component2(android.graphics.RectF);
+    method public static inline operator int component3(android.graphics.Rect);
+    method public static inline operator float component3(android.graphics.RectF);
+    method public static inline operator int component4(android.graphics.Rect);
+    method public static inline operator float component4(android.graphics.RectF);
+    method public static inline operator boolean contains(android.graphics.Rect, android.graphics.Point p);
+    method public static inline operator boolean contains(android.graphics.RectF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Region minus(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region minus(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, int xy);
+    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, float xy);
+    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, android.graphics.Point xy);
+    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, android.graphics.PointF xy);
+    method public static inline infix android.graphics.Rect or(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.RectF or(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, int xy);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, float xy);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Point xy);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.PointF xy);
+    method public static inline operator android.graphics.Rect times(android.graphics.Rect, int factor);
+    method public static inline operator android.graphics.RectF times(android.graphics.RectF, int factor);
+    method public static inline operator android.graphics.RectF times(android.graphics.RectF, float factor);
+    method public static inline android.graphics.Rect toRect(android.graphics.RectF);
+    method public static inline android.graphics.RectF toRectF(android.graphics.Rect);
+    method public static inline android.graphics.Region toRegion(android.graphics.Rect);
+    method public static inline android.graphics.Region toRegion(android.graphics.RectF);
+    method public static inline android.graphics.RectF transform(android.graphics.RectF, android.graphics.Matrix m);
+    method public static inline infix android.graphics.Region xor(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region xor(android.graphics.RectF, android.graphics.RectF r);
+  }
+
+  public final class RegionKt {
+    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator boolean contains(android.graphics.Region, android.graphics.Point p);
+    method public static inline void forEach(android.graphics.Region, kotlin.jvm.functions.Function1<? super android.graphics.Rect,kotlin.Unit> action);
+    method public static operator java.util.Iterator<android.graphics.Rect> iterator(android.graphics.Region);
+    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region not(android.graphics.Region);
+    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region unaryMinus(android.graphics.Region);
+    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Region r);
+  }
+
+  public final class ShaderKt {
+    method public static inline void transform(android.graphics.Shader, kotlin.jvm.functions.Function1<? super android.graphics.Matrix,kotlin.Unit> block);
+  }
+
+}
+
+package androidx.core.graphics.drawable {
+
+  public final class BitmapDrawableKt {
+    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
+  }
+
+  public final class ColorDrawableKt {
+    method public static inline android.graphics.drawable.ColorDrawable toDrawable(@ColorInt int);
+    method @RequiresApi(26) public static inline android.graphics.drawable.ColorDrawable toDrawable(android.graphics.Color);
+  }
+
+  public final class DrawableKt {
+    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
+    method public static android.graphics.Bitmap? toBitmapOrNull(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
+    method public static void updateBounds(android.graphics.drawable.Drawable, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+  }
+
+  public final class IconKt {
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toAdaptiveIcon(android.graphics.Bitmap);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.graphics.Bitmap);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.net.Uri);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(byte[]);
+  }
+
+}
+
+package androidx.core.location {
+
+  public final class LocationKt {
+    method public static inline operator double component1(android.location.Location);
+    method public static inline operator double component2(android.location.Location);
+  }
+
+}
+
+package androidx.core.net {
+
+  public final class UriKt {
+    method public static java.io.File toFile(android.net.Uri);
+    method public static inline android.net.Uri toUri(String);
+    method public static inline android.net.Uri toUri(java.io.File);
+  }
+
+}
+
+package androidx.core.os {
+
+  public final class BundleKt {
+    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+    method public static android.os.Bundle bundleOf();
+  }
+
+  public final class HandlerKt {
+    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+  }
+
+  @RequiresApi(31) public final class OutcomeReceiverKt {
+    method @RequiresApi(31) public static <R, E extends java.lang.Throwable> android.os.OutcomeReceiver<R,E> asOutcomeReceiver(kotlin.coroutines.Continuation<? super R>);
+  }
+
+  public final class PersistableBundleKt {
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf();
+    method @RequiresApi(21) public static android.os.PersistableBundle toPersistableBundle(java.util.Map<java.lang.String,?>);
+  }
+
+  public final class TraceKt {
+    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class CharSequenceKt {
+    method public static inline boolean isDigitsOnly(CharSequence);
+    method public static inline int trimmedLength(CharSequence);
+  }
+
+  public final class HtmlKt {
+    method public static inline android.text.Spanned parseAsHtml(String, optional int flags, optional android.text.Html.ImageGetter? imageGetter, optional android.text.Html.TagHandler? tagHandler);
+    method public static inline String toHtml(android.text.Spanned, optional int option);
+  }
+
+  public final class LocaleKt {
+    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
+  }
+
+  public final class SpannableStringBuilderKt {
+    method public static inline android.text.SpannableStringBuilder backgroundColor(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder bold(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannedString buildSpannedString(kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder color(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object![] spans, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object span, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+  }
+
+  public final class SpannableStringKt {
+    method public static inline void clearSpans(android.text.Spannable);
+    method public static inline operator void set(android.text.Spannable, int start, int end, Object span);
+    method public static inline operator void set(android.text.Spannable, kotlin.ranges.IntRange range, Object span);
+    method public static inline android.text.Spannable toSpannable(CharSequence);
+  }
+
+  public final class SpannedStringKt {
+    method public static inline <reified T> T![] getSpans(android.text.Spanned, optional int start, optional int end);
+    method public static inline android.text.Spanned toSpanned(CharSequence);
+  }
+
+  public final class StringKt {
+    method public static inline String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.transition {
+
+  public final class TransitionKt {
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onPause);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnCancel(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnEnd(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnPause(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnResume(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnStart(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.util {
+
+  public final class AndroidXConsumerKt {
+    method public static <T> androidx.core.util.Consumer<T> asAndroidXConsumer(kotlin.coroutines.Continuation<? super T>);
+  }
+
+  public final class AtomicFileKt {
+    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
+    method @RequiresApi(17) public static String readText(android.util.AtomicFile, optional java.nio.charset.Charset charset);
+    method @RequiresApi(17) public static inline void tryWrite(android.util.AtomicFile, kotlin.jvm.functions.Function1<? super java.io.FileOutputStream,kotlin.Unit> block);
+    method @RequiresApi(17) public static void writeBytes(android.util.AtomicFile, byte[] array);
+    method @RequiresApi(17) public static void writeText(android.util.AtomicFile, String text, optional java.nio.charset.Charset charset);
+  }
+
+  @RequiresApi(24) public final class ConsumerKt {
+    method @RequiresApi(24) public static <T> java.util.function.Consumer<T> asConsumer(kotlin.coroutines.Continuation<? super T>);
+  }
+
+  public final class HalfKt {
+    method @RequiresApi(26) public static inline android.util.Half toHalf(@HalfFloat short);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(float);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(double);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(String);
+  }
+
+  public final class LongSparseArrayKt {
+    method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
+    method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
+    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+    method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
+    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
+    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
+    method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
+    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
+  }
+
+  public final class LruCacheKt {
+    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
+  }
+
+  public final class PairKt {
+    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
+    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+    method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
+    method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
+    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
+    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
+  }
+
+  public final class RangeKt {
+    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> and(android.util.Range<T>, android.util.Range<T> other);
+    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, T value);
+    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, android.util.Range<T> other);
+    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> rangeTo(T, T that);
+    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> kotlin.ranges.ClosedRange<T> toClosedRange(android.util.Range<T>);
+    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> android.util.Range<T> toRange(kotlin.ranges.ClosedRange<T>);
+  }
+
+  public final class RunnableKt {
+    method public static Runnable asRunnable(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class SizeKt {
+    method @RequiresApi(21) public static inline operator int component1(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component1(android.util.SizeF);
+    method public static inline operator float component1(androidx.core.util.SizeFCompat);
+    method @RequiresApi(21) public static inline operator int component2(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
+    method public static inline operator float component2(androidx.core.util.SizeFCompat);
+  }
+
+  public final class SparseArrayKt {
+    method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
+    method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
+    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+    method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
+    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
+    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> int getSize(android.util.SparseArray<T>);
+    method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
+    method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
+    method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
+    method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
+    method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
+    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
+    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+    method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
+  }
+
+  public final class SparseBooleanArrayKt {
+    method public static inline operator boolean contains(android.util.SparseBooleanArray, int key);
+    method public static inline boolean containsKey(android.util.SparseBooleanArray, int key);
+    method public static inline boolean containsValue(android.util.SparseBooleanArray, boolean value);
+    method public static inline void forEach(android.util.SparseBooleanArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,kotlin.Unit> action);
+    method public static inline boolean getOrDefault(android.util.SparseBooleanArray, int key, boolean defaultValue);
+    method public static inline boolean getOrElse(android.util.SparseBooleanArray, int key, kotlin.jvm.functions.Function0<java.lang.Boolean> defaultValue);
+    method public static inline int getSize(android.util.SparseBooleanArray);
+    method public static inline boolean isEmpty(android.util.SparseBooleanArray);
+    method public static inline boolean isNotEmpty(android.util.SparseBooleanArray);
+    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseBooleanArray);
+    method public static operator android.util.SparseBooleanArray plus(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
+    method public static void putAll(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
+    method public static boolean remove(android.util.SparseBooleanArray, int key, boolean value);
+    method public static inline operator void set(android.util.SparseBooleanArray, int key, boolean value);
+    method public static kotlin.collections.BooleanIterator valueIterator(android.util.SparseBooleanArray);
+  }
+
+  public final class SparseIntArrayKt {
+    method public static inline operator boolean contains(android.util.SparseIntArray, int key);
+    method public static inline boolean containsKey(android.util.SparseIntArray, int key);
+    method public static inline boolean containsValue(android.util.SparseIntArray, int value);
+    method public static inline void forEach(android.util.SparseIntArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+    method public static inline int getOrDefault(android.util.SparseIntArray, int key, int defaultValue);
+    method public static inline int getOrElse(android.util.SparseIntArray, int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public static inline int getSize(android.util.SparseIntArray);
+    method public static inline boolean isEmpty(android.util.SparseIntArray);
+    method public static inline boolean isNotEmpty(android.util.SparseIntArray);
+    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseIntArray);
+    method public static operator android.util.SparseIntArray plus(android.util.SparseIntArray, android.util.SparseIntArray other);
+    method public static void putAll(android.util.SparseIntArray, android.util.SparseIntArray other);
+    method public static boolean remove(android.util.SparseIntArray, int key, int value);
+    method public static inline operator void set(android.util.SparseIntArray, int key, int value);
+    method public static kotlin.collections.IntIterator valueIterator(android.util.SparseIntArray);
+  }
+
+  public final class SparseLongArrayKt {
+    method @RequiresApi(18) public static inline operator boolean contains(android.util.SparseLongArray, int key);
+    method @RequiresApi(18) public static inline boolean containsKey(android.util.SparseLongArray, int key);
+    method @RequiresApi(18) public static inline boolean containsValue(android.util.SparseLongArray, long value);
+    method @RequiresApi(18) public static inline void forEach(android.util.SparseLongArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> action);
+    method @RequiresApi(18) public static inline long getOrDefault(android.util.SparseLongArray, int key, long defaultValue);
+    method @RequiresApi(18) public static inline long getOrElse(android.util.SparseLongArray, int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method @RequiresApi(18) public static inline int getSize(android.util.SparseLongArray);
+    method @RequiresApi(18) public static inline boolean isEmpty(android.util.SparseLongArray);
+    method @RequiresApi(18) public static inline boolean isNotEmpty(android.util.SparseLongArray);
+    method @RequiresApi(18) public static kotlin.collections.IntIterator keyIterator(android.util.SparseLongArray);
+    method @RequiresApi(18) public static operator android.util.SparseLongArray plus(android.util.SparseLongArray, android.util.SparseLongArray other);
+    method @RequiresApi(18) public static void putAll(android.util.SparseLongArray, android.util.SparseLongArray other);
+    method @RequiresApi(18) public static boolean remove(android.util.SparseLongArray, int key, long value);
+    method @RequiresApi(18) public static inline operator void set(android.util.SparseLongArray, int key, long value);
+    method @RequiresApi(18) public static kotlin.collections.LongIterator valueIterator(android.util.SparseLongArray);
+  }
+
+}
+
+package androidx.core.view {
+
+  public final class MenuKt {
+    method public static operator boolean contains(android.view.Menu, android.view.MenuItem item);
+    method public static inline void forEach(android.view.Menu, kotlin.jvm.functions.Function1<? super android.view.MenuItem,kotlin.Unit> action);
+    method public static inline void forEachIndexed(android.view.Menu, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.MenuItem,kotlin.Unit> action);
+    method public static inline operator android.view.MenuItem get(android.view.Menu, int index);
+    method public static kotlin.sequences.Sequence<android.view.MenuItem> getChildren(android.view.Menu);
+    method public static inline int getSize(android.view.Menu);
+    method public static inline boolean isEmpty(android.view.Menu);
+    method public static inline boolean isNotEmpty(android.view.Menu);
+    method public static operator java.util.Iterator<android.view.MenuItem> iterator(android.view.Menu);
+    method public static inline operator void minusAssign(android.view.Menu, android.view.MenuItem item);
+    method public static inline void removeItemAt(android.view.Menu, int index);
+  }
+
+  public final class ViewGroupKt {
+    method public static inline operator boolean contains(android.view.ViewGroup, android.view.View view);
+    method public static inline void forEach(android.view.ViewGroup, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void forEachIndexed(android.view.ViewGroup, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.View,kotlin.Unit> action);
+    method public static operator android.view.View get(android.view.ViewGroup, int index);
+    method public static kotlin.sequences.Sequence<android.view.View> getChildren(android.view.ViewGroup);
+    method public static kotlin.sequences.Sequence<android.view.View> getDescendants(android.view.ViewGroup);
+    method public static inline kotlin.ranges.IntRange getIndices(android.view.ViewGroup);
+    method public static inline int getSize(android.view.ViewGroup);
+    method public static inline boolean isEmpty(android.view.ViewGroup);
+    method public static inline boolean isNotEmpty(android.view.ViewGroup);
+    method public static operator java.util.Iterator<android.view.View> iterator(android.view.ViewGroup);
+    method public static inline operator void minusAssign(android.view.ViewGroup, android.view.View view);
+    method public static inline operator void plusAssign(android.view.ViewGroup, android.view.View view);
+    method public static inline void setMargins(android.view.ViewGroup.MarginLayoutParams, @Px int size);
+    method public static inline void updateMargins(android.view.ViewGroup.MarginLayoutParams, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
+  }
+
+  public final class ViewKt {
+    method public static inline void doOnAttach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnDetach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnNextLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline androidx.core.view.OneShotPreDrawListener doOnPreDraw(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static android.graphics.Bitmap drawToBitmap(android.view.View, optional android.graphics.Bitmap.Config config);
+    method public static kotlin.sequences.Sequence<android.view.View> getAllViews(android.view.View);
+    method public static kotlin.sequences.Sequence<android.view.ViewParent> getAncestors(android.view.View);
+    method public static inline int getMarginBottom(android.view.View);
+    method public static inline int getMarginEnd(android.view.View);
+    method public static inline int getMarginLeft(android.view.View);
+    method public static inline int getMarginRight(android.view.View);
+    method public static inline int getMarginStart(android.view.View);
+    method public static inline int getMarginTop(android.view.View);
+    method public static inline boolean isGone(android.view.View);
+    method public static inline boolean isInvisible(android.view.View);
+    method public static inline boolean isVisible(android.view.View);
+    method public static inline Runnable postDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method @RequiresApi(16) public static Runnable postOnAnimationDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline void setGone(android.view.View, boolean);
+    method public static inline void setInvisible(android.view.View, boolean);
+    method public static inline void setPadding(android.view.View, @Px int size);
+    method public static inline void setVisible(android.view.View, boolean);
+    method public static inline void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super android.view.ViewGroup.LayoutParams,kotlin.Unit> block);
+    method public static inline <reified T extends android.view.ViewGroup.LayoutParams> void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> block);
+    method public static inline void updatePadding(android.view.View, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public final class TextViewKt {
+    method public static inline android.text.TextWatcher addTextChangedListener(android.widget.TextView, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> beforeTextChanged, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged, optional kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> afterTextChanged);
+    method public static inline android.text.TextWatcher doAfterTextChanged(android.widget.TextView, kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> action);
+    method public static inline android.text.TextWatcher doBeforeTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+    method public static inline android.text.TextWatcher doOnTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+  }
+
+}
+
diff --git a/core/core-ktx/api/res-1.10.0-beta01.txt b/core/core-ktx/api/res-1.10.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/core/core-ktx/api/res-1.10.0-beta01.txt
diff --git a/core/core-ktx/api/restricted_1.10.0-beta01.txt b/core/core-ktx/api/restricted_1.10.0-beta01.txt
new file mode 100644
index 0000000..801b56b
--- /dev/null
+++ b/core/core-ktx/api/restricted_1.10.0-beta01.txt
@@ -0,0 +1,634 @@
+// Signature format: 4.0
+package androidx.core.animation {
+
+  public final class AnimatorKt {
+    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onRepeat);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener addPauseListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onPause);
+    method public static inline android.animation.Animator.AnimatorListener doOnCancel(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnEnd(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener doOnPause(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnRepeat(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method @RequiresApi(19) public static android.animation.Animator.AnimatorPauseListener doOnResume(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+    method public static inline android.animation.Animator.AnimatorListener doOnStart(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content {
+
+  public final class ContentValuesKt {
+    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
+  }
+
+  public final class ContextKt {
+    method public static inline <reified T> T! getSystemService(android.content.Context);
+    method public static inline void withStyledAttributes(android.content.Context, optional android.util.AttributeSet? set, int[] attrs, optional @AttrRes int defStyleAttr, optional @StyleRes int defStyleRes, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
+    method public static inline void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
+  }
+
+  public final class SharedPreferencesKt {
+    method public static inline void edit(android.content.SharedPreferences, optional boolean commit, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class TypedArrayKt {
+    method public static boolean getBooleanOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @ColorInt public static int getColorOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static android.content.res.ColorStateList getColorStateListOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static float getDimensionOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @Dimension public static int getDimensionPixelOffsetOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @Dimension public static int getDimensionPixelSizeOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static android.graphics.drawable.Drawable getDrawableOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static float getFloatOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @RequiresApi(26) public static android.graphics.Typeface getFontOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static int getIntOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static int getIntegerOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method @AnyRes public static int getResourceIdOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
+    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+  }
+
+}
+
+package androidx.core.database {
+
+  public final class CursorKt {
+    method public static inline byte[]? getBlobOrNull(android.database.Cursor, int index);
+    method public static inline Double? getDoubleOrNull(android.database.Cursor, int index);
+    method public static inline Float? getFloatOrNull(android.database.Cursor, int index);
+    method public static inline Integer? getIntOrNull(android.database.Cursor, int index);
+    method public static inline Long? getLongOrNull(android.database.Cursor, int index);
+    method public static inline Short? getShortOrNull(android.database.Cursor, int index);
+    method public static inline String? getStringOrNull(android.database.Cursor, int index);
+  }
+
+}
+
+package androidx.core.database.sqlite {
+
+  public final class SQLiteDatabaseKt {
+    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapKt {
+    method public static inline android.graphics.Bitmap applyCanvas(android.graphics.Bitmap, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.Point p);
+    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.PointF p);
+    method public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config);
+    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config, optional boolean hasAlpha, optional android.graphics.ColorSpace colorSpace);
+    method public static inline operator int get(android.graphics.Bitmap, int x, int y);
+    method public static inline android.graphics.Bitmap scale(android.graphics.Bitmap, int width, int height, optional boolean filter);
+    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
+  }
+
+  public final class CanvasKt {
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.Rect clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.RectF clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, int left, int top, int right, int bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, float left, float top, float right, float bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withClip(android.graphics.Canvas, android.graphics.Path clipPath, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withMatrix(android.graphics.Canvas, optional android.graphics.Matrix matrix, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withRotation(android.graphics.Canvas, optional float degrees, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSave(android.graphics.Canvas, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withScale(android.graphics.Canvas, optional float x, optional float y, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withSkew(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void withTranslation(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class ColorKt {
+    method @RequiresApi(26) public static inline operator float component1(android.graphics.Color);
+    method public static inline operator int component1(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component1(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component2(android.graphics.Color);
+    method public static inline operator int component2(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component2(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component3(android.graphics.Color);
+    method public static inline operator int component3(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component3(@ColorLong long);
+    method @RequiresApi(26) public static inline operator float component4(android.graphics.Color);
+    method public static inline operator int component4(@ColorInt int);
+    method @RequiresApi(26) public static inline operator float component4(@ColorLong long);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace.Named colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace.Named colorSpace);
+    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace colorSpace);
+    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace.Named colorSpace);
+    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace colorSpace);
+    method public static inline int getAlpha(@ColorInt int);
+    method @RequiresApi(26) public static inline float getAlpha(@ColorLong long);
+    method public static inline int getBlue(@ColorInt int);
+    method @RequiresApi(26) public static inline float getBlue(@ColorLong long);
+    method @RequiresApi(26) public static inline android.graphics.ColorSpace getColorSpace(@ColorLong long);
+    method public static inline int getGreen(@ColorInt int);
+    method @RequiresApi(26) public static inline float getGreen(@ColorLong long);
+    method @RequiresApi(26) public static inline float getLuminance(@ColorInt int);
+    method @RequiresApi(26) public static inline float getLuminance(@ColorLong long);
+    method public static inline int getRed(@ColorInt int);
+    method @RequiresApi(26) public static inline float getRed(@ColorLong long);
+    method @RequiresApi(26) public static inline boolean isSrgb(@ColorLong long);
+    method @RequiresApi(26) public static inline boolean isWideGamut(@ColorLong long);
+    method @RequiresApi(26) public static operator android.graphics.Color plus(android.graphics.Color, android.graphics.Color c);
+    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorInt int);
+    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorLong long);
+    method @ColorInt @RequiresApi(26) public static inline int toColorInt(@ColorLong long);
+    method @ColorInt public static inline int toColorInt(String);
+    method @ColorLong @RequiresApi(26) public static inline long toColorLong(@ColorInt int);
+  }
+
+  public final class ImageDecoderKt {
+    method @RequiresApi(28) public static inline android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
+    method @RequiresApi(28) public static inline android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
+  }
+
+  public final class MatrixKt {
+    method public static android.graphics.Matrix rotationMatrix(float degrees, optional float px, optional float py);
+    method public static android.graphics.Matrix scaleMatrix(optional float sx, optional float sy);
+    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
+    method public static android.graphics.Matrix translationMatrix(optional float tx, optional float ty);
+    method public static inline float[] values(android.graphics.Matrix);
+  }
+
+  public final class PaintKt {
+    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+  }
+
+  public final class PathKt {
+    method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(26) public static Iterable<androidx.core.graphics.PathSegment> flatten(android.graphics.Path, optional float error);
+    method @RequiresApi(19) public static inline operator android.graphics.Path minus(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline infix android.graphics.Path or(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline operator android.graphics.Path plus(android.graphics.Path, android.graphics.Path p);
+    method @RequiresApi(19) public static inline infix android.graphics.Path xor(android.graphics.Path, android.graphics.Path p);
+  }
+
+  public final class PictureKt {
+    method public static inline android.graphics.Picture record(android.graphics.Picture, int width, int height, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class PointKt {
+    method public static inline operator int component1(android.graphics.Point);
+    method public static inline operator float component1(android.graphics.PointF);
+    method public static inline operator int component2(android.graphics.Point);
+    method public static inline operator float component2(android.graphics.PointF);
+    method public static inline operator android.graphics.Point div(android.graphics.Point, float scalar);
+    method public static inline operator android.graphics.PointF div(android.graphics.PointF, float scalar);
+    method public static inline operator android.graphics.Point minus(android.graphics.Point, android.graphics.Point p);
+    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Point minus(android.graphics.Point, int xy);
+    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, float xy);
+    method public static inline operator android.graphics.Point plus(android.graphics.Point, android.graphics.Point p);
+    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Point plus(android.graphics.Point, int xy);
+    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, float xy);
+    method public static inline operator android.graphics.Point times(android.graphics.Point, float scalar);
+    method public static inline operator android.graphics.PointF times(android.graphics.PointF, float scalar);
+    method public static inline android.graphics.Point toPoint(android.graphics.PointF);
+    method public static inline android.graphics.PointF toPointF(android.graphics.Point);
+    method public static inline operator android.graphics.Point unaryMinus(android.graphics.Point);
+    method public static inline operator android.graphics.PointF unaryMinus(android.graphics.PointF);
+  }
+
+  public final class PorterDuffKt {
+    method public static inline android.graphics.PorterDuffColorFilter toColorFilter(android.graphics.PorterDuff.Mode, int color);
+    method public static inline android.graphics.PorterDuffXfermode toXfermode(android.graphics.PorterDuff.Mode);
+  }
+
+  public final class RectKt {
+    method public static inline infix android.graphics.Rect and(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.RectF and(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator int component1(android.graphics.Rect);
+    method public static inline operator float component1(android.graphics.RectF);
+    method public static inline operator int component2(android.graphics.Rect);
+    method public static inline operator float component2(android.graphics.RectF);
+    method public static inline operator int component3(android.graphics.Rect);
+    method public static inline operator float component3(android.graphics.RectF);
+    method public static inline operator int component4(android.graphics.Rect);
+    method public static inline operator float component4(android.graphics.RectF);
+    method public static inline operator boolean contains(android.graphics.Rect, android.graphics.Point p);
+    method public static inline operator boolean contains(android.graphics.RectF, android.graphics.PointF p);
+    method public static inline operator android.graphics.Region minus(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region minus(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, int xy);
+    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, float xy);
+    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, android.graphics.Point xy);
+    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, android.graphics.PointF xy);
+    method public static inline infix android.graphics.Rect or(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.RectF or(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.RectF r);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, int xy);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, float xy);
+    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Point xy);
+    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.PointF xy);
+    method public static inline operator android.graphics.Rect times(android.graphics.Rect, int factor);
+    method public static inline operator android.graphics.RectF times(android.graphics.RectF, int factor);
+    method public static inline operator android.graphics.RectF times(android.graphics.RectF, float factor);
+    method public static inline android.graphics.Rect toRect(android.graphics.RectF);
+    method public static inline android.graphics.RectF toRectF(android.graphics.Rect);
+    method public static inline android.graphics.Region toRegion(android.graphics.Rect);
+    method public static inline android.graphics.Region toRegion(android.graphics.RectF);
+    method public static inline android.graphics.RectF transform(android.graphics.RectF, android.graphics.Matrix m);
+    method public static inline infix android.graphics.Region xor(android.graphics.Rect, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region xor(android.graphics.RectF, android.graphics.RectF r);
+  }
+
+  public final class RegionKt {
+    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator boolean contains(android.graphics.Region, android.graphics.Point p);
+    method public static inline void forEach(android.graphics.Region, kotlin.jvm.functions.Function1<? super android.graphics.Rect,kotlin.Unit> action);
+    method public static operator java.util.Iterator<android.graphics.Rect> iterator(android.graphics.Region);
+    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region not(android.graphics.Region);
+    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Rect r);
+    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Region r);
+    method public static inline operator android.graphics.Region unaryMinus(android.graphics.Region);
+    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Rect r);
+    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Region r);
+  }
+
+  public final class ShaderKt {
+    method public static inline void transform(android.graphics.Shader, kotlin.jvm.functions.Function1<? super android.graphics.Matrix,kotlin.Unit> block);
+  }
+
+}
+
+package androidx.core.graphics.drawable {
+
+  public final class BitmapDrawableKt {
+    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
+  }
+
+  public final class ColorDrawableKt {
+    method public static inline android.graphics.drawable.ColorDrawable toDrawable(@ColorInt int);
+    method @RequiresApi(26) public static inline android.graphics.drawable.ColorDrawable toDrawable(android.graphics.Color);
+  }
+
+  public final class DrawableKt {
+    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
+    method public static android.graphics.Bitmap? toBitmapOrNull(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
+    method public static void updateBounds(android.graphics.drawable.Drawable, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+  }
+
+  public final class IconKt {
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toAdaptiveIcon(android.graphics.Bitmap);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.graphics.Bitmap);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.net.Uri);
+    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(byte[]);
+  }
+
+}
+
+package androidx.core.location {
+
+  public final class LocationKt {
+    method public static inline operator double component1(android.location.Location);
+    method public static inline operator double component2(android.location.Location);
+  }
+
+}
+
+package androidx.core.net {
+
+  public final class UriKt {
+    method public static java.io.File toFile(android.net.Uri);
+    method public static inline android.net.Uri toUri(String);
+    method public static inline android.net.Uri toUri(java.io.File);
+  }
+
+}
+
+package androidx.core.os {
+
+  public final class BundleKt {
+    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+    method public static android.os.Bundle bundleOf();
+  }
+
+  public final class HandlerKt {
+    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+  }
+
+  @RequiresApi(31) public final class OutcomeReceiverKt {
+    method @RequiresApi(31) public static <R, E extends java.lang.Throwable> android.os.OutcomeReceiver<R,E> asOutcomeReceiver(kotlin.coroutines.Continuation<? super R>);
+  }
+
+  public final class PersistableBundleKt {
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
+    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf();
+    method @RequiresApi(21) public static android.os.PersistableBundle toPersistableBundle(java.util.Map<java.lang.String,?>);
+  }
+
+  public final class TraceKt {
+    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class CharSequenceKt {
+    method public static inline boolean isDigitsOnly(CharSequence);
+    method public static inline int trimmedLength(CharSequence);
+  }
+
+  public final class HtmlKt {
+    method public static inline android.text.Spanned parseAsHtml(String, optional int flags, optional android.text.Html.ImageGetter? imageGetter, optional android.text.Html.TagHandler? tagHandler);
+    method public static inline String toHtml(android.text.Spanned, optional int option);
+  }
+
+  public final class LocaleKt {
+    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
+  }
+
+  public final class SpannableStringBuilderKt {
+    method public static inline android.text.SpannableStringBuilder backgroundColor(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder bold(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannedString buildSpannedString(kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder color(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object![] spans, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object span, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+    method public static inline android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
+  }
+
+  public final class SpannableStringKt {
+    method public static inline void clearSpans(android.text.Spannable);
+    method public static inline operator void set(android.text.Spannable, int start, int end, Object span);
+    method public static inline operator void set(android.text.Spannable, kotlin.ranges.IntRange range, Object span);
+    method public static inline android.text.Spannable toSpannable(CharSequence);
+  }
+
+  public final class SpannedStringKt {
+    method public static inline <reified T> T![] getSpans(android.text.Spanned, optional int start, optional int end);
+    method public static inline android.text.Spanned toSpanned(CharSequence);
+  }
+
+  public final class StringKt {
+    method public static inline String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.transition {
+
+  public final class TransitionKt {
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onPause);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnCancel(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnEnd(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnPause(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnResume(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnStart(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
+  }
+
+}
+
+package androidx.core.util {
+
+  public final class AndroidXConsumerKt {
+    method public static <T> androidx.core.util.Consumer<T> asAndroidXConsumer(kotlin.coroutines.Continuation<? super T>);
+  }
+
+  public final class AtomicFileKt {
+    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
+    method @RequiresApi(17) public static String readText(android.util.AtomicFile, optional java.nio.charset.Charset charset);
+    method @RequiresApi(17) public static inline void tryWrite(android.util.AtomicFile, kotlin.jvm.functions.Function1<? super java.io.FileOutputStream,kotlin.Unit> block);
+    method @RequiresApi(17) public static void writeBytes(android.util.AtomicFile, byte[] array);
+    method @RequiresApi(17) public static void writeText(android.util.AtomicFile, String text, optional java.nio.charset.Charset charset);
+  }
+
+  @RequiresApi(24) public final class ConsumerKt {
+    method @RequiresApi(24) public static <T> java.util.function.Consumer<T> asConsumer(kotlin.coroutines.Continuation<? super T>);
+  }
+
+  public final class HalfKt {
+    method @RequiresApi(26) public static inline android.util.Half toHalf(@HalfFloat short);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(float);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(double);
+    method @RequiresApi(26) public static inline android.util.Half toHalf(String);
+  }
+
+  public final class LongSparseArrayKt {
+    method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
+    method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
+    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+    method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
+    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
+    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
+    method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
+    method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
+    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
+  }
+
+  public final class LruCacheKt {
+    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
+  }
+
+  public final class PairKt {
+    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
+    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+    method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
+    method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
+    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
+    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
+  }
+
+  public final class RangeKt {
+    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> and(android.util.Range<T>, android.util.Range<T> other);
+    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, T value);
+    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, android.util.Range<T> other);
+    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> rangeTo(T, T that);
+    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> kotlin.ranges.ClosedRange<T> toClosedRange(android.util.Range<T>);
+    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> android.util.Range<T> toRange(kotlin.ranges.ClosedRange<T>);
+  }
+
+  public final class RunnableKt {
+    method public static Runnable asRunnable(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class SizeKt {
+    method @RequiresApi(21) public static inline operator int component1(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component1(android.util.SizeF);
+    method public static inline operator float component1(androidx.core.util.SizeFCompat);
+    method @RequiresApi(21) public static inline operator int component2(android.util.Size);
+    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
+    method public static inline operator float component2(androidx.core.util.SizeFCompat);
+  }
+
+  public final class SparseArrayKt {
+    method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
+    method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
+    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+    method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
+    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
+    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> int getSize(android.util.SparseArray<T>);
+    method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
+    method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
+    method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
+    method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
+    method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
+    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
+    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+    method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
+  }
+
+  public final class SparseBooleanArrayKt {
+    method public static inline operator boolean contains(android.util.SparseBooleanArray, int key);
+    method public static inline boolean containsKey(android.util.SparseBooleanArray, int key);
+    method public static inline boolean containsValue(android.util.SparseBooleanArray, boolean value);
+    method public static inline void forEach(android.util.SparseBooleanArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,kotlin.Unit> action);
+    method public static inline boolean getOrDefault(android.util.SparseBooleanArray, int key, boolean defaultValue);
+    method public static inline boolean getOrElse(android.util.SparseBooleanArray, int key, kotlin.jvm.functions.Function0<java.lang.Boolean> defaultValue);
+    method public static inline int getSize(android.util.SparseBooleanArray);
+    method public static inline boolean isEmpty(android.util.SparseBooleanArray);
+    method public static inline boolean isNotEmpty(android.util.SparseBooleanArray);
+    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseBooleanArray);
+    method public static operator android.util.SparseBooleanArray plus(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
+    method public static void putAll(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
+    method public static boolean remove(android.util.SparseBooleanArray, int key, boolean value);
+    method public static inline operator void set(android.util.SparseBooleanArray, int key, boolean value);
+    method public static kotlin.collections.BooleanIterator valueIterator(android.util.SparseBooleanArray);
+  }
+
+  public final class SparseIntArrayKt {
+    method public static inline operator boolean contains(android.util.SparseIntArray, int key);
+    method public static inline boolean containsKey(android.util.SparseIntArray, int key);
+    method public static inline boolean containsValue(android.util.SparseIntArray, int value);
+    method public static inline void forEach(android.util.SparseIntArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+    method public static inline int getOrDefault(android.util.SparseIntArray, int key, int defaultValue);
+    method public static inline int getOrElse(android.util.SparseIntArray, int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public static inline int getSize(android.util.SparseIntArray);
+    method public static inline boolean isEmpty(android.util.SparseIntArray);
+    method public static inline boolean isNotEmpty(android.util.SparseIntArray);
+    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseIntArray);
+    method public static operator android.util.SparseIntArray plus(android.util.SparseIntArray, android.util.SparseIntArray other);
+    method public static void putAll(android.util.SparseIntArray, android.util.SparseIntArray other);
+    method public static boolean remove(android.util.SparseIntArray, int key, int value);
+    method public static inline operator void set(android.util.SparseIntArray, int key, int value);
+    method public static kotlin.collections.IntIterator valueIterator(android.util.SparseIntArray);
+  }
+
+  public final class SparseLongArrayKt {
+    method @RequiresApi(18) public static inline operator boolean contains(android.util.SparseLongArray, int key);
+    method @RequiresApi(18) public static inline boolean containsKey(android.util.SparseLongArray, int key);
+    method @RequiresApi(18) public static inline boolean containsValue(android.util.SparseLongArray, long value);
+    method @RequiresApi(18) public static inline void forEach(android.util.SparseLongArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> action);
+    method @RequiresApi(18) public static inline long getOrDefault(android.util.SparseLongArray, int key, long defaultValue);
+    method @RequiresApi(18) public static inline long getOrElse(android.util.SparseLongArray, int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method @RequiresApi(18) public static inline int getSize(android.util.SparseLongArray);
+    method @RequiresApi(18) public static inline boolean isEmpty(android.util.SparseLongArray);
+    method @RequiresApi(18) public static inline boolean isNotEmpty(android.util.SparseLongArray);
+    method @RequiresApi(18) public static kotlin.collections.IntIterator keyIterator(android.util.SparseLongArray);
+    method @RequiresApi(18) public static operator android.util.SparseLongArray plus(android.util.SparseLongArray, android.util.SparseLongArray other);
+    method @RequiresApi(18) public static void putAll(android.util.SparseLongArray, android.util.SparseLongArray other);
+    method @RequiresApi(18) public static boolean remove(android.util.SparseLongArray, int key, long value);
+    method @RequiresApi(18) public static inline operator void set(android.util.SparseLongArray, int key, long value);
+    method @RequiresApi(18) public static kotlin.collections.LongIterator valueIterator(android.util.SparseLongArray);
+  }
+
+}
+
+package androidx.core.view {
+
+  public final class MenuKt {
+    method public static operator boolean contains(android.view.Menu, android.view.MenuItem item);
+    method public static inline void forEach(android.view.Menu, kotlin.jvm.functions.Function1<? super android.view.MenuItem,kotlin.Unit> action);
+    method public static inline void forEachIndexed(android.view.Menu, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.MenuItem,kotlin.Unit> action);
+    method public static inline operator android.view.MenuItem get(android.view.Menu, int index);
+    method public static kotlin.sequences.Sequence<android.view.MenuItem> getChildren(android.view.Menu);
+    method public static inline int getSize(android.view.Menu);
+    method public static inline boolean isEmpty(android.view.Menu);
+    method public static inline boolean isNotEmpty(android.view.Menu);
+    method public static operator java.util.Iterator<android.view.MenuItem> iterator(android.view.Menu);
+    method public static inline operator void minusAssign(android.view.Menu, android.view.MenuItem item);
+    method public static inline void removeItemAt(android.view.Menu, int index);
+  }
+
+  public final class ViewGroupKt {
+    method public static inline operator boolean contains(android.view.ViewGroup, android.view.View view);
+    method public static inline void forEach(android.view.ViewGroup, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void forEachIndexed(android.view.ViewGroup, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.View,kotlin.Unit> action);
+    method public static operator android.view.View get(android.view.ViewGroup, int index);
+    method public static kotlin.sequences.Sequence<android.view.View> getChildren(android.view.ViewGroup);
+    method public static kotlin.sequences.Sequence<android.view.View> getDescendants(android.view.ViewGroup);
+    method public static inline kotlin.ranges.IntRange getIndices(android.view.ViewGroup);
+    method public static inline int getSize(android.view.ViewGroup);
+    method public static inline boolean isEmpty(android.view.ViewGroup);
+    method public static inline boolean isNotEmpty(android.view.ViewGroup);
+    method public static operator java.util.Iterator<android.view.View> iterator(android.view.ViewGroup);
+    method public static inline operator void minusAssign(android.view.ViewGroup, android.view.View view);
+    method public static inline operator void plusAssign(android.view.ViewGroup, android.view.View view);
+    method public static inline void setMargins(android.view.ViewGroup.MarginLayoutParams, @Px int size);
+    method public static inline void updateMargins(android.view.ViewGroup.MarginLayoutParams, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
+  }
+
+  public final class ViewKt {
+    method public static inline void doOnAttach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnDetach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline void doOnNextLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static inline androidx.core.view.OneShotPreDrawListener doOnPreDraw(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
+    method public static android.graphics.Bitmap drawToBitmap(android.view.View, optional android.graphics.Bitmap.Config config);
+    method public static kotlin.sequences.Sequence<android.view.View> getAllViews(android.view.View);
+    method public static kotlin.sequences.Sequence<android.view.ViewParent> getAncestors(android.view.View);
+    method public static inline int getMarginBottom(android.view.View);
+    method public static inline int getMarginEnd(android.view.View);
+    method public static inline int getMarginLeft(android.view.View);
+    method public static inline int getMarginRight(android.view.View);
+    method public static inline int getMarginStart(android.view.View);
+    method public static inline int getMarginTop(android.view.View);
+    method public static inline boolean isGone(android.view.View);
+    method public static inline boolean isInvisible(android.view.View);
+    method public static inline boolean isVisible(android.view.View);
+    method public static inline Runnable postDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method @RequiresApi(16) public static Runnable postOnAnimationDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
+    method public static inline void setGone(android.view.View, boolean);
+    method public static inline void setInvisible(android.view.View, boolean);
+    method public static inline void setPadding(android.view.View, @Px int size);
+    method public static inline void setVisible(android.view.View, boolean);
+    method public static inline void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super android.view.ViewGroup.LayoutParams,kotlin.Unit> block);
+    method public static inline <reified T extends android.view.ViewGroup.LayoutParams> void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> block);
+    method public static inline void updatePadding(android.view.View, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
+    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public final class TextViewKt {
+    method public static inline android.text.TextWatcher addTextChangedListener(android.widget.TextView, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> beforeTextChanged, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged, optional kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> afterTextChanged);
+    method public static inline android.text.TextWatcher doAfterTextChanged(android.widget.TextView, kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> action);
+    method public static inline android.text.TextWatcher doBeforeTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+    method public static inline android.text.TextWatcher doOnTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
+  }
+
+}
+
diff --git a/core/core/api/1.10.0-beta01.txt b/core/core/api/1.10.0-beta01.txt
new file mode 100644
index 0000000..f8aa350
--- /dev/null
+++ b/core/core/api/1.10.0-beta01.txt
@@ -0,0 +1,3929 @@
+// Signature format: 4.0
+package androidx.core.accessibilityservice {
+
+  public final class AccessibilityServiceInfoCompat {
+    method public static String capabilityToString(int);
+    method public static String feedbackTypeToString(int);
+    method public static String? flagToString(int);
+    method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static String? loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
+    field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
+    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+    field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
+    field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
+    field public static final int FEEDBACK_BRAILLE = 32; // 0x20
+    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
+    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+  }
+
+}
+
+package androidx.core.app {
+
+  public class ActivityCompat extends androidx.core.content.ContextCompat {
+    ctor protected ActivityCompat();
+    method public static void finishAffinity(android.app.Activity);
+    method public static void finishAfterTransition(android.app.Activity);
+    method public static android.net.Uri? getReferrer(android.app.Activity);
+    method @Deprecated public static boolean invalidateOptionsMenu(android.app.Activity!);
+    method public static boolean isLaunchedFromBubble(android.app.Activity);
+    method public static void postponeEnterTransition(android.app.Activity);
+    method public static void recreate(android.app.Activity);
+    method public static androidx.core.view.DragAndDropPermissionsCompat? requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
+    method public static void requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+    method public static <T extends android.view.View> T requireViewById(android.app.Activity, @IdRes int);
+    method public static void setEnterSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setExitSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setLocusContext(android.app.Activity, androidx.core.content.LocusIdCompat?, android.os.Bundle?);
+    method public static void setPermissionCompatDelegate(androidx.core.app.ActivityCompat.PermissionCompatDelegate?);
+    method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, String);
+    method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle?);
+    method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public static void startPostponedEnterTransition(android.app.Activity);
+  }
+
+  public static interface ActivityCompat.OnRequestPermissionsResultCallback {
+    method public void onRequestPermissionsResult(int, String![], int[]);
+  }
+
+  public static interface ActivityCompat.PermissionCompatDelegate {
+    method public boolean onActivityResult(android.app.Activity, @IntRange(from=0) int, int, android.content.Intent?);
+    method public boolean requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+  }
+
+  public final class ActivityManagerCompat {
+    method public static boolean isLowRamDevice(android.app.ActivityManager);
+  }
+
+  public class ActivityOptionsCompat {
+    ctor protected ActivityOptionsCompat();
+    method public android.graphics.Rect? getLaunchBounds();
+    method public static androidx.core.app.ActivityOptionsCompat makeBasic();
+    method public static androidx.core.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, String);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, androidx.core.util.Pair<android.view.View!,java.lang.String!>!...);
+    method public static androidx.core.app.ActivityOptionsCompat makeTaskLaunchBehind();
+    method public static androidx.core.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
+    method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public androidx.core.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect?);
+    method public android.os.Bundle? toBundle();
+    method public void update(androidx.core.app.ActivityOptionsCompat);
+    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+    field public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
+  }
+
+  public final class AlarmManagerCompat {
+    method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
+    method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+  }
+
+  @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory {
+    ctor public AppComponentFactory();
+    method public final android.app.Activity instantiateActivity(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Activity instantiateActivityCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Application instantiateApplication(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Application instantiateApplicationCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.ContentProvider instantiateProvider(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.ContentProvider instantiateProviderCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.BroadcastReceiver instantiateReceiver(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.BroadcastReceiver instantiateReceiverCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Service instantiateService(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Service instantiateServiceCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+  }
+
+  public class AppLaunchChecker {
+    ctor @Deprecated public AppLaunchChecker();
+    method public static boolean hasStartedFromLauncher(android.content.Context);
+    method public static void onActivityCreate(android.app.Activity);
+  }
+
+  public final class AppOpsManagerCompat {
+    method public static int checkOrNoteProxyOp(android.content.Context, int, String, String);
+    method public static int noteOp(android.content.Context, String, int, String);
+    method public static int noteOpNoThrow(android.content.Context, String, int, String);
+    method public static int noteProxyOp(android.content.Context, String, String);
+    method public static int noteProxyOpNoThrow(android.content.Context, String, String);
+    method public static String? permissionToOp(String);
+    field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_DEFAULT = 3; // 0x3
+    field public static final int MODE_ERRORED = 2; // 0x2
+    field public static final int MODE_IGNORED = 1; // 0x1
+  }
+
+  public final class BundleCompat {
+    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  }
+
+  public class DialogCompat {
+    method public static android.view.View requireViewById(android.app.Dialog, int);
+  }
+
+  public class FrameMetricsAggregator {
+    ctor public FrameMetricsAggregator();
+    ctor public FrameMetricsAggregator(int);
+    method public void add(android.app.Activity);
+    method public android.util.SparseIntArray![]? getMetrics();
+    method public android.util.SparseIntArray![]? remove(android.app.Activity);
+    method public android.util.SparseIntArray![]? reset();
+    method public android.util.SparseIntArray![]? stop();
+    field public static final int ANIMATION_DURATION = 256; // 0x100
+    field public static final int ANIMATION_INDEX = 8; // 0x8
+    field public static final int COMMAND_DURATION = 32; // 0x20
+    field public static final int COMMAND_INDEX = 5; // 0x5
+    field public static final int DELAY_DURATION = 128; // 0x80
+    field public static final int DELAY_INDEX = 7; // 0x7
+    field public static final int DRAW_DURATION = 8; // 0x8
+    field public static final int DRAW_INDEX = 3; // 0x3
+    field public static final int EVERY_DURATION = 511; // 0x1ff
+    field public static final int INPUT_DURATION = 2; // 0x2
+    field public static final int INPUT_INDEX = 1; // 0x1
+    field public static final int LAYOUT_MEASURE_DURATION = 4; // 0x4
+    field public static final int LAYOUT_MEASURE_INDEX = 2; // 0x2
+    field public static final int SWAP_DURATION = 64; // 0x40
+    field public static final int SWAP_INDEX = 6; // 0x6
+    field public static final int SYNC_DURATION = 16; // 0x10
+    field public static final int SYNC_INDEX = 4; // 0x4
+    field public static final int TOTAL_DURATION = 1; // 0x1
+    field public static final int TOTAL_INDEX = 0; // 0x0
+  }
+
+  @Deprecated public abstract class JobIntentService extends android.app.Service {
+    ctor @Deprecated public JobIntentService();
+    method @Deprecated public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
+    method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
+    method @Deprecated public boolean isStopped();
+    method @Deprecated public android.os.IBinder! onBind(android.content.Intent);
+    method @Deprecated protected abstract void onHandleWork(android.content.Intent);
+    method @Deprecated public boolean onStopCurrentWork();
+    method @Deprecated public void setInterruptIfStopped(boolean);
+  }
+
+  public final class LocaleManagerCompat {
+    method @AnyThread public static androidx.core.os.LocaleListCompat getSystemLocales(android.content.Context);
+  }
+
+  public final class MultiWindowModeChangedInfo {
+    ctor public MultiWindowModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public MultiWindowModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInMultiWindowMode();
+  }
+
+  public final class NavUtils {
+    method public static android.content.Intent? getParentActivityIntent(android.app.Activity);
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static String? getParentActivityName(android.app.Activity);
+    method public static String? getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void navigateUpFromSameTask(android.app.Activity);
+    method public static void navigateUpTo(android.app.Activity, android.content.Intent);
+    method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
+    field public static final String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
+  }
+
+  public class NotificationChannelCompat {
+    method public boolean canBubble();
+    method public boolean canBypassDnd();
+    method public boolean canShowBadge();
+    method public android.media.AudioAttributes? getAudioAttributes();
+    method public String? getConversationId();
+    method public String? getDescription();
+    method public String? getGroup();
+    method public String getId();
+    method public int getImportance();
+    method public int getLightColor();
+    method public int getLockscreenVisibility();
+    method public CharSequence? getName();
+    method public String? getParentChannelId();
+    method public android.net.Uri? getSound();
+    method public long[]? getVibrationPattern();
+    method public boolean isImportantConversation();
+    method public boolean shouldShowLights();
+    method public boolean shouldVibrate();
+    method public androidx.core.app.NotificationChannelCompat.Builder toBuilder();
+    field public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
+  }
+
+  public static class NotificationChannelCompat.Builder {
+    ctor public NotificationChannelCompat.Builder(String, int);
+    method public androidx.core.app.NotificationChannelCompat build();
+    method public androidx.core.app.NotificationChannelCompat.Builder setConversationId(String, String);
+    method public androidx.core.app.NotificationChannelCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setImportance(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightColor(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightsEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setName(CharSequence?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setShowBadge(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setSound(android.net.Uri?, android.media.AudioAttributes?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationPattern(long[]?);
+  }
+
+  public class NotificationChannelGroupCompat {
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getChannels();
+    method public String? getDescription();
+    method public String getId();
+    method public CharSequence? getName();
+    method public boolean isBlocked();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder toBuilder();
+  }
+
+  public static class NotificationChannelGroupCompat.Builder {
+    ctor public NotificationChannelGroupCompat.Builder(String);
+    method public androidx.core.app.NotificationChannelGroupCompat build();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setName(CharSequence?);
+  }
+
+  public class NotificationCompat {
+    ctor @Deprecated public NotificationCompat();
+    method public static androidx.core.app.NotificationCompat.Action? getAction(android.app.Notification, int);
+    method public static int getActionCount(android.app.Notification);
+    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification);
+    method public static boolean getAutoCancel(android.app.Notification);
+    method public static int getBadgeIconType(android.app.Notification);
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata(android.app.Notification);
+    method public static String? getCategory(android.app.Notification);
+    method public static String? getChannelId(android.app.Notification);
+    method public static int getColor(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentInfo(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentText(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentTitle(android.app.Notification);
+    method public static android.os.Bundle? getExtras(android.app.Notification);
+    method public static String? getGroup(android.app.Notification);
+    method public static int getGroupAlertBehavior(android.app.Notification);
+    method @RequiresApi(21) public static java.util.List<androidx.core.app.NotificationCompat.Action!> getInvisibleActions(android.app.Notification);
+    method public static boolean getLocalOnly(android.app.Notification);
+    method public static androidx.core.content.LocusIdCompat? getLocusId(android.app.Notification);
+    method public static boolean getOngoing(android.app.Notification);
+    method public static boolean getOnlyAlertOnce(android.app.Notification);
+    method public static java.util.List<androidx.core.app.Person!> getPeople(android.app.Notification);
+    method public static android.app.Notification? getPublicVersion(android.app.Notification);
+    method public static CharSequence? getSettingsText(android.app.Notification);
+    method public static String? getShortcutId(android.app.Notification);
+    method @RequiresApi(19) public static boolean getShowWhen(android.app.Notification);
+    method public static String? getSortKey(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getSubText(android.app.Notification);
+    method public static long getTimeoutAfter(android.app.Notification);
+    method @RequiresApi(19) public static boolean getUsesChronometer(android.app.Notification);
+    method public static int getVisibility(android.app.Notification);
+    method public static boolean isGroupSummary(android.app.Notification);
+    field public static final int BADGE_ICON_LARGE = 2; // 0x2
+    field public static final int BADGE_ICON_NONE = 0; // 0x0
+    field public static final int BADGE_ICON_SMALL = 1; // 0x1
+    field public static final String CATEGORY_ALARM = "alarm";
+    field public static final String CATEGORY_CALL = "call";
+    field public static final String CATEGORY_EMAIL = "email";
+    field public static final String CATEGORY_ERROR = "err";
+    field public static final String CATEGORY_EVENT = "event";
+    field public static final String CATEGORY_LOCATION_SHARING = "location_sharing";
+    field public static final String CATEGORY_MESSAGE = "msg";
+    field public static final String CATEGORY_MISSED_CALL = "missed_call";
+    field public static final String CATEGORY_NAVIGATION = "navigation";
+    field public static final String CATEGORY_PROGRESS = "progress";
+    field public static final String CATEGORY_PROMO = "promo";
+    field public static final String CATEGORY_RECOMMENDATION = "recommendation";
+    field public static final String CATEGORY_REMINDER = "reminder";
+    field public static final String CATEGORY_SERVICE = "service";
+    field public static final String CATEGORY_SOCIAL = "social";
+    field public static final String CATEGORY_STATUS = "status";
+    field public static final String CATEGORY_STOPWATCH = "stopwatch";
+    field public static final String CATEGORY_SYSTEM = "sys";
+    field public static final String CATEGORY_TRANSPORT = "transport";
+    field public static final String CATEGORY_WORKOUT = "workout";
+    field @ColorInt public static final int COLOR_DEFAULT = 0; // 0x0
+    field public static final int DEFAULT_ALL = -1; // 0xffffffff
+    field public static final int DEFAULT_LIGHTS = 4; // 0x4
+    field public static final int DEFAULT_SOUND = 1; // 0x1
+    field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final String EXTRA_ANSWER_COLOR = "android.answerColor";
+    field public static final String EXTRA_ANSWER_INTENT = "android.answerIntent";
+    field public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
+    field public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+    field public static final String EXTRA_BIG_TEXT = "android.bigText";
+    field public static final String EXTRA_CALL_IS_VIDEO = "android.callIsVideo";
+    field public static final String EXTRA_CALL_PERSON = "android.callPerson";
+    field public static final String EXTRA_CALL_PERSON_COMPAT = "android.callPersonCompat";
+    field public static final String EXTRA_CALL_TYPE = "android.callType";
+    field public static final String EXTRA_CHANNEL_GROUP_ID = "android.intent.extra.CHANNEL_GROUP_ID";
+    field public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
+    field public static final String EXTRA_CHRONOMETER_COUNT_DOWN = "android.chronometerCountDown";
+    field public static final String EXTRA_COLORIZED = "android.colorized";
+    field public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final String EXTRA_COMPAT_TEMPLATE = "androidx.core.app.extra.COMPAT_TEMPLATE";
+    field public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
+    field public static final String EXTRA_DECLINE_COLOR = "android.declineColor";
+    field public static final String EXTRA_DECLINE_INTENT = "android.declineIntent";
+    field public static final String EXTRA_HANG_UP_INTENT = "android.hangUpIntent";
+    field public static final String EXTRA_HIDDEN_CONVERSATION_TITLE = "android.hiddenConversationTitle";
+    field public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic";
+    field public static final String EXTRA_INFO_TEXT = "android.infoText";
+    field public static final String EXTRA_IS_GROUP_CONVERSATION = "android.isGroupConversation";
+    field public static final String EXTRA_LARGE_ICON = "android.largeIcon";
+    field public static final String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+    field public static final String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final String EXTRA_MESSAGES = "android.messages";
+    field public static final String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
+    field public static final String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+    field public static final String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
+    field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
+    field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
+    field public static final String EXTRA_PICTURE = "android.picture";
+    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
+    field public static final String EXTRA_PICTURE_ICON = "android.pictureIcon";
+    field public static final String EXTRA_PROGRESS = "android.progress";
+    field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+    field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
+    field public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+    field public static final String EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED = "android.showBigPictureWhenCollapsed";
+    field public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+    field public static final String EXTRA_SHOW_WHEN = "android.showWhen";
+    field public static final String EXTRA_SMALL_ICON = "android.icon";
+    field public static final String EXTRA_SUB_TEXT = "android.subText";
+    field public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
+    field public static final String EXTRA_TEMPLATE = "android.template";
+    field public static final String EXTRA_TEXT = "android.text";
+    field public static final String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final String EXTRA_TITLE = "android.title";
+    field public static final String EXTRA_TITLE_BIG = "android.title.big";
+    field public static final String EXTRA_VERIFICATION_ICON = "android.verificationIcon";
+    field public static final String EXTRA_VERIFICATION_ICON_COMPAT = "android.verificationIconCompat";
+    field public static final String EXTRA_VERIFICATION_TEXT = "android.verificationText";
+    field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
+    field public static final int FLAG_BUBBLE = 4096; // 0x1000
+    field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
+    field @Deprecated public static final int FLAG_HIGH_PRIORITY = 128; // 0x80
+    field public static final int FLAG_INSISTENT = 4; // 0x4
+    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
+    field public static final int FLAG_NO_CLEAR = 32; // 0x20
+    field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
+    field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
+    field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int FOREGROUND_SERVICE_DEFAULT = 0; // 0x0
+    field public static final int FOREGROUND_SERVICE_DEFERRED = 2; // 0x2
+    field public static final int FOREGROUND_SERVICE_IMMEDIATE = 1; // 0x1
+    field public static final int GROUP_ALERT_ALL = 0; // 0x0
+    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
+    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
+    field public static final String GROUP_KEY_SILENT = "silent";
+    field public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
+    field public static final int PRIORITY_DEFAULT = 0; // 0x0
+    field public static final int PRIORITY_HIGH = 1; // 0x1
+    field public static final int PRIORITY_LOW = -1; // 0xffffffff
+    field public static final int PRIORITY_MAX = 2; // 0x2
+    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
+    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
+  }
+
+  public static class NotificationCompat.Action {
+    ctor public NotificationCompat.Action(int, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    method public android.app.PendingIntent? getActionIntent();
+    method public boolean getAllowGeneratedReplies();
+    method public androidx.core.app.RemoteInput![]? getDataOnlyRemoteInputs();
+    method public android.os.Bundle getExtras();
+    method @Deprecated public int getIcon();
+    method public androidx.core.graphics.drawable.IconCompat? getIconCompat();
+    method public androidx.core.app.RemoteInput![]? getRemoteInputs();
+    method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
+    method public boolean getShowsUserInterface();
+    method public CharSequence? getTitle();
+    method public boolean isAuthenticationRequired();
+    method public boolean isContextual();
+    field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
+    field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
+    field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
+    field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2
+    field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3
+    field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6
+    field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0
+    field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1
+    field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9
+    field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8
+    field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7
+    field public android.app.PendingIntent? actionIntent;
+    field @Deprecated public int icon;
+    field public CharSequence! title;
+  }
+
+  public static final class NotificationCompat.Action.Builder {
+    ctor public NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action.Builder(int, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action.Builder(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Action.Builder addRemoteInput(androidx.core.app.RemoteInput?);
+    method public androidx.core.app.NotificationCompat.Action build();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Extender);
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setAuthenticationRequired(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
+    method public androidx.core.app.NotificationCompat.Action.Builder setShowsUserInterface(boolean);
+  }
+
+  public static interface NotificationCompat.Action.Extender {
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_NONE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_REPLY, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_UNREAD, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_DELETE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_ARCHIVE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_UNMUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_UP, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_DOWN, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_CALL}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.Action.SemanticAction {
+  }
+
+  public static final class NotificationCompat.Action.WearableExtender implements androidx.core.app.NotificationCompat.Action.Extender {
+    ctor public NotificationCompat.Action.WearableExtender();
+    ctor public NotificationCompat.Action.WearableExtender(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+    method @Deprecated public CharSequence? getCancelLabel();
+    method @Deprecated public CharSequence? getConfirmLabel();
+    method public boolean getHintDisplayActionInline();
+    method public boolean getHintLaunchesActivity();
+    method @Deprecated public CharSequence? getInProgressLabel();
+    method public boolean isAvailableOffline();
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setCancelLabel(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setConfirmLabel(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setInProgressLabel(CharSequence?);
+  }
+
+  public static class NotificationCompat.BigPictureStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigPictureStyle();
+    ctor public NotificationCompat.BigPictureStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap?);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setBigContentTitle(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle setContentDescription(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setSummaryText(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle showBigPictureWhenCollapsed(boolean);
+  }
+
+  public static class NotificationCompat.BigTextStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigTextStyle();
+    ctor public NotificationCompat.BigTextStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle bigText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setSummaryText(CharSequence?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata {
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? fromPlatform(android.app.Notification.BubbleMetadata?);
+    method public boolean getAutoExpandBubble();
+    method public android.app.PendingIntent? getDeleteIntent();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getDesiredHeight();
+    method @DimenRes public int getDesiredHeightResId();
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public android.app.PendingIntent? getIntent();
+    method public String? getShortcutId();
+    method public boolean isNotificationSuppressed();
+    method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata.Builder {
+    ctor @Deprecated public NotificationCompat.BubbleMetadata.Builder();
+    ctor @RequiresApi(30) public NotificationCompat.BubbleMetadata.Builder(String);
+    ctor public NotificationCompat.BubbleMetadata.Builder(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata build();
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setAutoExpandBubble(boolean);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setSuppressNotification(boolean);
+  }
+
+  public static class NotificationCompat.Builder {
+    ctor @RequiresApi(19) public NotificationCompat.Builder(android.content.Context, android.app.Notification);
+    ctor public NotificationCompat.Builder(android.content.Context, String);
+    ctor @Deprecated public NotificationCompat.Builder(android.content.Context);
+    method public androidx.core.app.NotificationCompat.Builder addAction(int, CharSequence?, android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder addAction(androidx.core.app.NotificationCompat.Action?);
+    method public androidx.core.app.NotificationCompat.Builder addExtras(android.os.Bundle?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(int, CharSequence?, android.app.PendingIntent?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(androidx.core.app.NotificationCompat.Action?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder addPerson(String?);
+    method public androidx.core.app.NotificationCompat.Builder addPerson(androidx.core.app.Person?);
+    method public android.app.Notification build();
+    method public androidx.core.app.NotificationCompat.Builder clearActions();
+    method public androidx.core.app.NotificationCompat.Builder clearInvisibleActions();
+    method public androidx.core.app.NotificationCompat.Builder clearPeople();
+    method public android.widget.RemoteViews? createBigContentView();
+    method public android.widget.RemoteViews? createContentView();
+    method public android.widget.RemoteViews? createHeadsUpContentView();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Extender);
+    method public android.os.Bundle getExtras();
+    method @Deprecated public android.app.Notification getNotification();
+    method protected static CharSequence? limitCharSequenceLength(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setAutoCancel(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setBadgeIconType(int);
+    method public androidx.core.app.NotificationCompat.Builder setBubbleMetadata(androidx.core.app.NotificationCompat.BubbleMetadata?);
+    method public androidx.core.app.NotificationCompat.Builder setCategory(String?);
+    method public androidx.core.app.NotificationCompat.Builder setChannelId(String);
+    method @RequiresApi(24) public androidx.core.app.NotificationCompat.Builder setChronometerCountDown(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.Builder setColorized(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setContent(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setContentInfo(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setContentText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setDefaults(int);
+    method public androidx.core.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Builder setForegroundServiceBehavior(int);
+    method public androidx.core.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent?, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationCompat.Builder setGroupAlertBehavior(int);
+    method public androidx.core.app.NotificationCompat.Builder setGroupSummary(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.Builder setLights(@ColorInt int, int, int);
+    method public androidx.core.app.NotificationCompat.Builder setLocalOnly(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setNotificationSilent();
+    method public androidx.core.app.NotificationCompat.Builder setNumber(int);
+    method public androidx.core.app.NotificationCompat.Builder setOngoing(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPriority(int);
+    method public androidx.core.app.NotificationCompat.Builder setProgress(int, int, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPublicVersion(android.app.Notification?);
+    method public androidx.core.app.NotificationCompat.Builder setRemoteInputHistory(CharSequence![]?);
+    method public androidx.core.app.NotificationCompat.Builder setSettingsText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutId(String?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutInfo(androidx.core.content.pm.ShortcutInfoCompat?);
+    method public androidx.core.app.NotificationCompat.Builder setShowWhen(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setSilent(boolean);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.Builder setSmallIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int, int);
+    method public androidx.core.app.NotificationCompat.Builder setSortKey(String?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?, int);
+    method public androidx.core.app.NotificationCompat.Builder setStyle(androidx.core.app.NotificationCompat.Style?);
+    method public androidx.core.app.NotificationCompat.Builder setSubText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?, android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setTimeoutAfter(long);
+    method public androidx.core.app.NotificationCompat.Builder setUsesChronometer(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setVibrate(long[]?);
+    method public androidx.core.app.NotificationCompat.Builder setVisibility(int);
+    method public androidx.core.app.NotificationCompat.Builder setWhen(long);
+    field @Deprecated public java.util.ArrayList<java.lang.String!>! mPeople;
+  }
+
+  public static class NotificationCompat.CallStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.CallStyle();
+    ctor public NotificationCompat.CallStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public static androidx.core.app.NotificationCompat.CallStyle forIncomingCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forOngoingCall(androidx.core.app.Person, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forScreeningCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method public androidx.core.app.NotificationCompat.CallStyle setAnswerButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setDeclineButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setIsVideo(boolean);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationText(CharSequence?);
+    field public static final int CALL_TYPE_INCOMING = 1; // 0x1
+    field public static final int CALL_TYPE_ONGOING = 2; // 0x2
+    field public static final int CALL_TYPE_SCREENING = 3; // 0x3
+    field public static final int CALL_TYPE_UNKNOWN = 0; // 0x0
+  }
+
+  public static final class NotificationCompat.CarExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.CarExtender();
+    ctor public NotificationCompat.CarExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method @ColorInt public int getColor();
+    method public android.graphics.Bitmap? getLargeIcon();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation? getUnreadConversation();
+    method public androidx.core.app.NotificationCompat.CarExtender setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation?);
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation {
+    method @Deprecated public long getLatestTimestamp();
+    method @Deprecated public String![]? getMessages();
+    method @Deprecated public String? getParticipant();
+    method @Deprecated public String![]? getParticipants();
+    method @Deprecated public android.app.PendingIntent? getReadPendingIntent();
+    method @Deprecated public androidx.core.app.RemoteInput? getRemoteInput();
+    method @Deprecated public android.app.PendingIntent? getReplyPendingIntent();
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+    ctor @Deprecated public NotificationCompat.CarExtender.UnreadConversation.Builder(String);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation build();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent?, androidx.core.app.RemoteInput?);
+  }
+
+  public static class NotificationCompat.DecoratedCustomViewStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.DecoratedCustomViewStyle();
+  }
+
+  public static interface NotificationCompat.Extender {
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+  }
+
+  public static class NotificationCompat.InboxStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.InboxStyle();
+    ctor public NotificationCompat.InboxStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.InboxStyle addLine(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setSummaryText(CharSequence?);
+  }
+
+  public static class NotificationCompat.MessagingStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor @Deprecated public NotificationCompat.MessagingStyle(CharSequence);
+    ctor public NotificationCompat.MessagingStyle(androidx.core.app.Person);
+    method public void addCompatExtras(android.os.Bundle);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addHistoricMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method @Deprecated public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, CharSequence?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, androidx.core.app.Person?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method public static androidx.core.app.NotificationCompat.MessagingStyle? extractMessagingStyleFromNotification(android.app.Notification);
+    method public CharSequence? getConversationTitle();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getHistoricMessages();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getMessages();
+    method public androidx.core.app.Person getUser();
+    method @Deprecated public CharSequence? getUserDisplayName();
+    method public boolean isGroupConversation();
+    method public androidx.core.app.NotificationCompat.MessagingStyle setConversationTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle setGroupConversation(boolean);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class NotificationCompat.MessagingStyle.Message {
+    ctor public NotificationCompat.MessagingStyle.Message(CharSequence?, long, androidx.core.app.Person?);
+    ctor @Deprecated public NotificationCompat.MessagingStyle.Message(CharSequence?, long, CharSequence?);
+    method public String? getDataMimeType();
+    method public android.net.Uri? getDataUri();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.Person? getPerson();
+    method @Deprecated public CharSequence? getSender();
+    method public CharSequence? getText();
+    method public long getTimestamp();
+    method public androidx.core.app.NotificationCompat.MessagingStyle.Message setData(String?, android.net.Uri?);
+  }
+
+  public abstract static class NotificationCompat.Style {
+    ctor public NotificationCompat.Style();
+    method public android.app.Notification? build();
+    method public void setBuilder(androidx.core.app.NotificationCompat.Builder?);
+  }
+
+  public static final class NotificationCompat.WearableExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.WearableExtender();
+    ctor public NotificationCompat.WearableExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.WearableExtender addAction(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.WearableExtender addActions(java.util.List<androidx.core.app.NotificationCompat.Action!>);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification!>);
+    method public androidx.core.app.NotificationCompat.WearableExtender clearActions();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender clearPages();
+    method public androidx.core.app.NotificationCompat.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method public java.util.List<androidx.core.app.NotificationCompat.Action!> getActions();
+    method @Deprecated public android.graphics.Bitmap? getBackground();
+    method public String? getBridgeTag();
+    method public int getContentAction();
+    method @Deprecated public int getContentIcon();
+    method @Deprecated public int getContentIconGravity();
+    method public boolean getContentIntentAvailableOffline();
+    method @Deprecated public int getCustomContentHeight();
+    method @Deprecated public int getCustomSizePreset();
+    method public String? getDismissalId();
+    method @Deprecated public android.app.PendingIntent? getDisplayIntent();
+    method @Deprecated public int getGravity();
+    method @Deprecated public boolean getHintAmbientBigPicture();
+    method @Deprecated public boolean getHintAvoidBackgroundClipping();
+    method public boolean getHintContentIntentLaunchesActivity();
+    method @Deprecated public boolean getHintHideIcon();
+    method @Deprecated public int getHintScreenTimeout();
+    method @Deprecated public boolean getHintShowBackgroundOnly();
+    method @Deprecated public java.util.List<android.app.Notification!> getPages();
+    method public boolean getStartScrollBottom();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setBridgeTag(String?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentAction(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIcon(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIconGravity(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setDismissalId(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setGravity(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
+    field @Deprecated public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+    field @Deprecated public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
+    field @Deprecated public static final int SIZE_DEFAULT = 0; // 0x0
+    field @Deprecated public static final int SIZE_FULL_SCREEN = 5; // 0x5
+    field @Deprecated public static final int SIZE_LARGE = 4; // 0x4
+    field @Deprecated public static final int SIZE_MEDIUM = 3; // 0x3
+    field @Deprecated public static final int SIZE_SMALL = 2; // 0x2
+    field @Deprecated public static final int SIZE_XSMALL = 1; // 0x1
+    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+  }
+
+  public final class NotificationCompatExtras {
+    field public static final String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
+    field public static final String EXTRA_GROUP_KEY = "android.support.groupKey";
+    field public static final String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
+    field public static final String EXTRA_LOCAL_ONLY = "android.support.localOnly";
+    field public static final String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+    field public static final String EXTRA_SORT_KEY = "android.support.sortKey";
+  }
+
+  public abstract class NotificationCompatSideChannelService extends android.app.Service {
+    ctor public NotificationCompatSideChannelService();
+    method public abstract void cancel(String!, int, String!);
+    method public abstract void cancelAll(String!);
+    method public abstract void notify(String!, int, String!, android.app.Notification!);
+    method public android.os.IBinder! onBind(android.content.Intent!);
+  }
+
+  public final class NotificationManagerCompat {
+    method public boolean areNotificationsEnabled();
+    method public void cancel(int);
+    method public void cancel(String?, int);
+    method public void cancelAll();
+    method public void createNotificationChannel(android.app.NotificationChannel);
+    method public void createNotificationChannel(androidx.core.app.NotificationChannelCompat);
+    method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
+    method public void createNotificationChannelGroup(androidx.core.app.NotificationChannelGroupCompat);
+    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
+    method public void createNotificationChannelGroupsCompat(java.util.List<androidx.core.app.NotificationChannelGroupCompat!>);
+    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
+    method public void createNotificationChannelsCompat(java.util.List<androidx.core.app.NotificationChannelCompat!>);
+    method public void deleteNotificationChannel(String);
+    method public void deleteNotificationChannelGroup(String);
+    method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
+    method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
+    method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
+    method public int getImportance();
+    method public android.app.NotificationChannel? getNotificationChannel(String);
+    method public android.app.NotificationChannel? getNotificationChannel(String, String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String, String);
+    method public android.app.NotificationChannelGroup? getNotificationChannelGroup(String);
+    method public androidx.core.app.NotificationChannelGroupCompat? getNotificationChannelGroupCompat(String);
+    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
+    method public java.util.List<androidx.core.app.NotificationChannelGroupCompat!> getNotificationChannelGroupsCompat();
+    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getNotificationChannelsCompat();
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(int, android.app.Notification);
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(String?, int, android.app.Notification);
+    field public static final String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
+    field public static final String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
+    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
+    field public static final int IMPORTANCE_HIGH = 4; // 0x4
+    field public static final int IMPORTANCE_LOW = 2; // 0x2
+    field public static final int IMPORTANCE_MAX = 5; // 0x5
+    field public static final int IMPORTANCE_MIN = 1; // 0x1
+    field public static final int IMPORTANCE_NONE = 0; // 0x0
+    field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+  }
+
+  public interface OnMultiWindowModeChangedProvider {
+    method public void addOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+    method public void removeOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+  }
+
+  public interface OnNewIntentProvider {
+    method public void addOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+    method public void removeOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+  }
+
+  public interface OnPictureInPictureModeChangedProvider {
+    method public void addOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+    method public void removeOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+  }
+
+  public final class PendingIntentCompat {
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getBroadcast(android.content.Context, int, android.content.Intent, int, boolean);
+    method @RequiresApi(26) public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int, boolean);
+  }
+
+  public class Person {
+    method public static androidx.core.app.Person fromBundle(android.os.Bundle);
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public String? getKey();
+    method public CharSequence? getName();
+    method public String? getUri();
+    method public boolean isBot();
+    method public boolean isImportant();
+    method public androidx.core.app.Person.Builder toBuilder();
+    method public android.os.Bundle toBundle();
+  }
+
+  public static class Person.Builder {
+    ctor public Person.Builder();
+    method public androidx.core.app.Person build();
+    method public androidx.core.app.Person.Builder setBot(boolean);
+    method public androidx.core.app.Person.Builder setIcon(androidx.core.graphics.drawable.IconCompat?);
+    method public androidx.core.app.Person.Builder setImportant(boolean);
+    method public androidx.core.app.Person.Builder setKey(String?);
+    method public androidx.core.app.Person.Builder setName(CharSequence?);
+    method public androidx.core.app.Person.Builder setUri(String?);
+  }
+
+  public final class PictureInPictureModeChangedInfo {
+    ctor public PictureInPictureModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public PictureInPictureModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInPictureInPictureMode();
+  }
+
+  public final class RemoteActionCompat implements androidx.versionedparcelable.VersionedParcelable {
+    ctor public RemoteActionCompat(androidx.core.graphics.drawable.IconCompat, CharSequence, CharSequence, android.app.PendingIntent);
+    ctor public RemoteActionCompat(androidx.core.app.RemoteActionCompat);
+    method @RequiresApi(26) public static androidx.core.app.RemoteActionCompat createFromRemoteAction(android.app.RemoteAction);
+    method public android.app.PendingIntent getActionIntent();
+    method public CharSequence getContentDescription();
+    method public androidx.core.graphics.drawable.IconCompat getIcon();
+    method public CharSequence getTitle();
+    method public boolean isEnabled();
+    method public void setEnabled(boolean);
+    method public void setShouldShowIcon(boolean);
+    method public boolean shouldShowIcon();
+    method @RequiresApi(26) public android.app.RemoteAction toRemoteAction();
+  }
+
+  public final class RemoteInput {
+    method public static void addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String!,android.net.Uri!>);
+    method public static void addResultsToIntent(androidx.core.app.RemoteInput![], android.content.Intent, android.os.Bundle);
+    method public boolean getAllowFreeFormInput();
+    method public java.util.Set<java.lang.String!>? getAllowedDataTypes();
+    method public CharSequence![]? getChoices();
+    method public static java.util.Map<java.lang.String!,android.net.Uri!>? getDataResultsFromIntent(android.content.Intent, String);
+    method public int getEditChoicesBeforeSending();
+    method public android.os.Bundle getExtras();
+    method public CharSequence? getLabel();
+    method public String getResultKey();
+    method public static android.os.Bundle? getResultsFromIntent(android.content.Intent);
+    method public static int getResultsSource(android.content.Intent);
+    method public boolean isDataOnly();
+    method public static void setResultsSource(android.content.Intent, int);
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
+    field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+    field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+    field public static final int SOURCE_CHOICE = 1; // 0x1
+    field public static final int SOURCE_FREE_FORM_INPUT = 0; // 0x0
+  }
+
+  public static final class RemoteInput.Builder {
+    ctor public RemoteInput.Builder(String);
+    method public androidx.core.app.RemoteInput.Builder addExtras(android.os.Bundle);
+    method public androidx.core.app.RemoteInput build();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
+    method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+    method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence![]?);
+    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(int);
+    method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
+  }
+
+  public final class ServiceCompat {
+    method public static void stopForeground(android.app.Service, int);
+    field public static final int START_STICKY = 1; // 0x1
+    field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+    field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
+  }
+
+  public final class ShareCompat {
+    method @Deprecated public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
+    method @Deprecated public static void configureMenuItem(android.view.Menu, @IdRes int, androidx.core.app.ShareCompat.IntentBuilder);
+    method public static android.content.ComponentName? getCallingActivity(android.app.Activity);
+    method public static String? getCallingPackage(android.app.Activity);
+    field public static final String EXTRA_CALLING_ACTIVITY = "androidx.core.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_ACTIVITY_INTEROP = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_PACKAGE = "androidx.core.app.EXTRA_CALLING_PACKAGE";
+    field public static final String EXTRA_CALLING_PACKAGE_INTEROP = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
+  }
+
+  public static class ShareCompat.IntentBuilder {
+    ctor public ShareCompat.IntentBuilder(android.content.Context);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
+    method public android.content.Intent createChooserIntent();
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentBuilder from(android.app.Activity);
+    method public android.content.Intent getIntent();
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(@StringRes int);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailBcc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailCc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailTo(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setHtmlText(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setStream(android.net.Uri?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setSubject(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setText(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setType(String?);
+    method public void startChooser();
+  }
+
+  public static class ShareCompat.IntentReader {
+    ctor public ShareCompat.IntentReader(android.app.Activity);
+    ctor public ShareCompat.IntentReader(android.content.Context, android.content.Intent);
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentReader from(android.app.Activity);
+    method public android.content.ComponentName? getCallingActivity();
+    method public android.graphics.drawable.Drawable? getCallingActivityIcon();
+    method public android.graphics.drawable.Drawable? getCallingApplicationIcon();
+    method public CharSequence? getCallingApplicationLabel();
+    method public String? getCallingPackage();
+    method public String![]? getEmailBcc();
+    method public String![]? getEmailCc();
+    method public String![]? getEmailTo();
+    method public String? getHtmlText();
+    method public android.net.Uri? getStream();
+    method public android.net.Uri? getStream(int);
+    method public int getStreamCount();
+    method public String? getSubject();
+    method public CharSequence? getText();
+    method public String? getType();
+    method public boolean isMultipleShare();
+    method public boolean isShareIntent();
+    method public boolean isSingleShare();
+  }
+
+  public abstract class SharedElementCallback {
+    ctor public SharedElementCallback();
+    method public android.os.Parcelable! onCaptureSharedElementSnapshot(android.view.View!, android.graphics.Matrix!, android.graphics.RectF!);
+    method public android.view.View! onCreateSnapshotView(android.content.Context!, android.os.Parcelable!);
+    method public void onMapSharedElements(java.util.List<java.lang.String!>!, java.util.Map<java.lang.String!,android.view.View!>!);
+    method public void onRejectSharedElements(java.util.List<android.view.View!>!);
+    method public void onSharedElementEnd(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementStart(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementsArrived(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener!);
+  }
+
+  public static interface SharedElementCallback.OnSharedElementsReadyListener {
+    method public void onSharedElementsReady();
+  }
+
+  public final class TaskStackBuilder implements java.lang.Iterable<android.content.Intent> {
+    method public androidx.core.app.TaskStackBuilder addNextIntent(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.app.Activity);
+    method public androidx.core.app.TaskStackBuilder addParentStack(Class<?>);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.content.ComponentName);
+    method public static androidx.core.app.TaskStackBuilder create(android.content.Context);
+    method public android.content.Intent? editIntentAt(int);
+    method @Deprecated public static androidx.core.app.TaskStackBuilder! from(android.content.Context!);
+    method @Deprecated public android.content.Intent! getIntent(int);
+    method public int getIntentCount();
+    method public android.content.Intent![] getIntents();
+    method public android.app.PendingIntent? getPendingIntent(int, int);
+    method public android.app.PendingIntent? getPendingIntent(int, int, android.os.Bundle?);
+    method @Deprecated public java.util.Iterator<android.content.Intent!> iterator();
+    method public void startActivities();
+    method public void startActivities(android.os.Bundle?);
+  }
+
+  public static interface TaskStackBuilder.SupportParentable {
+    method public android.content.Intent? getSupportParentActivityIntent();
+  }
+
+}
+
+package androidx.core.content {
+
+  public final class ContentProviderCompat {
+    method public static android.content.Context requireContext(android.content.ContentProvider);
+  }
+
+  public final class ContentResolverCompat {
+    method public static android.database.Cursor? query(android.content.ContentResolver, android.net.Uri, String![]?, String?, String![]?, String?, androidx.core.os.CancellationSignal?);
+  }
+
+  public class ContextCompat {
+    ctor protected ContextCompat();
+    method public static int checkSelfPermission(android.content.Context, String);
+    method public static android.content.Context? createDeviceProtectedStorageContext(android.content.Context);
+    method public static String? getAttributionTag(android.content.Context);
+    method public static java.io.File getCodeCacheDir(android.content.Context);
+    method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
+    method public static java.io.File? getDataDir(android.content.Context);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
+    method public static java.io.File![] getExternalCacheDirs(android.content.Context);
+    method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
+    method public static java.util.concurrent.Executor getMainExecutor(android.content.Context);
+    method public static java.io.File? getNoBackupFilesDir(android.content.Context);
+    method public static java.io.File![] getObbDirs(android.content.Context);
+    method public static <T> T? getSystemService(android.content.Context, Class<T!>);
+    method public static String? getSystemServiceName(android.content.Context, Class<?>);
+    method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, int);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, String?, android.os.Handler?, int);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![]);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
+    method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
+    method public static void startForegroundService(android.content.Context, android.content.Intent);
+    field public static final int RECEIVER_EXPORTED = 2; // 0x2
+    field public static final int RECEIVER_NOT_EXPORTED = 4; // 0x4
+    field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
+  }
+
+  public class FileProvider extends android.content.ContentProvider {
+    ctor public FileProvider();
+    ctor protected FileProvider(@XmlRes int);
+    method public int delete(android.net.Uri, String?, String![]?);
+    method public String? getType(android.net.Uri);
+    method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
+    method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
+    method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
+    method public boolean onCreate();
+    method public android.database.Cursor query(android.net.Uri, String![]?, String?, String![]?, String?);
+    method public int update(android.net.Uri, android.content.ContentValues, String?, String![]?);
+  }
+
+  public final class IntentCompat {
+    method public static android.content.Intent createManageUnusedAppRestrictionsIntent(android.content.Context, String);
+    method public static android.os.Parcelable![]? getParcelableArrayExtra(android.content.Intent, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayListExtra(android.content.Intent, String?, Class<? extends T>);
+    method public static <T> T? getParcelableExtra(android.content.Intent, String?, Class<T!>);
+    method public static android.content.Intent makeMainSelectorActivity(String, String);
+    field public static final String ACTION_CREATE_REMINDER = "android.intent.action.CREATE_REMINDER";
+    field public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+    field public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
+    field public static final String EXTRA_TIME = "android.intent.extra.TIME";
+  }
+
+  public class IntentSanitizer {
+    method public android.content.Intent sanitize(android.content.Intent, androidx.core.util.Consumer<java.lang.String!>);
+    method public android.content.Intent sanitizeByFiltering(android.content.Intent);
+    method public android.content.Intent sanitizeByThrowing(android.content.Intent);
+  }
+
+  public static final class IntentSanitizer.Builder {
+    ctor public IntentSanitizer.Builder();
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowAnyComponent();
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipData(androidx.core.util.Predicate<android.content.ClipData!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataText();
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUri(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(android.content.ComponentName);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(androidx.core.util.Predicate<android.content.ComponentName!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponentWithPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowData(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowDataWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<?>);
+    method public <T> androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<T!>, androidx.core.util.Predicate<T!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, androidx.core.util.Predicate<java.lang.Object!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStream(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStreamUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowFlags(int);
+    method public androidx.core.content.IntentSanitizer.Builder allowHistoryStackFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowIdentifier();
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowReceiverFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowSelector();
+    method public androidx.core.content.IntentSanitizer.Builder allowSourceBounds();
+    method public androidx.core.content.IntentSanitizer.Builder allowType(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowType(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer build();
+  }
+
+  public final class LocusIdCompat {
+    ctor public LocusIdCompat(String);
+    method public String getId();
+    method @RequiresApi(29) public android.content.LocusId toLocusId();
+    method @RequiresApi(29) public static androidx.core.content.LocusIdCompat toLocusIdCompat(android.content.LocusId);
+  }
+
+  public final class MimeTypeFilter {
+    method public static boolean matches(String?, String);
+    method public static String? matches(String?, String![]);
+    method public static String? matches(String![]?, String);
+    method public static String![] matchesMany(String![]?, String);
+  }
+
+  public interface OnConfigurationChangedProvider {
+    method public void addOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+    method public void removeOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+  }
+
+  public interface OnTrimMemoryProvider {
+    method public void addOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+    method public void removeOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+  }
+
+  public final class PackageManagerCompat {
+    method public static com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> getUnusedAppRestrictionsStatus(android.content.Context);
+    field public static final String ACTION_PERMISSION_REVOCATION_SETTINGS = "android.intent.action.AUTO_REVOKE_PERMISSIONS";
+  }
+
+  public final class PermissionChecker {
+    method public static int checkCallingOrSelfPermission(android.content.Context, String);
+    method public static int checkCallingPermission(android.content.Context, String, String?);
+    method public static int checkPermission(android.content.Context, String, int, int, String?);
+    method public static int checkSelfPermission(android.content.Context, String);
+    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
+    field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
+    field public static final int PERMISSION_GRANTED = 0; // 0x0
+  }
+
+  @Deprecated public final class SharedPreferencesCompat {
+  }
+
+  @Deprecated public static final class SharedPreferencesCompat.EditorCompat {
+    method @Deprecated public void apply(android.content.SharedPreferences.Editor);
+    method @Deprecated public static androidx.core.content.SharedPreferencesCompat.EditorCompat! getInstance();
+  }
+
+  public class UnusedAppRestrictionsBackportCallback {
+    method public void onResult(boolean, boolean) throws android.os.RemoteException;
+  }
+
+  public abstract class UnusedAppRestrictionsBackportService extends android.app.Service {
+    ctor public UnusedAppRestrictionsBackportService();
+    method protected abstract void isPermissionRevocationEnabled(androidx.core.content.UnusedAppRestrictionsBackportCallback);
+    method public android.os.IBinder? onBind(android.content.Intent?);
+    field public static final String ACTION_UNUSED_APP_RESTRICTIONS_BACKPORT_CONNECTION = "android.support.unusedapprestrictions.action.CustomUnusedAppRestrictionsBackportService";
+  }
+
+  public final class UnusedAppRestrictionsConstants {
+    field public static final int API_30 = 4; // 0x4
+    field public static final int API_30_BACKPORT = 3; // 0x3
+    field public static final int API_31 = 5; // 0x5
+    field public static final int DISABLED = 2; // 0x2
+    field public static final int ERROR = 0; // 0x0
+    field public static final int FEATURE_NOT_AVAILABLE = 1; // 0x1
+  }
+
+  public class UriMatcherCompat {
+    method public static androidx.core.util.Predicate<android.net.Uri!> asPredicate(android.content.UriMatcher);
+  }
+
+}
+
+package androidx.core.content.pm {
+
+  @Deprecated public final class ActivityInfoCompat {
+    field @Deprecated public static final int CONFIG_UI_MODE = 512; // 0x200
+  }
+
+  public final class PackageInfoCompat {
+    method public static long getLongVersionCode(android.content.pm.PackageInfo);
+    method public static java.util.List<android.content.pm.Signature!> getSignatures(android.content.pm.PackageManager, String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static boolean hasSignatures(android.content.pm.PackageManager, String, @Size(min=1) java.util.Map<byte[]!,java.lang.Integer!>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
+  }
+
+  public final class PermissionInfoCompat {
+    method public static int getProtection(android.content.pm.PermissionInfo);
+    method public static int getProtectionFlags(android.content.pm.PermissionInfo);
+  }
+
+  public class ShortcutInfoCompat {
+    method public android.content.ComponentName? getActivity();
+    method public java.util.Set<java.lang.String!>? getCategories();
+    method public CharSequence? getDisabledMessage();
+    method public int getDisabledReason();
+    method public int getExcludedFromSurfaces();
+    method public android.os.PersistableBundle? getExtras();
+    method public String getId();
+    method public android.content.Intent getIntent();
+    method public android.content.Intent![] getIntents();
+    method public long getLastChangedTimestamp();
+    method public androidx.core.content.LocusIdCompat? getLocusId();
+    method public CharSequence? getLongLabel();
+    method public String getPackage();
+    method public int getRank();
+    method public CharSequence getShortLabel();
+    method public android.os.UserHandle? getUserHandle();
+    method public boolean hasKeyFieldsOnly();
+    method public boolean isCached();
+    method public boolean isDeclaredInManifest();
+    method public boolean isDynamic();
+    method public boolean isEnabled();
+    method public boolean isExcludedFromSurfaces(int);
+    method public boolean isImmutable();
+    method public boolean isPinned();
+    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
+    field public static final int SURFACE_LAUNCHER = 1; // 0x1
+  }
+
+  public static class ShortcutInfoCompat.Builder {
+    ctor public ShortcutInfoCompat.Builder(android.content.Context, String);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String, String, java.util.List<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat build();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setAlwaysBadged();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setCategories(java.util.Set<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExcludedFromSurfaces(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExtras(android.os.PersistableBundle);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIcon(androidx.core.graphics.drawable.IconCompat!);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIsConversation();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLabel(CharSequence);
+    method @Deprecated public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived(boolean);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPerson(androidx.core.app.Person);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPersons(androidx.core.app.Person![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setRank(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setShortLabel(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setSliceUri(android.net.Uri);
+  }
+
+  public class ShortcutManagerCompat {
+    method public static boolean addDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static android.content.Intent createShortcutResultIntent(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void disableShortcuts(android.content.Context, java.util.List<java.lang.String!>, CharSequence?);
+    method public static void enableShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
+    method public static int getIconMaxHeight(android.content.Context);
+    method public static int getIconMaxWidth(android.content.Context);
+    method public static int getMaxShortcutCountPerActivity(android.content.Context);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getShortcuts(android.content.Context, int);
+    method public static boolean isRateLimitingActive(android.content.Context);
+    method public static boolean isRequestPinShortcutSupported(android.content.Context);
+    method public static boolean pushDynamicShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void removeAllDynamicShortcuts(android.content.Context);
+    method public static void removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void removeLongLivedShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void reportShortcutUsed(android.content.Context, String);
+    method public static boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
+    method public static boolean setDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static boolean updateShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    field public static final String EXTRA_SHORTCUT_ID = "android.intent.extra.shortcut.ID";
+    field public static final int FLAG_MATCH_CACHED = 8; // 0x8
+    field public static final int FLAG_MATCH_DYNAMIC = 2; // 0x2
+    field public static final int FLAG_MATCH_MANIFEST = 1; // 0x1
+    field public static final int FLAG_MATCH_PINNED = 4; // 0x4
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class ConfigurationHelper {
+    method public static int getDensityDpi(android.content.res.Resources);
+  }
+
+  public final class ResourcesCompat {
+    method public static void clearCachesForTheme(android.content.res.Resources.Theme);
+    method public static android.graphics.Typeface? getCachedFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method @ColorInt public static int getColor(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.Resources, @DrawableRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawableForDensity(android.content.res.Resources, @DrawableRes int, int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static float getFloat(android.content.res.Resources, @DimenRes int);
+    method public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method public static void getFont(android.content.Context, @FontRes int, androidx.core.content.res.ResourcesCompat.FontCallback, android.os.Handler?) throws android.content.res.Resources.NotFoundException;
+    field @AnyRes public static final int ID_NULL = 0; // 0x0
+  }
+
+  public abstract static class ResourcesCompat.FontCallback {
+    ctor public ResourcesCompat.FontCallback();
+    method public abstract void onFontRetrievalFailed(int);
+    method public abstract void onFontRetrieved(android.graphics.Typeface);
+  }
+
+  public static final class ResourcesCompat.ThemeCompat {
+    method public static void rebase(android.content.res.Resources.Theme);
+  }
+
+}
+
+package androidx.core.database {
+
+  public final class CursorWindowCompat {
+    method public static android.database.CursorWindow create(String?, long);
+  }
+
+  @Deprecated public final class DatabaseUtilsCompat {
+    method @Deprecated public static String![]! appendSelectionArgs(String![]!, String![]!);
+    method @Deprecated public static String! concatenateWhere(String!, String!);
+  }
+
+}
+
+package androidx.core.database.sqlite {
+
+  public final class SQLiteCursorCompat {
+    method public static void setFillWindowForwardOnly(android.database.sqlite.SQLiteCursor, boolean);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapCompat {
+    method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, android.graphics.Rect?, boolean);
+    method public static int getAllocationByteCount(android.graphics.Bitmap);
+    method public static boolean hasMipMap(android.graphics.Bitmap);
+    method public static void setHasMipMap(android.graphics.Bitmap, boolean);
+  }
+
+  public class BlendModeColorFilterCompat {
+    method public static android.graphics.ColorFilter? createBlendModeColorFilterCompat(int, androidx.core.graphics.BlendModeCompat);
+  }
+
+  public enum BlendModeCompat {
+    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HUE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SATURATION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
+  }
+
+  public final class ColorUtils {
+    method @ColorInt public static int HSLToColor(float[]);
+    method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
+    method public static void LABToXYZ(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double, double[]);
+    method public static void RGBToHSL(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, float[]);
+    method public static void RGBToLAB(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method public static void RGBToXYZ(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method @ColorInt public static int XYZToColor(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double);
+    method public static void XYZToLAB(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double, double[]);
+    method @ColorInt public static int blendARGB(@ColorInt int, @ColorInt int, @FloatRange(from=0.0, to=1.0) float);
+    method public static void blendHSL(float[], float[], @FloatRange(from=0.0, to=1.0) float, float[]);
+    method public static void blendLAB(double[], double[], @FloatRange(from=0.0, to=1.0) double, double[]);
+    method public static double calculateContrast(@ColorInt int, @ColorInt int);
+    method @FloatRange(from=0.0, to=1.0) public static double calculateLuminance(@ColorInt int);
+    method public static int calculateMinimumAlpha(@ColorInt int, @ColorInt int, float);
+    method public static void colorToHSL(@ColorInt int, float[]);
+    method public static void colorToLAB(@ColorInt int, double[]);
+    method public static void colorToXYZ(@ColorInt int, double[]);
+    method public static int compositeColors(@ColorInt int, @ColorInt int);
+    method @RequiresApi(26) public static android.graphics.Color compositeColors(android.graphics.Color, android.graphics.Color);
+    method public static double distanceEuclidean(double[], double[]);
+    method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
+  }
+
+  public final class Insets {
+    method public static androidx.core.graphics.Insets add(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets max(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets min(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets of(int, int, int, int);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    method public static androidx.core.graphics.Insets subtract(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method @RequiresApi(api=29) public static androidx.core.graphics.Insets toCompatInsets(android.graphics.Insets);
+    method @RequiresApi(29) public android.graphics.Insets toPlatformInsets();
+    field public static final androidx.core.graphics.Insets NONE;
+    field public final int bottom;
+    field public final int left;
+    field public final int right;
+    field public final int top;
+  }
+
+  public final class PaintCompat {
+    method public static boolean hasGlyph(android.graphics.Paint, String);
+    method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
+  }
+
+  public final class PathSegment {
+    ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
+    method public android.graphics.PointF getEnd();
+    method public float getEndFraction();
+    method public android.graphics.PointF getStart();
+    method public float getStartFraction();
+  }
+
+  public final class PathUtils {
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path);
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path, @FloatRange(from=0) float);
+  }
+
+  public class TypefaceCompat {
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, int);
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, @IntRange(from=1, to=1000) int, boolean);
+  }
+
+}
+
+package androidx.core.graphics.drawable {
+
+  public final class DrawableCompat {
+    method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
+    method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
+    method public static void clearColorFilter(android.graphics.drawable.Drawable);
+    method public static int getAlpha(android.graphics.drawable.Drawable);
+    method public static android.graphics.ColorFilter? getColorFilter(android.graphics.drawable.Drawable);
+    method public static int getLayoutDirection(android.graphics.drawable.Drawable);
+    method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
+    method @Deprecated public static void jumpToCurrentState(android.graphics.drawable.Drawable);
+    method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
+    method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
+    method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
+    method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
+    method public static void setTint(android.graphics.drawable.Drawable, @ColorInt int);
+    method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList?);
+    method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode?);
+    method public static <T extends android.graphics.drawable.Drawable> T! unwrap(android.graphics.drawable.Drawable);
+    method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
+  }
+
+  public class IconCompat implements androidx.versionedparcelable.VersionedParcelable {
+    method public static androidx.core.graphics.drawable.IconCompat? createFromBundle(android.os.Bundle);
+    method @RequiresApi(23) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.content.Context, android.graphics.drawable.Icon);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithData(byte[], int, int);
+    method public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.Context, @DrawableRes int);
+    method @DrawableRes public int getResId();
+    method public String getResPackage();
+    method public int getType();
+    method public android.net.Uri getUri();
+    method public android.graphics.drawable.Drawable? loadDrawable(android.content.Context);
+    method public void onPostParceling();
+    method public void onPreParceling(boolean);
+    method public androidx.core.graphics.drawable.IconCompat setTint(@ColorInt int);
+    method public androidx.core.graphics.drawable.IconCompat setTintList(android.content.res.ColorStateList?);
+    method public androidx.core.graphics.drawable.IconCompat setTintMode(android.graphics.PorterDuff.Mode?);
+    method public android.os.Bundle toBundle();
+    method @Deprecated @RequiresApi(23) public android.graphics.drawable.Icon toIcon();
+    method @RequiresApi(23) public android.graphics.drawable.Icon toIcon(android.content.Context?);
+    field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
+    field public static final int TYPE_BITMAP = 1; // 0x1
+    field public static final int TYPE_DATA = 3; // 0x3
+    field public static final int TYPE_RESOURCE = 2; // 0x2
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int TYPE_URI = 4; // 0x4
+    field public static final int TYPE_URI_ADAPTIVE_BITMAP = 6; // 0x6
+  }
+
+  public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.Bitmap? getBitmap();
+    method public float getCornerRadius();
+    method public int getGravity();
+    method public int getOpacity();
+    method public final android.graphics.Paint getPaint();
+    method public boolean hasAntiAlias();
+    method public boolean hasMipMap();
+    method public boolean isCircular();
+    method public void setAlpha(int);
+    method public void setAntiAlias(boolean);
+    method public void setCircular(boolean);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setCornerRadius(float);
+    method public void setDither(boolean);
+    method public void setGravity(int);
+    method public void setMipMap(boolean);
+    method public void setTargetDensity(android.graphics.Canvas);
+    method public void setTargetDensity(android.util.DisplayMetrics);
+    method public void setTargetDensity(int);
+  }
+
+  public final class RoundedBitmapDrawableFactory {
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap?);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, String);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
+  }
+
+}
+
+package androidx.core.hardware.display {
+
+  public final class DisplayManagerCompat {
+    method public android.view.Display? getDisplay(int);
+    method public android.view.Display![] getDisplays();
+    method public android.view.Display![] getDisplays(String?);
+    method public static androidx.core.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
+    field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+  }
+
+}
+
+package androidx.core.hardware.fingerprint {
+
+  @Deprecated public class FingerprintManagerCompat {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public void authenticate(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject?, int, androidx.core.os.CancellationSignal?, androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler?);
+    method @Deprecated public static androidx.core.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean hasEnrolledFingerprints();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean isHardwareDetected();
+  }
+
+  @Deprecated public abstract static class FingerprintManagerCompat.AuthenticationCallback {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationCallback();
+    method @Deprecated public void onAuthenticationError(int, CharSequence!);
+    method @Deprecated public void onAuthenticationFailed();
+    method @Deprecated public void onAuthenticationHelp(int, CharSequence!);
+    method @Deprecated public void onAuthenticationSucceeded(androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult!);
+  }
+
+  @Deprecated public static final class FingerprintManagerCompat.AuthenticationResult {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationResult(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject!);
+    method @Deprecated public androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject! getCryptoObject();
+  }
+
+  @Deprecated public static class FingerprintManagerCompat.CryptoObject {
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
+    method @Deprecated public javax.crypto.Cipher? getCipher();
+    method @Deprecated public javax.crypto.Mac? getMac();
+    method @Deprecated public java.security.Signature? getSignature();
+  }
+
+}
+
+package androidx.core.location {
+
+  public abstract class GnssStatusCompat {
+    method @FloatRange(from=0, to=360) public abstract float getAzimuthDegrees(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getBasebandCn0DbHz(@IntRange(from=0) int);
+    method @FloatRange(from=0) public abstract float getCarrierFrequencyHz(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getCn0DbHz(@IntRange(from=0) int);
+    method public abstract int getConstellationType(@IntRange(from=0) int);
+    method @FloatRange(from=0xffffffa6, to=90) public abstract float getElevationDegrees(@IntRange(from=0) int);
+    method @IntRange(from=0) public abstract int getSatelliteCount();
+    method @IntRange(from=1, to=200) public abstract int getSvid(@IntRange(from=0) int);
+    method public abstract boolean hasAlmanacData(@IntRange(from=0) int);
+    method public abstract boolean hasBasebandCn0DbHz(@IntRange(from=0) int);
+    method public abstract boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
+    method public abstract boolean hasEphemerisData(@IntRange(from=0) int);
+    method public abstract boolean usedInFix(@IntRange(from=0) int);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static androidx.core.location.GnssStatusCompat wrap(android.location.GnssStatus);
+    method public static androidx.core.location.GnssStatusCompat wrap(android.location.GpsStatus);
+    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
+    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
+    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
+    field public static final int CONSTELLATION_GPS = 1; // 0x1
+    field public static final int CONSTELLATION_IRNSS = 7; // 0x7
+    field public static final int CONSTELLATION_QZSS = 4; // 0x4
+    field public static final int CONSTELLATION_SBAS = 2; // 0x2
+    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
+  }
+
+  public abstract static class GnssStatusCompat.Callback {
+    ctor public GnssStatusCompat.Callback();
+    method public void onFirstFix(@IntRange(from=0) int);
+    method public void onSatelliteStatusChanged(androidx.core.location.GnssStatusCompat);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public final class LocationCompat {
+    method public static float getBearingAccuracyDegrees(android.location.Location);
+    method public static long getElapsedRealtimeMillis(android.location.Location);
+    method public static long getElapsedRealtimeNanos(android.location.Location);
+    method @FloatRange(from=0.0) public static float getMslAltitudeAccuracyMeters(android.location.Location);
+    method public static double getMslAltitudeMeters(android.location.Location);
+    method public static float getSpeedAccuracyMetersPerSecond(android.location.Location);
+    method public static float getVerticalAccuracyMeters(android.location.Location);
+    method public static boolean hasBearingAccuracy(android.location.Location);
+    method public static boolean hasMslAltitude(android.location.Location);
+    method public static boolean hasMslAltitudeAccuracy(android.location.Location);
+    method public static boolean hasSpeedAccuracy(android.location.Location);
+    method public static boolean hasVerticalAccuracy(android.location.Location);
+    method public static boolean isMock(android.location.Location);
+    method public static void removeMslAltitude(android.location.Location);
+    method public static void removeMslAltitudeAccuracy(android.location.Location);
+    method public static void setBearingAccuracyDegrees(android.location.Location, float);
+    method public static void setMock(android.location.Location, boolean);
+    method public static void setMslAltitudeAccuracyMeters(android.location.Location, @FloatRange(from=0.0) float);
+    method public static void setMslAltitudeMeters(android.location.Location, double);
+    method public static void setSpeedAccuracyMetersPerSecond(android.location.Location, float);
+    method public static void setVerticalAccuracyMeters(android.location.Location, float);
+    field public static final String EXTRA_BEARING_ACCURACY = "bearingAccuracy";
+    field public static final String EXTRA_IS_MOCK = "mockLocation";
+    field public static final String EXTRA_MSL_ALTITUDE = "androidx.core.location.extra.MSL_ALTITUDE";
+    field public static final String EXTRA_MSL_ALTITUDE_ACCURACY = "androidx.core.location.extra.MSL_ALTITUDE_ACCURACY";
+    field public static final String EXTRA_SPEED_ACCURACY = "speedAccuracy";
+    field public static final String EXTRA_VERTICAL_ACCURACY = "verticalAccuracy";
+  }
+
+  public interface LocationListenerCompat extends android.location.LocationListener {
+    method public default void onStatusChanged(String, int, android.os.Bundle?);
+  }
+
+  public final class LocationManagerCompat {
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void getCurrentLocation(android.location.LocationManager, String, androidx.core.os.CancellationSignal?, java.util.concurrent.Executor, androidx.core.util.Consumer<android.location.Location!>);
+    method public static String? getGnssHardwareModelName(android.location.LocationManager);
+    method public static int getGnssYearOfHardware(android.location.LocationManager);
+    method public static boolean hasProvider(android.location.LocationManager, String);
+    method public static boolean isLocationEnabled(android.location.LocationManager);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
+    method @RequiresApi(android.os.Build.VERSION_CODES.R) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, java.util.concurrent.Executor, android.location.GnssMeasurementsEvent.Callback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback, android.os.Handler);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, java.util.concurrent.Executor, androidx.core.location.GnssStatusCompat.Callback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void removeUpdates(android.location.LocationManager, androidx.core.location.LocationListenerCompat);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, java.util.concurrent.Executor, androidx.core.location.LocationListenerCompat);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, androidx.core.location.LocationListenerCompat, android.os.Looper);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static void unregisterGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback);
+    method public static void unregisterGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback);
+  }
+
+  public final class LocationRequestCompat {
+    method @IntRange(from=1) public long getDurationMillis();
+    method @IntRange(from=0) public long getIntervalMillis();
+    method @IntRange(from=0) public long getMaxUpdateDelayMillis();
+    method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates();
+    method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters();
+    method @IntRange(from=0) public long getMinUpdateIntervalMillis();
+    method public int getQuality();
+    method @RequiresApi(31) public android.location.LocationRequest toLocationRequest();
+    method @RequiresApi(19) public android.location.LocationRequest? toLocationRequest(String);
+    field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL
+    field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66
+    field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64
+    field public static final int QUALITY_LOW_POWER = 104; // 0x68
+  }
+
+  public static final class LocationRequestCompat.Builder {
+    ctor public LocationRequestCompat.Builder(long);
+    ctor public LocationRequestCompat.Builder(androidx.core.location.LocationRequestCompat);
+    method public androidx.core.location.LocationRequestCompat build();
+    method public androidx.core.location.LocationRequestCompat.Builder clearMinUpdateIntervalMillis();
+    method public androidx.core.location.LocationRequestCompat.Builder setDurationMillis(@IntRange(from=1) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdateDelayMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setQuality(int);
+  }
+
+}
+
+package androidx.core.math {
+
+  public class MathUtils {
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
+    method public static float clamp(float, float, float);
+    method public static double clamp(double, double, double);
+    method public static int clamp(int, int, int);
+    method public static long clamp(long, long, long);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
+    method public static int toIntExact(long);
+  }
+
+}
+
+package androidx.core.net {
+
+  public final class ConnectivityManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static android.net.NetworkInfo? getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
+    method public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
+    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+  }
+
+  public final class MailTo {
+    method public String? getBcc();
+    method public String? getBody();
+    method public String? getCc();
+    method public java.util.Map<java.lang.String!,java.lang.String!>? getHeaders();
+    method public String? getSubject();
+    method public String? getTo();
+    method public static boolean isMailTo(String?);
+    method public static boolean isMailTo(android.net.Uri?);
+    method public static androidx.core.net.MailTo parse(String) throws androidx.core.net.ParseException;
+    method public static androidx.core.net.MailTo parse(android.net.Uri) throws androidx.core.net.ParseException;
+    field public static final String MAILTO_SCHEME = "mailto:";
+  }
+
+  public class ParseException extends java.lang.RuntimeException {
+    field public final String response;
+  }
+
+  public final class TrafficStatsCompat {
+    method @Deprecated public static void clearThreadStatsTag();
+    method @Deprecated public static int getThreadStatsTag();
+    method @Deprecated public static void incrementOperationCount(int);
+    method @Deprecated public static void incrementOperationCount(int, int);
+    method @Deprecated public static void setThreadStatsTag(int);
+    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void tagSocket(java.net.Socket!) throws java.net.SocketException;
+    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void untagSocket(java.net.Socket!) throws java.net.SocketException;
+  }
+
+  public final class UriCompat {
+    method public static String toSafeString(android.net.Uri);
+  }
+
+}
+
+package androidx.core.os {
+
+  public class BuildCompat {
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N) public static boolean isAtLeastN();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N_MR1) public static boolean isAtLeastNMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O) public static boolean isAtLeastO();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O_MR1) public static boolean isAtLeastOMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.P) public static boolean isAtLeastP();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
+    method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
+    field @ChecksSdkIntAtLeast(extension=android.os.ext.SdkExtensions.AD_SERVICES) public static final int AD_SERVICES_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.R) public static final int R_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.S) public static final int S_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.TIRAMISU) public static final int T_EXTENSION_INT;
+  }
+
+  public final class BundleCompat {
+    method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
+    method public static android.os.Parcelable![]? getParcelableArray(android.os.Bundle, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayList(android.os.Bundle, String?, Class<? extends T>);
+    method public static <T> android.util.SparseArray<T!>? getSparseParcelableArray(android.os.Bundle, String?, Class<? extends T>);
+  }
+
+  public final class CancellationSignal {
+    ctor public CancellationSignal();
+    method public void cancel();
+    method public Object? getCancellationSignalObject();
+    method public boolean isCanceled();
+    method public void setOnCancelListener(androidx.core.os.CancellationSignal.OnCancelListener?);
+    method public void throwIfCanceled();
+  }
+
+  public static interface CancellationSignal.OnCancelListener {
+    method public void onCancel();
+  }
+
+  public final class ConfigurationCompat {
+    method public static androidx.core.os.LocaleListCompat getLocales(android.content.res.Configuration);
+  }
+
+  public final class EnvironmentCompat {
+    method public static String getStorageState(java.io.File);
+    field public static final String MEDIA_UNKNOWN = "unknown";
+  }
+
+  public final class ExecutorCompat {
+    method public static java.util.concurrent.Executor create(android.os.Handler);
+  }
+
+  public final class HandlerCompat {
+    method public static android.os.Handler createAsync(android.os.Looper);
+    method public static android.os.Handler createAsync(android.os.Looper, android.os.Handler.Callback);
+    method @RequiresApi(16) public static boolean hasCallbacks(android.os.Handler, Runnable);
+    method public static boolean postDelayed(android.os.Handler, Runnable, Object?, long);
+  }
+
+  public final class LocaleListCompat {
+    method public static androidx.core.os.LocaleListCompat create(java.util.Locale!...);
+    method public static androidx.core.os.LocaleListCompat forLanguageTags(String?);
+    method public java.util.Locale? get(int);
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getAdjustedDefault();
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getDefault();
+    method public static androidx.core.os.LocaleListCompat getEmptyLocaleList();
+    method public java.util.Locale? getFirstMatch(String![]);
+    method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
+    method public boolean isEmpty();
+    method @RequiresApi(21) public static boolean matchesLanguageAndScript(java.util.Locale, java.util.Locale);
+    method @IntRange(from=0) public int size();
+    method public String toLanguageTags();
+    method public Object? unwrap();
+    method @Deprecated @RequiresApi(24) public static androidx.core.os.LocaleListCompat! wrap(Object!);
+    method @RequiresApi(24) public static androidx.core.os.LocaleListCompat wrap(android.os.LocaleList);
+  }
+
+  public final class MessageCompat {
+    method public static boolean isAsynchronous(android.os.Message);
+    method public static void setAsynchronous(android.os.Message, boolean);
+  }
+
+  public class OperationCanceledException extends java.lang.RuntimeException {
+    ctor public OperationCanceledException();
+    ctor public OperationCanceledException(String?);
+  }
+
+  public final class ParcelCompat {
+    method public static <T> Object![]? readArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> java.util.ArrayList<T!>? readArrayList(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static boolean readBoolean(android.os.Parcel);
+    method public static <K, V> java.util.HashMap<K!,V!>? readHashMap(android.os.Parcel, ClassLoader?, Class<? extends K>, Class<? extends V>);
+    method public static <T> void readList(android.os.Parcel, java.util.List<? super T>, ClassLoader?, Class<T!>);
+    method public static <K, V> void readMap(android.os.Parcel, java.util.Map<? super K,? super V>, ClassLoader?, Class<K!>, Class<V!>);
+    method public static <T extends android.os.Parcelable> T? readParcelable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @Deprecated public static <T> T![]? readParcelableArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.os.Parcelable![]? readParcelableArrayTyped(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(30) public static <T> android.os.Parcelable.Creator<T!>? readParcelableCreator(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.Q) public static <T> java.util.List<T!> readParcelableList(android.os.Parcel, java.util.List<T!>, ClassLoader?, Class<T!>);
+    method public static <T extends java.io.Serializable> T? readSerializable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.util.SparseArray<T!>? readSparseArray(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static void writeBoolean(android.os.Parcel, boolean);
+  }
+
+  @Deprecated public final class ParcelableCompat {
+    method @Deprecated public static <T> android.os.Parcelable.Creator<T!>! newCreator(androidx.core.os.ParcelableCompatCreatorCallbacks<T!>!);
+  }
+
+  @Deprecated public interface ParcelableCompatCreatorCallbacks<T> {
+    method @Deprecated public T! createFromParcel(android.os.Parcel!, ClassLoader!);
+    method @Deprecated public T![]! newArray(int);
+  }
+
+  public final class ProcessCompat {
+    method public static boolean isApplicationUid(int);
+  }
+
+  @Deprecated public final class TraceCompat {
+    method @Deprecated public static void beginAsyncSection(String, int);
+    method @Deprecated public static void beginSection(String);
+    method @Deprecated public static void endAsyncSection(String, int);
+    method @Deprecated public static void endSection();
+    method @Deprecated public static boolean isEnabled();
+    method @Deprecated public static void setCounter(String, int);
+  }
+
+  @RequiresApi(17) public class UserHandleCompat {
+    method public static android.os.UserHandle getUserHandleForUid(int);
+  }
+
+  public class UserManagerCompat {
+    method public static boolean isUserUnlocked(android.content.Context);
+  }
+
+}
+
+package androidx.core.provider {
+
+  public final class DocumentsContractCompat {
+    method public static android.net.Uri? buildChildDocumentsUri(String, String?);
+    method public static android.net.Uri? buildChildDocumentsUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildDocumentUri(String, String);
+    method public static android.net.Uri? buildDocumentUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildTreeDocumentUri(String, String);
+    method public static android.net.Uri? createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException;
+    method public static String? getDocumentId(android.net.Uri);
+    method public static String? getTreeDocumentId(android.net.Uri);
+    method public static boolean isDocumentUri(android.content.Context, android.net.Uri?);
+    method public static boolean isTreeUri(android.net.Uri);
+    method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.net.Uri? renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException;
+  }
+
+  public static final class DocumentsContractCompat.DocumentCompat {
+    field public static final int FLAG_VIRTUAL_DOCUMENT = 512; // 0x200
+  }
+
+  public final class FontRequest {
+    ctor public FontRequest(String, String, String, java.util.List<java.util.List<byte[]!>!>);
+    ctor public FontRequest(String, String, String, @ArrayRes int);
+    method public java.util.List<java.util.List<byte[]!>!>? getCertificates();
+    method @ArrayRes public int getCertificatesArrayResId();
+    method public String getProviderAuthority();
+    method public String getProviderPackage();
+    method public String getQuery();
+  }
+
+  public class FontsContractCompat {
+    method public static android.graphics.Typeface? buildTypeface(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![]);
+    method public static androidx.core.provider.FontsContractCompat.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void requestFont(android.content.Context, androidx.core.provider.FontRequest, androidx.core.provider.FontsContractCompat.FontRequestCallback, android.os.Handler);
+  }
+
+  public static final class FontsContractCompat.Columns implements android.provider.BaseColumns {
+    ctor public FontsContractCompat.Columns();
+    field public static final String FILE_ID = "file_id";
+    field public static final String ITALIC = "font_italic";
+    field public static final String RESULT_CODE = "result_code";
+    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
+    field public static final int RESULT_CODE_OK = 0; // 0x0
+    field public static final String TTC_INDEX = "font_ttc_index";
+    field public static final String VARIATION_SETTINGS = "font_variation_settings";
+    field public static final String WEIGHT = "font_weight";
+  }
+
+  public static class FontsContractCompat.FontFamilyResult {
+    method public androidx.core.provider.FontsContractCompat.FontInfo![]! getFonts();
+    method public int getStatusCode();
+    field public static final int STATUS_OK = 0; // 0x0
+    field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
+    field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
+  }
+
+  public static class FontsContractCompat.FontInfo {
+    method public int getResultCode();
+    method @IntRange(from=0) public int getTtcIndex();
+    method public android.net.Uri getUri();
+    method @IntRange(from=1, to=1000) public int getWeight();
+    method public boolean isItalic();
+  }
+
+  public static class FontsContractCompat.FontRequestCallback {
+    ctor public FontsContractCompat.FontRequestCallback();
+    method public void onTypefaceRequestFailed(int);
+    method public void onTypefaceRetrieved(android.graphics.Typeface!);
+    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+    field public static final int FAIL_REASON_SECURITY_VIOLATION = -4; // 0xfffffffc
+    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
+  }
+
+}
+
+package androidx.core.telephony {
+
+  @RequiresApi(22) public class SubscriptionManagerCompat {
+    method public static int getSlotIndex(int);
+  }
+
+  public class TelephonyManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static String? getImei(android.telephony.TelephonyManager);
+    method public static int getSubscriptionId(android.telephony.TelephonyManager);
+  }
+
+}
+
+package androidx.core.telephony.mbms {
+
+  public final class MbmsHelper {
+    method public static CharSequence? getBestNameForService(android.content.Context, android.telephony.mbms.ServiceInfo);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class BidiFormatter {
+    method public static androidx.core.text.BidiFormatter! getInstance();
+    method public static androidx.core.text.BidiFormatter! getInstance(boolean);
+    method public static androidx.core.text.BidiFormatter! getInstance(java.util.Locale!);
+    method public boolean getStereoReset();
+    method public boolean isRtl(String!);
+    method public boolean isRtl(CharSequence!);
+    method public boolean isRtlContext();
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public String! unicodeWrap(String!, boolean);
+    method public CharSequence! unicodeWrap(CharSequence!, boolean);
+    method public String! unicodeWrap(String!);
+    method public CharSequence! unicodeWrap(CharSequence!);
+  }
+
+  public static final class BidiFormatter.Builder {
+    ctor public BidiFormatter.Builder();
+    ctor public BidiFormatter.Builder(boolean);
+    ctor public BidiFormatter.Builder(java.util.Locale!);
+    method public androidx.core.text.BidiFormatter! build();
+    method public androidx.core.text.BidiFormatter.Builder! setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat!);
+    method public androidx.core.text.BidiFormatter.Builder! stereoReset(boolean);
+  }
+
+  public final class HtmlCompat {
+    method public static android.text.Spanned fromHtml(String, int);
+    method public static android.text.Spanned fromHtml(String, int, android.text.Html.ImageGetter?, android.text.Html.TagHandler?);
+    method public static String toHtml(android.text.Spanned, int);
+    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
+    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
+    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
+    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
+    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
+  }
+
+  public final class ICUCompat {
+    method public static String? maximizeAndGetScript(java.util.Locale);
+  }
+
+  public class PrecomputedTextCompat implements android.text.Spannable {
+    method public char charAt(int);
+    method public static androidx.core.text.PrecomputedTextCompat! create(CharSequence, androidx.core.text.PrecomputedTextCompat.Params);
+    method @IntRange(from=0) public int getParagraphCount();
+    method @IntRange(from=0) public int getParagraphEnd(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getParagraphStart(@IntRange(from=0) int);
+    method public androidx.core.text.PrecomputedTextCompat.Params getParams();
+    method public int getSpanEnd(Object!);
+    method public int getSpanFlags(Object!);
+    method public int getSpanStart(Object!);
+    method public <T> T![]! getSpans(int, int, Class<T!>!);
+    method @UiThread public static java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>! getTextFuture(CharSequence, androidx.core.text.PrecomputedTextCompat.Params, java.util.concurrent.Executor?);
+    method public int length();
+    method public int nextSpanTransition(int, int, Class!);
+    method public void removeSpan(Object!);
+    method public void setSpan(Object!, int, int, int);
+    method public CharSequence! subSequence(int, int);
+  }
+
+  public static final class PrecomputedTextCompat.Params {
+    ctor @RequiresApi(28) public PrecomputedTextCompat.Params(android.text.PrecomputedText.Params);
+    method @RequiresApi(23) public int getBreakStrategy();
+    method @RequiresApi(23) public int getHyphenationFrequency();
+    method @RequiresApi(18) public android.text.TextDirectionHeuristic? getTextDirection();
+    method public android.text.TextPaint getTextPaint();
+  }
+
+  public static class PrecomputedTextCompat.Params.Builder {
+    ctor public PrecomputedTextCompat.Params.Builder(android.text.TextPaint);
+    method public androidx.core.text.PrecomputedTextCompat.Params build();
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setBreakStrategy(int);
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setHyphenationFrequency(int);
+    method @RequiresApi(18) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setTextDirection(android.text.TextDirectionHeuristic);
+  }
+
+  public interface TextDirectionHeuristicCompat {
+    method public boolean isRtl(char[]!, int, int);
+    method public boolean isRtl(CharSequence!, int, int);
+  }
+
+  public final class TextDirectionHeuristicsCompat {
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! ANYRTL_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_RTL;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LOCALE;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! RTL;
+  }
+
+  public final class TextUtilsCompat {
+    method public static int getLayoutDirectionFromLocale(java.util.Locale?);
+    method public static String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.text.util {
+
+  public final class LinkifyCompat {
+    method public static boolean addLinks(android.text.Spannable, int);
+    method public static boolean addLinks(android.widget.TextView, int);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+  }
+
+}
+
+package androidx.core.util {
+
+  public class AtomicFile {
+    ctor public AtomicFile(java.io.File);
+    method public void delete();
+    method public void failWrite(java.io.FileOutputStream?);
+    method public void finishWrite(java.io.FileOutputStream?);
+    method public java.io.File getBaseFile();
+    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
+    method public byte[] readFully() throws java.io.IOException;
+    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+  }
+
+  public interface Consumer<T> {
+    method public void accept(T!);
+  }
+
+  public class ObjectsCompat {
+    method public static boolean equals(Object?, Object?);
+    method public static int hash(java.lang.Object!...);
+    method public static int hashCode(Object?);
+    method public static <T> T requireNonNull(T?);
+    method public static <T> T requireNonNull(T?, String);
+    method public static String? toString(Object?, String?);
+  }
+
+  public class Pair<F, S> {
+    ctor public Pair(F!, S!);
+    method public static <A, B> androidx.core.util.Pair<A!,B!> create(A!, B!);
+    field public final F! first;
+    field public final S! second;
+  }
+
+  public final class PatternsCompat {
+    field public static final java.util.regex.Pattern DOMAIN_NAME;
+    field public static final java.util.regex.Pattern EMAIL_ADDRESS;
+    field public static final java.util.regex.Pattern IP_ADDRESS;
+    field public static final java.util.regex.Pattern WEB_URL;
+  }
+
+  public final class Pools {
+  }
+
+  public static interface Pools.Pool<T> {
+    method public T? acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SimplePool<T> implements androidx.core.util.Pools.Pool<T> {
+    ctor public Pools.SimplePool(int);
+    method public T! acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SynchronizedPool<T> extends androidx.core.util.Pools.SimplePool<T> {
+    ctor public Pools.SynchronizedPool(int);
+  }
+
+  public interface Predicate<T> {
+    method public default androidx.core.util.Predicate<T!>! and(androidx.core.util.Predicate<? super T>!);
+    method public static <T> androidx.core.util.Predicate<T!>! isEqual(Object!);
+    method public default androidx.core.util.Predicate<T!>! negate();
+    method public static <T> androidx.core.util.Predicate<T!>! not(androidx.core.util.Predicate<? super T>!);
+    method public default androidx.core.util.Predicate<T!>! or(androidx.core.util.Predicate<? super T>!);
+    method public boolean test(T!);
+  }
+
+  public final class SizeFCompat {
+    ctor public SizeFCompat(float, float);
+    method public float getHeight();
+    method public float getWidth();
+    method @RequiresApi(21) public android.util.SizeF toSizeF();
+    method @RequiresApi(21) public static androidx.core.util.SizeFCompat toSizeFCompat(android.util.SizeF);
+  }
+
+  public interface Supplier<T> {
+    method public T! get();
+  }
+
+}
+
+package androidx.core.view {
+
+  public class AccessibilityDelegateCompat {
+    ctor public AccessibilityDelegateCompat();
+    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public void sendAccessibilityEvent(android.view.View, int);
+    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+  }
+
+  public abstract class ActionProvider {
+    ctor public ActionProvider(android.content.Context);
+    method public android.content.Context getContext();
+    method public boolean hasSubMenu();
+    method public boolean isVisible();
+    method public abstract android.view.View onCreateActionView();
+    method public android.view.View onCreateActionView(android.view.MenuItem);
+    method public boolean onPerformDefaultAction();
+    method public void onPrepareSubMenu(android.view.SubMenu);
+    method public boolean overridesItemVisibility();
+    method public void refreshVisibility();
+    method public void setVisibilityListener(androidx.core.view.ActionProvider.VisibilityListener?);
+  }
+
+  public static interface ActionProvider.VisibilityListener {
+    method public void onActionProviderVisibilityChanged(boolean);
+  }
+
+  public final class ContentInfoCompat {
+    method public android.content.ClipData getClip();
+    method public android.os.Bundle? getExtras();
+    method public int getFlags();
+    method public android.net.Uri? getLinkUri();
+    method public int getSource();
+    method public android.util.Pair<androidx.core.view.ContentInfoCompat!,androidx.core.view.ContentInfoCompat!> partition(androidx.core.util.Predicate<android.content.ClipData.Item!>);
+    method @RequiresApi(31) public static android.util.Pair<android.view.ContentInfo!,android.view.ContentInfo!> partition(android.view.ContentInfo, java.util.function.Predicate<android.content.ClipData.Item!>);
+    method @RequiresApi(31) public android.view.ContentInfo toContentInfo();
+    method @RequiresApi(31) public static androidx.core.view.ContentInfoCompat toContentInfoCompat(android.view.ContentInfo);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_APP = 0; // 0x0
+    field public static final int SOURCE_AUTOFILL = 4; // 0x4
+    field public static final int SOURCE_CLIPBOARD = 1; // 0x1
+    field public static final int SOURCE_DRAG_AND_DROP = 3; // 0x3
+    field public static final int SOURCE_INPUT_METHOD = 2; // 0x2
+    field public static final int SOURCE_PROCESS_TEXT = 5; // 0x5
+  }
+
+  public static final class ContentInfoCompat.Builder {
+    ctor public ContentInfoCompat.Builder(androidx.core.view.ContentInfoCompat);
+    ctor public ContentInfoCompat.Builder(android.content.ClipData, int);
+    method public androidx.core.view.ContentInfoCompat build();
+    method public androidx.core.view.ContentInfoCompat.Builder setClip(android.content.ClipData);
+    method public androidx.core.view.ContentInfoCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.view.ContentInfoCompat.Builder setFlags(int);
+    method public androidx.core.view.ContentInfoCompat.Builder setLinkUri(android.net.Uri?);
+    method public androidx.core.view.ContentInfoCompat.Builder setSource(int);
+  }
+
+  public final class DisplayCompat {
+    method public static androidx.core.view.DisplayCompat.ModeCompat getMode(android.content.Context, android.view.Display);
+    method public static androidx.core.view.DisplayCompat.ModeCompat![] getSupportedModes(android.content.Context, android.view.Display);
+  }
+
+  public static final class DisplayCompat.ModeCompat {
+    method public int getPhysicalHeight();
+    method public int getPhysicalWidth();
+    method @Deprecated public boolean isNative();
+    method @RequiresApi(android.os.Build.VERSION_CODES.M) public android.view.Display.Mode? toMode();
+  }
+
+  public final class DisplayCutoutCompat {
+    ctor public DisplayCutoutCompat(android.graphics.Rect?, java.util.List<android.graphics.Rect!>?);
+    ctor public DisplayCutoutCompat(androidx.core.graphics.Insets, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, androidx.core.graphics.Insets);
+    method public java.util.List<android.graphics.Rect!> getBoundingRects();
+    method public int getSafeInsetBottom();
+    method public int getSafeInsetLeft();
+    method public int getSafeInsetRight();
+    method public int getSafeInsetTop();
+    method public androidx.core.graphics.Insets getWaterfallInsets();
+  }
+
+  public final class DragAndDropPermissionsCompat {
+    method public void release();
+  }
+
+  public class DragStartHelper {
+    ctor public DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener);
+    method public void attach();
+    method public void detach();
+    method public void getTouchPosition(android.graphics.Point);
+    method public boolean onLongClick(android.view.View);
+    method public boolean onTouch(android.view.View, android.view.MotionEvent);
+  }
+
+  public static interface DragStartHelper.OnDragStartListener {
+    method public boolean onDragStart(android.view.View, androidx.core.view.DragStartHelper);
+  }
+
+  public final class GestureDetectorCompat {
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler?);
+    method public boolean isLongpressEnabled();
+    method public boolean onTouchEvent(android.view.MotionEvent);
+    method public void setIsLongpressEnabled(boolean);
+    method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener?);
+  }
+
+  public final class GravityCompat {
+    method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
+    method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static int getAbsoluteGravity(int, int);
+    field public static final int END = 8388613; // 0x800005
+    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
+    field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
+    field public static final int START = 8388611; // 0x800003
+  }
+
+  public final class InputDeviceCompat {
+    field public static final int SOURCE_ANY = -256; // 0xffffff00
+    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
+    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
+    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
+    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
+    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
+    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
+    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
+    field public static final int SOURCE_DPAD = 513; // 0x201
+    field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
+    field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
+    field public static final int SOURCE_KEYBOARD = 257; // 0x101
+    field public static final int SOURCE_MOUSE = 8194; // 0x2002
+    field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
+    field public static final int SOURCE_STYLUS = 16386; // 0x4002
+    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
+    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
+    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
+    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
+    field public static final int SOURCE_UNKNOWN = 0; // 0x0
+  }
+
+  public final class LayoutInflaterCompat {
+    method @Deprecated public static androidx.core.view.LayoutInflaterFactory! getFactory(android.view.LayoutInflater!);
+    method @Deprecated public static void setFactory(android.view.LayoutInflater, androidx.core.view.LayoutInflaterFactory);
+    method public static void setFactory2(android.view.LayoutInflater, android.view.LayoutInflater.Factory2);
+  }
+
+  @Deprecated public interface LayoutInflaterFactory {
+    method @Deprecated public android.view.View! onCreateView(android.view.View!, String!, android.content.Context!, android.util.AttributeSet!);
+  }
+
+  public final class MarginLayoutParamsCompat {
+    method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
+    method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
+    method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
+  }
+
+  public final class MenuCompat {
+    method public static void setGroupDividerEnabled(android.view.Menu, boolean);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+  }
+
+  public interface MenuHost {
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void invalidateMenu();
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public class MenuHostHelper {
+    ctor public MenuHostHelper(Runnable);
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public void onPrepareMenu(android.view.Menu);
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public final class MenuItemCompat {
+    method @Deprecated public static boolean collapseActionView(android.view.MenuItem!);
+    method @Deprecated public static boolean expandActionView(android.view.MenuItem!);
+    method public static androidx.core.view.ActionProvider? getActionProvider(android.view.MenuItem);
+    method @Deprecated public static android.view.View! getActionView(android.view.MenuItem!);
+    method public static int getAlphabeticModifiers(android.view.MenuItem);
+    method public static CharSequence? getContentDescription(android.view.MenuItem);
+    method public static android.content.res.ColorStateList? getIconTintList(android.view.MenuItem);
+    method public static android.graphics.PorterDuff.Mode? getIconTintMode(android.view.MenuItem);
+    method public static int getNumericModifiers(android.view.MenuItem);
+    method public static CharSequence? getTooltipText(android.view.MenuItem);
+    method @Deprecated public static boolean isActionViewExpanded(android.view.MenuItem!);
+    method public static android.view.MenuItem? setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider?);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, android.view.View!);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, int);
+    method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
+    method public static void setContentDescription(android.view.MenuItem, CharSequence?);
+    method public static void setIconTintList(android.view.MenuItem, android.content.res.ColorStateList?);
+    method public static void setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode?);
+    method public static void setNumericShortcut(android.view.MenuItem, char, int);
+    method @Deprecated public static android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem!, androidx.core.view.MenuItemCompat.OnActionExpandListener!);
+    method public static void setShortcut(android.view.MenuItem, char, char, int, int);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+    method public static void setTooltipText(android.view.MenuItem, CharSequence?);
+    field @Deprecated public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+    field @Deprecated public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+    field @Deprecated public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+    field @Deprecated public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+    field @Deprecated public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+  }
+
+  @Deprecated public static interface MenuItemCompat.OnActionExpandListener {
+    method @Deprecated public boolean onMenuItemActionCollapse(android.view.MenuItem!);
+    method @Deprecated public boolean onMenuItemActionExpand(android.view.MenuItem!);
+  }
+
+  public interface MenuProvider {
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public default void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public default void onPrepareMenu(android.view.Menu);
+  }
+
+  public final class MotionEventCompat {
+    method @Deprecated public static int findPointerIndex(android.view.MotionEvent!, int);
+    method @Deprecated public static int getActionIndex(android.view.MotionEvent!);
+    method @Deprecated public static int getActionMasked(android.view.MotionEvent!);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int, int);
+    method @Deprecated public static int getButtonState(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerCount(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerId(android.view.MotionEvent!, int);
+    method @Deprecated public static int getSource(android.view.MotionEvent!);
+    method @Deprecated public static float getX(android.view.MotionEvent!, int);
+    method @Deprecated public static float getY(android.view.MotionEvent!, int);
+    method public static boolean isFromSource(android.view.MotionEvent, int);
+    field @Deprecated public static final int ACTION_HOVER_ENTER = 9; // 0x9
+    field @Deprecated public static final int ACTION_HOVER_EXIT = 10; // 0xa
+    field @Deprecated public static final int ACTION_HOVER_MOVE = 7; // 0x7
+    field @Deprecated public static final int ACTION_MASK = 255; // 0xff
+    field @Deprecated public static final int ACTION_POINTER_DOWN = 5; // 0x5
+    field @Deprecated public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
+    field @Deprecated public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+    field @Deprecated public static final int ACTION_POINTER_UP = 6; // 0x6
+    field @Deprecated public static final int ACTION_SCROLL = 8; // 0x8
+    field @Deprecated public static final int AXIS_BRAKE = 23; // 0x17
+    field @Deprecated public static final int AXIS_DISTANCE = 24; // 0x18
+    field @Deprecated public static final int AXIS_GAS = 22; // 0x16
+    field @Deprecated public static final int AXIS_GENERIC_1 = 32; // 0x20
+    field @Deprecated public static final int AXIS_GENERIC_10 = 41; // 0x29
+    field @Deprecated public static final int AXIS_GENERIC_11 = 42; // 0x2a
+    field @Deprecated public static final int AXIS_GENERIC_12 = 43; // 0x2b
+    field @Deprecated public static final int AXIS_GENERIC_13 = 44; // 0x2c
+    field @Deprecated public static final int AXIS_GENERIC_14 = 45; // 0x2d
+    field @Deprecated public static final int AXIS_GENERIC_15 = 46; // 0x2e
+    field @Deprecated public static final int AXIS_GENERIC_16 = 47; // 0x2f
+    field @Deprecated public static final int AXIS_GENERIC_2 = 33; // 0x21
+    field @Deprecated public static final int AXIS_GENERIC_3 = 34; // 0x22
+    field @Deprecated public static final int AXIS_GENERIC_4 = 35; // 0x23
+    field @Deprecated public static final int AXIS_GENERIC_5 = 36; // 0x24
+    field @Deprecated public static final int AXIS_GENERIC_6 = 37; // 0x25
+    field @Deprecated public static final int AXIS_GENERIC_7 = 38; // 0x26
+    field @Deprecated public static final int AXIS_GENERIC_8 = 39; // 0x27
+    field @Deprecated public static final int AXIS_GENERIC_9 = 40; // 0x28
+    field @Deprecated public static final int AXIS_HAT_X = 15; // 0xf
+    field @Deprecated public static final int AXIS_HAT_Y = 16; // 0x10
+    field @Deprecated public static final int AXIS_HSCROLL = 10; // 0xa
+    field @Deprecated public static final int AXIS_LTRIGGER = 17; // 0x11
+    field @Deprecated public static final int AXIS_ORIENTATION = 8; // 0x8
+    field @Deprecated public static final int AXIS_PRESSURE = 2; // 0x2
+    field public static final int AXIS_RELATIVE_X = 27; // 0x1b
+    field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
+    field @Deprecated public static final int AXIS_RTRIGGER = 18; // 0x12
+    field @Deprecated public static final int AXIS_RUDDER = 20; // 0x14
+    field @Deprecated public static final int AXIS_RX = 12; // 0xc
+    field @Deprecated public static final int AXIS_RY = 13; // 0xd
+    field @Deprecated public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SCROLL = 26; // 0x1a
+    field @Deprecated public static final int AXIS_SIZE = 3; // 0x3
+    field @Deprecated public static final int AXIS_THROTTLE = 19; // 0x13
+    field @Deprecated public static final int AXIS_TILT = 25; // 0x19
+    field @Deprecated public static final int AXIS_TOOL_MAJOR = 6; // 0x6
+    field @Deprecated public static final int AXIS_TOOL_MINOR = 7; // 0x7
+    field @Deprecated public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
+    field @Deprecated public static final int AXIS_TOUCH_MINOR = 5; // 0x5
+    field @Deprecated public static final int AXIS_VSCROLL = 9; // 0x9
+    field @Deprecated public static final int AXIS_WHEEL = 21; // 0x15
+    field @Deprecated public static final int AXIS_X = 0; // 0x0
+    field @Deprecated public static final int AXIS_Y = 1; // 0x1
+    field @Deprecated public static final int AXIS_Z = 11; // 0xb
+    field @Deprecated public static final int BUTTON_PRIMARY = 1; // 0x1
+  }
+
+  public interface NestedScrollingChild {
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean isNestedScrollingEnabled();
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(int);
+    method public void stopNestedScroll();
+  }
+
+  public interface NestedScrollingChild2 extends androidx.core.view.NestedScrollingChild {
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+  }
+
+  public interface NestedScrollingChild3 extends androidx.core.view.NestedScrollingChild2 {
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+  }
+
+  public class NestedScrollingChildHelper {
+    ctor public NestedScrollingChildHelper(android.view.View);
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean isNestedScrollingEnabled();
+    method public void onDetachedFromWindow();
+    method public void onStopNestedScroll(android.view.View);
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll();
+    method public void stopNestedScroll(int);
+  }
+
+  public interface NestedScrollingParent {
+    method public int getNestedScrollAxes();
+    method public boolean onNestedFling(android.view.View, float, float, boolean);
+    method public boolean onNestedPreFling(android.view.View, float, float);
+    method public void onNestedPreScroll(android.view.View, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int);
+    method public void onStopNestedScroll(android.view.View);
+  }
+
+  public interface NestedScrollingParent2 extends androidx.core.view.NestedScrollingParent {
+    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View, int);
+  }
+
+  public interface NestedScrollingParent3 extends androidx.core.view.NestedScrollingParent2 {
+    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+  }
+
+  public class NestedScrollingParentHelper {
+    ctor public NestedScrollingParentHelper(android.view.ViewGroup);
+    method public int getNestedScrollAxes();
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View);
+    method public void onStopNestedScroll(android.view.View, int);
+  }
+
+  public interface OnApplyWindowInsetsListener {
+    method public androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+  }
+
+  public interface OnReceiveContentListener {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+  }
+
+  public interface OnReceiveContentViewBehavior {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
+  }
+
+  public final class OneShotPreDrawListener implements android.view.View.OnAttachStateChangeListener android.view.ViewTreeObserver.OnPreDrawListener {
+    method public static androidx.core.view.OneShotPreDrawListener add(android.view.View, Runnable);
+    method public boolean onPreDraw();
+    method public void onViewAttachedToWindow(android.view.View);
+    method public void onViewDetachedFromWindow(android.view.View);
+    method public void removeListener();
+  }
+
+  public final class PointerIconCompat {
+    method public static androidx.core.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
+    method public static androidx.core.view.PointerIconCompat getSystemIcon(android.content.Context, int);
+    method public static androidx.core.view.PointerIconCompat load(android.content.res.Resources, int);
+    field public static final int TYPE_ALIAS = 1010; // 0x3f2
+    field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
+    field public static final int TYPE_ARROW = 1000; // 0x3e8
+    field public static final int TYPE_CELL = 1006; // 0x3ee
+    field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
+    field public static final int TYPE_COPY = 1011; // 0x3f3
+    field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
+    field public static final int TYPE_DEFAULT = 1000; // 0x3e8
+    field public static final int TYPE_GRAB = 1020; // 0x3fc
+    field public static final int TYPE_GRABBING = 1021; // 0x3fd
+    field public static final int TYPE_HAND = 1002; // 0x3ea
+    field public static final int TYPE_HELP = 1003; // 0x3eb
+    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
+    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
+    field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_TEXT = 1008; // 0x3f0
+    field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
+    field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
+    field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
+    field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
+    field public static final int TYPE_WAIT = 1004; // 0x3ec
+    field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
+    field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
+  }
+
+  public final class ScaleGestureDetectorCompat {
+    method @Deprecated public static boolean isQuickScaleEnabled(Object!);
+    method public static boolean isQuickScaleEnabled(android.view.ScaleGestureDetector);
+    method @Deprecated public static void setQuickScaleEnabled(Object!, boolean);
+    method public static void setQuickScaleEnabled(android.view.ScaleGestureDetector, boolean);
+  }
+
+  public interface ScrollingView {
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+  }
+
+  public interface TintableBackgroundView {
+    method public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  @Deprecated public final class VelocityTrackerCompat {
+    method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
+    method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
+  }
+
+  public class ViewCompat {
+    ctor @Deprecated protected ViewCompat();
+    method public static int addAccessibilityAction(android.view.View, CharSequence, androidx.core.view.accessibility.AccessibilityViewCommand);
+    method public static void addKeyboardNavigationClusters(android.view.View, java.util.Collection<android.view.View!>, int);
+    method public static void addOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static androidx.core.view.ViewPropertyAnimatorCompat animate(android.view.View);
+    method @Deprecated public static boolean canScrollHorizontally(android.view.View!, int);
+    method @Deprecated public static boolean canScrollVertically(android.view.View!, int);
+    method public static void cancelDragAndDrop(android.view.View);
+    method @Deprecated public static int combineMeasuredStates(int, int);
+    method public static androidx.core.view.WindowInsetsCompat computeSystemWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat, android.graphics.Rect);
+    method public static androidx.core.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method public static void dispatchFinishTemporaryDetach(android.view.View);
+    method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
+    method public static boolean dispatchNestedPreFling(android.view.View, float, float);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?, int);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?);
+    method public static void dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int, int[]);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int);
+    method public static void dispatchStartTemporaryDetach(android.view.View);
+    method public static void enableAccessibleClickableSpanSupport(android.view.View);
+    method public static int generateViewId();
+    method public static androidx.core.view.AccessibilityDelegateCompat? getAccessibilityDelegate(android.view.View);
+    method public static int getAccessibilityLiveRegion(android.view.View);
+    method public static androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method @UiThread public static CharSequence? getAccessibilityPaneTitle(android.view.View);
+    method @Deprecated public static float getAlpha(android.view.View!);
+    method public static android.content.res.ColorStateList? getBackgroundTintList(android.view.View);
+    method public static android.graphics.PorterDuff.Mode? getBackgroundTintMode(android.view.View);
+    method public static android.graphics.Rect? getClipBounds(android.view.View);
+    method public static android.view.Display? getDisplay(android.view.View);
+    method public static float getElevation(android.view.View);
+    method public static boolean getFitsSystemWindows(android.view.View);
+    method public static int getImportantForAccessibility(android.view.View);
+    method public static int getImportantForAutofill(android.view.View);
+    method public static int getLabelFor(android.view.View);
+    method @Deprecated public static int getLayerType(android.view.View!);
+    method public static int getLayoutDirection(android.view.View);
+    method @Deprecated public static android.graphics.Matrix? getMatrix(android.view.View!);
+    method @Deprecated public static int getMeasuredHeightAndState(android.view.View!);
+    method @Deprecated public static int getMeasuredState(android.view.View!);
+    method @Deprecated public static int getMeasuredWidthAndState(android.view.View!);
+    method public static int getMinimumHeight(android.view.View);
+    method public static int getMinimumWidth(android.view.View);
+    method public static int getNextClusterForwardId(android.view.View);
+    method public static String![]? getOnReceiveContentMimeTypes(android.view.View);
+    method @Deprecated public static int getOverScrollMode(android.view.View!);
+    method @Px public static int getPaddingEnd(android.view.View);
+    method @Px public static int getPaddingStart(android.view.View);
+    method public static android.view.ViewParent? getParentForAccessibility(android.view.View);
+    method @Deprecated public static float getPivotX(android.view.View!);
+    method @Deprecated public static float getPivotY(android.view.View!);
+    method public static androidx.core.view.WindowInsetsCompat? getRootWindowInsets(android.view.View);
+    method @Deprecated public static float getRotation(android.view.View!);
+    method @Deprecated public static float getRotationX(android.view.View!);
+    method @Deprecated public static float getRotationY(android.view.View!);
+    method @Deprecated public static float getScaleX(android.view.View!);
+    method @Deprecated public static float getScaleY(android.view.View!);
+    method public static int getScrollIndicators(android.view.View);
+    method @UiThread public static CharSequence? getStateDescription(android.view.View);
+    method public static java.util.List<android.graphics.Rect!> getSystemGestureExclusionRects(android.view.View);
+    method public static String? getTransitionName(android.view.View);
+    method @Deprecated public static float getTranslationX(android.view.View!);
+    method @Deprecated public static float getTranslationY(android.view.View!);
+    method public static float getTranslationZ(android.view.View);
+    method @Deprecated public static androidx.core.view.WindowInsetsControllerCompat? getWindowInsetsController(android.view.View);
+    method @Deprecated public static int getWindowSystemUiVisibility(android.view.View);
+    method @Deprecated public static float getX(android.view.View!);
+    method @Deprecated public static float getY(android.view.View!);
+    method public static float getZ(android.view.View);
+    method public static boolean hasAccessibilityDelegate(android.view.View);
+    method public static boolean hasExplicitFocusable(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View, int);
+    method public static boolean hasOnClickListeners(android.view.View);
+    method public static boolean hasOverlappingRendering(android.view.View);
+    method public static boolean hasTransientState(android.view.View);
+    method @UiThread public static boolean isAccessibilityHeading(android.view.View);
+    method public static boolean isAttachedToWindow(android.view.View);
+    method public static boolean isFocusedByDefault(android.view.View);
+    method public static boolean isImportantForAccessibility(android.view.View);
+    method public static boolean isImportantForAutofill(android.view.View);
+    method public static boolean isInLayout(android.view.View);
+    method public static boolean isKeyboardNavigationCluster(android.view.View);
+    method public static boolean isLaidOut(android.view.View);
+    method public static boolean isLayoutDirectionResolved(android.view.View);
+    method public static boolean isNestedScrollingEnabled(android.view.View);
+    method @Deprecated public static boolean isOpaque(android.view.View!);
+    method public static boolean isPaddingRelative(android.view.View);
+    method @UiThread public static boolean isScreenReaderFocusable(android.view.View);
+    method @Deprecated public static void jumpDrawablesToCurrentState(android.view.View!);
+    method public static android.view.View? keyboardNavigationClusterSearch(android.view.View, android.view.View?, int);
+    method public static void offsetLeftAndRight(android.view.View, int);
+    method public static void offsetTopAndBottom(android.view.View, int);
+    method public static androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method @Deprecated public static void onInitializeAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+    method public static void postInvalidateOnAnimation(android.view.View);
+    method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
+    method public static void postOnAnimation(android.view.View, Runnable);
+    method public static void postOnAnimationDelayed(android.view.View, Runnable, long);
+    method public static void removeAccessibilityAction(android.view.View, int);
+    method public static void removeOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static void replaceAccessibilityAction(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat, CharSequence?, androidx.core.view.accessibility.AccessibilityViewCommand?);
+    method public static void requestApplyInsets(android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.View, @IdRes int);
+    method @Deprecated public static int resolveSizeAndState(int, int, int);
+    method public static boolean restoreDefaultFocus(android.view.View);
+    method public static void saveAttributeDataForStyleable(android.view.View, android.content.Context, int[], android.util.AttributeSet?, android.content.res.TypedArray, int, int);
+    method public static void setAccessibilityDelegate(android.view.View, androidx.core.view.AccessibilityDelegateCompat?);
+    method @UiThread public static void setAccessibilityHeading(android.view.View, boolean);
+    method public static void setAccessibilityLiveRegion(android.view.View, int);
+    method @UiThread public static void setAccessibilityPaneTitle(android.view.View, CharSequence?);
+    method @Deprecated public static void setActivated(android.view.View!, boolean);
+    method @Deprecated public static void setAlpha(android.view.View!, @FloatRange(from=0.0, to=1.0) float);
+    method public static void setAutofillHints(android.view.View, java.lang.String!...);
+    method public static void setBackground(android.view.View, android.graphics.drawable.Drawable?);
+    method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList?);
+    method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode?);
+    method @Deprecated public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup!, boolean);
+    method public static void setClipBounds(android.view.View, android.graphics.Rect?);
+    method public static void setElevation(android.view.View, float);
+    method @Deprecated public static void setFitsSystemWindows(android.view.View!, boolean);
+    method public static void setFocusedByDefault(android.view.View, boolean);
+    method public static void setHasTransientState(android.view.View, boolean);
+    method @UiThread public static void setImportantForAccessibility(android.view.View, int);
+    method public static void setImportantForAutofill(android.view.View, int);
+    method public static void setKeyboardNavigationCluster(android.view.View, boolean);
+    method public static void setLabelFor(android.view.View, @IdRes int);
+    method public static void setLayerPaint(android.view.View, android.graphics.Paint?);
+    method @Deprecated public static void setLayerType(android.view.View!, int, android.graphics.Paint!);
+    method public static void setLayoutDirection(android.view.View, int);
+    method public static void setNestedScrollingEnabled(android.view.View, boolean);
+    method public static void setNextClusterForwardId(android.view.View, int);
+    method public static void setOnApplyWindowInsetsListener(android.view.View, androidx.core.view.OnApplyWindowInsetsListener?);
+    method public static void setOnReceiveContentListener(android.view.View, String![]?, androidx.core.view.OnReceiveContentListener?);
+    method @Deprecated public static void setOverScrollMode(android.view.View!, int);
+    method public static void setPaddingRelative(android.view.View, @Px int, @Px int, @Px int, @Px int);
+    method @Deprecated public static void setPivotX(android.view.View!, float);
+    method @Deprecated public static void setPivotY(android.view.View!, float);
+    method public static void setPointerIcon(android.view.View, androidx.core.view.PointerIconCompat?);
+    method @Deprecated public static void setRotation(android.view.View!, float);
+    method @Deprecated public static void setRotationX(android.view.View!, float);
+    method @Deprecated public static void setRotationY(android.view.View!, float);
+    method @Deprecated public static void setSaveFromParentEnabled(android.view.View!, boolean);
+    method @Deprecated public static void setScaleX(android.view.View!, float);
+    method @Deprecated public static void setScaleY(android.view.View!, float);
+    method @UiThread public static void setScreenReaderFocusable(android.view.View, boolean);
+    method public static void setScrollIndicators(android.view.View, int);
+    method public static void setScrollIndicators(android.view.View, int, int);
+    method @UiThread public static void setStateDescription(android.view.View, CharSequence?);
+    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect!>);
+    method public static void setTooltipText(android.view.View, CharSequence?);
+    method public static void setTransitionName(android.view.View, String?);
+    method @Deprecated public static void setTranslationX(android.view.View!, float);
+    method @Deprecated public static void setTranslationY(android.view.View!, float);
+    method public static void setTranslationZ(android.view.View, float);
+    method public static void setWindowInsetsAnimationCallback(android.view.View, androidx.core.view.WindowInsetsAnimationCompat.Callback?);
+    method @Deprecated public static void setX(android.view.View!, float);
+    method @Deprecated public static void setY(android.view.View!, float);
+    method public static void setZ(android.view.View, float);
+    method public static boolean startDragAndDrop(android.view.View, android.content.ClipData?, android.view.View.DragShadowBuilder, Object?, int);
+    method public static boolean startNestedScroll(android.view.View, int);
+    method public static boolean startNestedScroll(android.view.View, int, int);
+    method public static void stopNestedScroll(android.view.View);
+    method public static void stopNestedScroll(android.view.View, int);
+    method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
+    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
+    field @Deprecated public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
+    field @Deprecated public static final int LAYER_TYPE_NONE = 0; // 0x0
+    field @Deprecated public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
+    field @Deprecated public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+    field @Deprecated public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+    field @Deprecated public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
+    field @Deprecated public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+    field @Deprecated public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
+    field @Deprecated public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
+    field @Deprecated public static final int OVER_SCROLL_NEVER = 2; // 0x2
+    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+    field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+    field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+    field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
+    field public static final int TYPE_NON_TOUCH = 1; // 0x1
+    field public static final int TYPE_TOUCH = 0; // 0x0
+  }
+
+  public static interface ViewCompat.OnUnhandledKeyEventListenerCompat {
+    method public boolean onUnhandledKeyEvent(android.view.View, android.view.KeyEvent);
+  }
+
+  public final class ViewConfigurationCompat {
+    method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method public static int getScaledHoverSlop(android.view.ViewConfiguration);
+    method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
+    method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
+    method public static boolean shouldShowMenuShortcutsWhenKeyboardPresent(android.view.ViewConfiguration, android.content.Context);
+  }
+
+  public final class ViewGroupCompat {
+    method public static int getLayoutMode(android.view.ViewGroup);
+    method public static int getNestedScrollAxes(android.view.ViewGroup);
+    method public static boolean isTransitionGroup(android.view.ViewGroup);
+    method @Deprecated public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void setLayoutMode(android.view.ViewGroup, int);
+    method @Deprecated public static void setMotionEventSplittingEnabled(android.view.ViewGroup!, boolean);
+    method public static void setTransitionGroup(android.view.ViewGroup, boolean);
+    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
+  }
+
+  public final class ViewParentCompat {
+    method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
+    method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View, int);
+    method @Deprecated public static boolean requestSendAccessibilityEvent(android.view.ViewParent!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+  }
+
+  public final class ViewPropertyAnimatorCompat {
+    method public androidx.core.view.ViewPropertyAnimatorCompat alpha(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat alphaBy(float);
+    method public void cancel();
+    method public long getDuration();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public long getStartDelay();
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotation(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setDuration(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setListener(androidx.core.view.ViewPropertyAnimatorListener?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setStartDelay(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener?);
+    method public void start();
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZ(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withEndAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withLayer();
+    method public androidx.core.view.ViewPropertyAnimatorCompat withStartAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat x(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat xBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat y(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat yBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat z(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat zBy(float);
+  }
+
+  public interface ViewPropertyAnimatorListener {
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public class ViewPropertyAnimatorListenerAdapter implements androidx.core.view.ViewPropertyAnimatorListener {
+    ctor public ViewPropertyAnimatorListenerAdapter();
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public interface ViewPropertyAnimatorUpdateListener {
+    method public void onAnimationUpdate(android.view.View);
+  }
+
+  public final class WindowCompat {
+    method public static androidx.core.view.WindowInsetsControllerCompat getInsetsController(android.view.Window, android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
+    method public static void setDecorFitsSystemWindows(android.view.Window, boolean);
+    field public static final int FEATURE_ACTION_BAR = 8; // 0x8
+    field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+  }
+
+  public final class WindowInsetsAnimationCompat {
+    ctor public WindowInsetsAnimationCompat(int, android.view.animation.Interpolator?, long);
+    method @FloatRange(from=0.0f, to=1.0f) public float getAlpha();
+    method public long getDurationMillis();
+    method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
+    method public float getInterpolatedFraction();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public int getTypeMask();
+    method public void setAlpha(@FloatRange(from=0.0f, to=1.0f) float);
+    method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public static final class WindowInsetsAnimationCompat.BoundsCompat {
+    ctor public WindowInsetsAnimationCompat.BoundsCompat(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public androidx.core.graphics.Insets getLowerBound();
+    method public androidx.core.graphics.Insets getUpperBound();
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat inset(androidx.core.graphics.Insets);
+    method @RequiresApi(30) public android.view.WindowInsetsAnimation.Bounds toBounds();
+    method @RequiresApi(30) public static androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat toBoundsCompat(android.view.WindowInsetsAnimation.Bounds);
+  }
+
+  public abstract static class WindowInsetsAnimationCompat.Callback {
+    ctor public WindowInsetsAnimationCompat.Callback(int);
+    method public final int getDispatchMode();
+    method public void onEnd(androidx.core.view.WindowInsetsAnimationCompat);
+    method public void onPrepare(androidx.core.view.WindowInsetsAnimationCompat);
+    method public abstract androidx.core.view.WindowInsetsCompat onProgress(androidx.core.view.WindowInsetsCompat, java.util.List<androidx.core.view.WindowInsetsAnimationCompat!>);
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat onStart(androidx.core.view.WindowInsetsAnimationCompat, androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat);
+    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
+    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
+  }
+
+  public interface WindowInsetsAnimationControlListenerCompat {
+    method public void onCancelled(androidx.core.view.WindowInsetsAnimationControllerCompat?);
+    method public void onFinished(androidx.core.view.WindowInsetsAnimationControllerCompat);
+    method public void onReady(androidx.core.view.WindowInsetsAnimationControllerCompat, int);
+  }
+
+  public final class WindowInsetsAnimationControllerCompat {
+    method public void finish(boolean);
+    method public float getCurrentAlpha();
+    method @FloatRange(from=0.0f, to=1.0f) public float getCurrentFraction();
+    method public androidx.core.graphics.Insets getCurrentInsets();
+    method public androidx.core.graphics.Insets getHiddenStateInsets();
+    method public androidx.core.graphics.Insets getShownStateInsets();
+    method public int getTypes();
+    method public boolean isCancelled();
+    method public boolean isFinished();
+    method public boolean isReady();
+    method public void setInsetsAndAlpha(androidx.core.graphics.Insets?, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public class WindowInsetsCompat {
+    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat?);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeDisplayCutout();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeStableInsets();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeSystemWindowInsets();
+    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getInsets(int);
+    method public androidx.core.graphics.Insets getInsetsIgnoringVisibility(int);
+    method @Deprecated public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
+    method @Deprecated public int getStableInsetBottom();
+    method @Deprecated public int getStableInsetLeft();
+    method @Deprecated public int getStableInsetRight();
+    method @Deprecated public int getStableInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getStableInsets();
+    method @Deprecated public androidx.core.graphics.Insets getSystemGestureInsets();
+    method @Deprecated public int getSystemWindowInsetBottom();
+    method @Deprecated public int getSystemWindowInsetLeft();
+    method @Deprecated public int getSystemWindowInsetRight();
+    method @Deprecated public int getSystemWindowInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getSystemWindowInsets();
+    method @Deprecated public androidx.core.graphics.Insets getTappableElementInsets();
+    method public boolean hasInsets();
+    method @Deprecated public boolean hasStableInsets();
+    method @Deprecated public boolean hasSystemWindowInsets();
+    method public androidx.core.view.WindowInsetsCompat inset(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat inset(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+    method public boolean isConsumed();
+    method public boolean isRound();
+    method public boolean isVisible(int);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
+    method @RequiresApi(20) public android.view.WindowInsets? toWindowInsets();
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets);
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets, android.view.View?);
+    field public static final androidx.core.view.WindowInsetsCompat CONSUMED;
+  }
+
+  public static final class WindowInsetsCompat.Builder {
+    ctor public WindowInsetsCompat.Builder();
+    ctor public WindowInsetsCompat.Builder(androidx.core.view.WindowInsetsCompat);
+    method public androidx.core.view.WindowInsetsCompat build();
+    method public androidx.core.view.WindowInsetsCompat.Builder setDisplayCutout(androidx.core.view.DisplayCutoutCompat?);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsets(int, androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsetsIgnoringVisibility(int, androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setMandatorySystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setStableInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemWindowInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setTappableElementInsets(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setVisible(int, boolean);
+  }
+
+  public static final class WindowInsetsCompat.Type {
+    method public static int captionBar();
+    method public static int displayCutout();
+    method public static int ime();
+    method public static int mandatorySystemGestures();
+    method public static int navigationBars();
+    method public static int statusBars();
+    method public static int systemBars();
+    method public static int systemGestures();
+    method public static int tappableElement();
+  }
+
+  public final class WindowInsetsControllerCompat {
+    ctor public WindowInsetsControllerCompat(android.view.Window, android.view.View);
+    method public void addOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void controlWindowInsetsAnimation(int, long, android.view.animation.Interpolator?, android.os.CancellationSignal?, androidx.core.view.WindowInsetsAnimationControlListenerCompat);
+    method public int getSystemBarsBehavior();
+    method public void hide(int);
+    method public boolean isAppearanceLightNavigationBars();
+    method public boolean isAppearanceLightStatusBars();
+    method public void removeOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void setAppearanceLightNavigationBars(boolean);
+    method public void setAppearanceLightStatusBars(boolean);
+    method public void setSystemBarsBehavior(int);
+    method public void show(int);
+    method @Deprecated @RequiresApi(30) public static androidx.core.view.WindowInsetsControllerCompat toWindowInsetsControllerCompat(android.view.WindowInsetsController);
+    field public static final int BEHAVIOR_DEFAULT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_SWIPE = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0; // 0x0
+    field public static final int BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2; // 0x2
+  }
+
+  public static interface WindowInsetsControllerCompat.OnControllableInsetsChangedListener {
+    method public void onControllableInsetsChanged(androidx.core.view.WindowInsetsControllerCompat, int);
+  }
+
+}
+
+package androidx.core.view.accessibility {
+
+  public final class AccessibilityClickableSpanCompat extends android.text.style.ClickableSpan {
+    method public void onClick(android.view.View);
+  }
+
+  public final class AccessibilityEventCompat {
+    method @Deprecated public static void appendRecord(android.view.accessibility.AccessibilityEvent!, androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! asRecord(android.view.accessibility.AccessibilityEvent!);
+    method public static int getAction(android.view.accessibility.AccessibilityEvent);
+    method public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
+    method public static int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! getRecord(android.view.accessibility.AccessibilityEvent!, int);
+    method @Deprecated public static int getRecordCount(android.view.accessibility.AccessibilityEvent!);
+    method public static void setAction(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
+    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 512; // 0x200
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 256; // 0x100
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 128; // 0x80
+    field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
+    field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
+    field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
+    field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
+    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
+    field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+    field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
+    field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
+    field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
+    field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
+    field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
+    field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
+    field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
+    field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
+    field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+    field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
+    field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
+    field @Deprecated public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
+  }
+
+  public final class AccessibilityManagerCompat {
+    method @Deprecated public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!, int);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+  }
+
+  @Deprecated public static interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    method @Deprecated public void onAccessibilityStateChanged(boolean);
+  }
+
+  @Deprecated public abstract static class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    ctor @Deprecated public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
+  }
+
+  public static interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
+    method public void onTouchExplorationStateChanged(boolean);
+  }
+
+  public class AccessibilityNodeInfoCompat {
+    ctor @Deprecated public AccessibilityNodeInfoCompat(Object!);
+    method public void addAction(int);
+    method public void addAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public void addChild(android.view.View!);
+    method public void addChild(android.view.View!, int);
+    method public boolean canOpenPopup();
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByText(String!);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByViewId(String!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! findFocus(int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!>! getActionList();
+    method @Deprecated public int getActions();
+    method public java.util.List<java.lang.String!> getAvailableExtraData();
+    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
+    method public void getBoundsInScreen(android.graphics.Rect!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
+    method public int getChildCount();
+    method public CharSequence! getClassName();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! getCollectionInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! getCollectionItemInfo();
+    method public CharSequence! getContentDescription();
+    method public int getDrawingOrder();
+    method public CharSequence! getError();
+    method public android.view.accessibility.AccessibilityNodeInfo.ExtraRenderingInfo? getExtraRenderingInfo();
+    method public android.os.Bundle! getExtras();
+    method public CharSequence? getHintText();
+    method @Deprecated public Object! getInfo();
+    method public int getInputType();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabelFor();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
+    method public int getLiveRegion();
+    method public int getMaxTextLength();
+    method public long getMinDurationBetweenContentChangesMillis();
+    method public int getMovementGranularities();
+    method public CharSequence! getPackageName();
+    method public CharSequence? getPaneTitle();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getParent();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! getRangeInfo();
+    method public CharSequence? getRoleDescription();
+    method public CharSequence? getStateDescription();
+    method public CharSequence! getText();
+    method public int getTextSelectionEnd();
+    method public int getTextSelectionStart();
+    method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
+    method public String? getUniqueId();
+    method public String! getViewIdResourceName();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
+    method public int getWindowId();
+    method public boolean hasRequestInitialAccessibilityFocus();
+    method public boolean isAccessibilityFocused();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isClickable();
+    method public boolean isContentInvalid();
+    method public boolean isContextClickable();
+    method public boolean isDismissable();
+    method public boolean isEditable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public boolean isFocused();
+    method public boolean isHeading();
+    method public boolean isImportantForAccessibility();
+    method public boolean isLongClickable();
+    method public boolean isMultiLine();
+    method public boolean isPassword();
+    method public boolean isScreenReaderFocusable();
+    method public boolean isScrollable();
+    method public boolean isSelected();
+    method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
+    method public boolean isTextSelectable();
+    method public boolean isVisibleToUser();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat!);
+    method public boolean performAction(int);
+    method public boolean performAction(int, android.os.Bundle!);
+    method @Deprecated public void recycle();
+    method public boolean refresh();
+    method public boolean removeAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public boolean removeChild(android.view.View!);
+    method public boolean removeChild(android.view.View!, int);
+    method public void setAccessibilityFocused(boolean);
+    method public void setAvailableExtraData(java.util.List<java.lang.String!>);
+    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
+    method public void setBoundsInScreen(android.graphics.Rect!);
+    method public void setCanOpenPopup(boolean);
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setClassName(CharSequence!);
+    method public void setClickable(boolean);
+    method public void setCollectionInfo(Object!);
+    method public void setCollectionItemInfo(Object!);
+    method public void setContentDescription(CharSequence!);
+    method public void setContentInvalid(boolean);
+    method public void setContextClickable(boolean);
+    method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
+    method public void setEditable(boolean);
+    method public void setEnabled(boolean);
+    method public void setError(CharSequence!);
+    method public void setFocusable(boolean);
+    method public void setFocused(boolean);
+    method public void setHeading(boolean);
+    method public void setHintText(CharSequence?);
+    method public void setImportantForAccessibility(boolean);
+    method public void setInputType(int);
+    method public void setLabelFor(android.view.View!);
+    method public void setLabelFor(android.view.View!, int);
+    method public void setLabeledBy(android.view.View!);
+    method public void setLabeledBy(android.view.View!, int);
+    method public void setLiveRegion(int);
+    method public void setLongClickable(boolean);
+    method public void setMaxTextLength(int);
+    method public void setMinDurationBetweenContentChangesMillis(long);
+    method public void setMovementGranularities(int);
+    method public void setMultiLine(boolean);
+    method public void setPackageName(CharSequence!);
+    method public void setPaneTitle(CharSequence?);
+    method public void setParent(android.view.View!);
+    method public void setParent(android.view.View!, int);
+    method public void setPassword(boolean);
+    method public void setRangeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat!);
+    method public void setRequestInitialAccessibilityFocus(boolean);
+    method public void setRoleDescription(CharSequence?);
+    method public void setScreenReaderFocusable(boolean);
+    method public void setScrollable(boolean);
+    method public void setSelected(boolean);
+    method public void setShowingHintText(boolean);
+    method public void setSource(android.view.View!);
+    method public void setSource(android.view.View!, int);
+    method public void setStateDescription(CharSequence?);
+    method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
+    method public void setTextSelectable(boolean);
+    method public void setTextSelection(int, int);
+    method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
+    method public void setTraversalAfter(android.view.View!);
+    method public void setTraversalAfter(android.view.View!, int);
+    method public void setTraversalBefore(android.view.View!);
+    method public void setTraversalBefore(android.view.View!, int);
+    method public void setUniqueId(String?);
+    method public void setViewIdResourceName(String!);
+    method public void setVisibleToUser(boolean);
+    method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
+    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+    field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+    field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+    field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+    field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_X = "ACTION_ARGUMENT_MOVE_WINDOW_X";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y = "ACTION_ARGUMENT_MOVE_WINDOW_Y";
+    field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
+    field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
+    field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+    field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
+    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
+    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
+    field public static final int ACTION_CLICK = 16; // 0x10
+    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
+    field public static final int ACTION_COPY = 16384; // 0x4000
+    field public static final int ACTION_CUT = 65536; // 0x10000
+    field public static final int ACTION_DISMISS = 1048576; // 0x100000
+    field public static final int ACTION_EXPAND = 262144; // 0x40000
+    field public static final int ACTION_FOCUS = 1; // 0x1
+    field public static final int ACTION_LONG_CLICK = 32; // 0x20
+    field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
+    field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+    field public static final int ACTION_PASTE = 32768; // 0x8000
+    field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
+    field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
+    field public static final int ACTION_SELECT = 4; // 0x4
+    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH";
+    field public static final int EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_MAX_LENGTH = 20000; // 0x4e20
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX";
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY";
+    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+    field public static final int FOCUS_INPUT = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
+    field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
+    field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
+    field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
+  }
+
+  public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
+    ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!);
+    method public int getId();
+    method public CharSequence! getLabel();
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COLLAPSE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CONTEXT_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_CANCEL;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_DROP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_START;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_IME_ENTER;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_LONG_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PRESS_AND_HOLD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SELECT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_PROGRESS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_TEXT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_ON_SCREEN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SHOW_TEXT_SUGGESTIONS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_TOOLTIP;
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public int getSelectionMode();
+    method public boolean isHierarchical();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean, int);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
+    method public int getColumnIndex();
+    method public int getColumnSpan();
+    method public int getRowIndex();
+    method public int getRowSpan();
+    method @Deprecated public boolean isHeading();
+    method public boolean isSelected();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean, boolean);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean);
+  }
+
+  public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
+    method public float getCurrent();
+    method public float getMax();
+    method public float getMin();
+    method public int getType();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! obtain(int, float, float, float);
+    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+    field public static final int RANGE_TYPE_INT = 0; // 0x0
+    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+  }
+
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region!,android.view.View!>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
+  public class AccessibilityNodeProviderCompat {
+    ctor public AccessibilityNodeProviderCompat();
+    ctor public AccessibilityNodeProviderCompat(Object?);
+    method public void addExtraDataToAccessibilityNodeInfo(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, String, android.os.Bundle?);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? createAccessibilityNodeInfo(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>? findAccessibilityNodeInfosByText(String, int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? findFocus(int);
+    method public Object? getProvider();
+    method public boolean performAction(int, int, android.os.Bundle?);
+    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
+  }
+
+  public class AccessibilityRecordCompat {
+    ctor @Deprecated public AccessibilityRecordCompat(Object!);
+    method @Deprecated public boolean equals(Object?);
+    method @Deprecated public int getAddedCount();
+    method @Deprecated public CharSequence! getBeforeText();
+    method @Deprecated public CharSequence! getClassName();
+    method @Deprecated public CharSequence! getContentDescription();
+    method @Deprecated public int getCurrentItemIndex();
+    method @Deprecated public int getFromIndex();
+    method @Deprecated public Object! getImpl();
+    method @Deprecated public int getItemCount();
+    method @Deprecated public int getMaxScrollX();
+    method public static int getMaxScrollX(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public int getMaxScrollY();
+    method public static int getMaxScrollY(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public android.os.Parcelable! getParcelableData();
+    method @Deprecated public int getRemovedCount();
+    method @Deprecated public int getScrollX();
+    method @Deprecated public int getScrollY();
+    method @Deprecated public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getSource();
+    method @Deprecated public java.util.List<java.lang.CharSequence!>! getText();
+    method @Deprecated public int getToIndex();
+    method @Deprecated public int getWindowId();
+    method @Deprecated public int hashCode();
+    method @Deprecated public boolean isChecked();
+    method @Deprecated public boolean isEnabled();
+    method @Deprecated public boolean isFullScreen();
+    method @Deprecated public boolean isPassword();
+    method @Deprecated public boolean isScrollable();
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain(androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain();
+    method @Deprecated public void recycle();
+    method @Deprecated public void setAddedCount(int);
+    method @Deprecated public void setBeforeText(CharSequence!);
+    method @Deprecated public void setChecked(boolean);
+    method @Deprecated public void setClassName(CharSequence!);
+    method @Deprecated public void setContentDescription(CharSequence!);
+    method @Deprecated public void setCurrentItemIndex(int);
+    method @Deprecated public void setEnabled(boolean);
+    method @Deprecated public void setFromIndex(int);
+    method @Deprecated public void setFullScreen(boolean);
+    method @Deprecated public void setItemCount(int);
+    method @Deprecated public void setMaxScrollX(int);
+    method public static void setMaxScrollX(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setMaxScrollY(int);
+    method public static void setMaxScrollY(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setParcelableData(android.os.Parcelable!);
+    method @Deprecated public void setPassword(boolean);
+    method @Deprecated public void setRemovedCount(int);
+    method @Deprecated public void setScrollX(int);
+    method @Deprecated public void setScrollY(int);
+    method @Deprecated public void setScrollable(boolean);
+    method @Deprecated public void setSource(android.view.View!);
+    method @Deprecated public void setSource(android.view.View!, int);
+    method public static void setSource(android.view.accessibility.AccessibilityRecord, android.view.View?, int);
+    method @Deprecated public void setToIndex(int);
+  }
+
+  public interface AccessibilityViewCommand {
+    method public boolean perform(android.view.View, androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments?);
+  }
+
+  public abstract static class AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.CommandArguments();
+  }
+
+  public static final class AccessibilityViewCommand.MoveAtGranularityArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveAtGranularityArguments();
+    method public boolean getExtendSelection();
+    method public int getGranularity();
+  }
+
+  public static final class AccessibilityViewCommand.MoveHtmlArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveHtmlArguments();
+    method public String? getHTMLElement();
+  }
+
+  public static final class AccessibilityViewCommand.MoveWindowArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveWindowArguments();
+    method public int getX();
+    method public int getY();
+  }
+
+  public static final class AccessibilityViewCommand.ScrollToPositionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.ScrollToPositionArguments();
+    method public int getColumn();
+    method public int getRow();
+  }
+
+  public static final class AccessibilityViewCommand.SetProgressArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetProgressArguments();
+    method public float getProgress();
+  }
+
+  public static final class AccessibilityViewCommand.SetSelectionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetSelectionArguments();
+    method public int getEnd();
+    method public int getStart();
+  }
+
+  public static final class AccessibilityViewCommand.SetTextArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetTextArguments();
+    method public CharSequence? getText();
+  }
+
+  public class AccessibilityWindowInfoCompat {
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
+    method public int getChildCount();
+    method public int getDisplayId();
+    method public int getId();
+    method public int getLayer();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getParent();
+    method public void getRegionInScreen(android.graphics.Region);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getRoot();
+    method public CharSequence? getTitle();
+    method public int getType();
+    method public boolean isAccessibilityFocused();
+    method public boolean isActive();
+    method public boolean isFocused();
+    method public boolean isInPictureInPictureMode();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat?);
+    method @Deprecated public void recycle();
+    method public android.view.accessibility.AccessibilityWindowInfo? unwrap();
+    field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
+    field public static final int TYPE_APPLICATION = 1; // 0x1
+    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+    field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
+    field public static final int TYPE_SYSTEM = 3; // 0x3
+  }
+
+}
+
+package androidx.core.view.animation {
+
+  public final class PathInterpolatorCompat {
+    method public static android.view.animation.Interpolator create(android.graphics.Path);
+    method public static android.view.animation.Interpolator create(float, float);
+    method public static android.view.animation.Interpolator create(float, float, float, float);
+  }
+
+}
+
+package androidx.core.view.inputmethod {
+
+  public final class EditorInfoCompat {
+    ctor @Deprecated public EditorInfoCompat();
+    method public static String![] getContentMimeTypes(android.view.inputmethod.EditorInfo);
+    method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
+    method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
+    method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
+    method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
+    field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
+    field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
+  }
+
+  public final class InputConnectionCompat {
+    ctor @Deprecated public InputConnectionCompat();
+    method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+    method @Deprecated public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+    method public static android.view.inputmethod.InputConnection createWrapper(android.view.View, android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo);
+    field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
+  }
+
+  public static interface InputConnectionCompat.OnCommitContentListener {
+    method public boolean onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+  }
+
+  public final class InputContentInfoCompat {
+    ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri?);
+    method public android.net.Uri getContentUri();
+    method public android.content.ClipDescription getDescription();
+    method public android.net.Uri? getLinkUri();
+    method public void releasePermission();
+    method public void requestPermission();
+    method public Object? unwrap();
+    method public static androidx.core.view.inputmethod.InputContentInfoCompat? wrap(Object?);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
+    ctor public AutoScrollHelper(android.view.View);
+    method public abstract boolean canTargetScrollHorizontally(int);
+    method public abstract boolean canTargetScrollVertically(int);
+    method public boolean isEnabled();
+    method public boolean isExclusive();
+    method public boolean onTouch(android.view.View!, android.view.MotionEvent!);
+    method public abstract void scrollTargetBy(int, int);
+    method public androidx.core.widget.AutoScrollHelper setActivationDelay(int);
+    method public androidx.core.widget.AutoScrollHelper setEdgeType(int);
+    method public androidx.core.widget.AutoScrollHelper! setEnabled(boolean);
+    method public androidx.core.widget.AutoScrollHelper! setExclusive(boolean);
+    method public androidx.core.widget.AutoScrollHelper setMaximumEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMaximumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMinimumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRampDownDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRampUpDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRelativeEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRelativeVelocity(float, float);
+    field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
+    field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
+    field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
+    field public static final float NO_MAX = 3.4028235E38f;
+    field public static final float NO_MIN = 0.0f;
+    field public static final float RELATIVE_UNSPECIFIED = 0.0f;
+  }
+
+  public final class CheckedTextViewCompat {
+    method public static android.graphics.drawable.Drawable? getCheckMarkDrawable(android.widget.CheckedTextView);
+    method public static android.content.res.ColorStateList? getCheckMarkTintList(android.widget.CheckedTextView);
+    method public static android.graphics.PorterDuff.Mode? getCheckMarkTintMode(android.widget.CheckedTextView);
+    method public static void setCheckMarkTintList(android.widget.CheckedTextView, android.content.res.ColorStateList?);
+    method public static void setCheckMarkTintMode(android.widget.CheckedTextView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class CompoundButtonCompat {
+    method public static android.graphics.drawable.Drawable? getButtonDrawable(android.widget.CompoundButton);
+    method public static android.content.res.ColorStateList? getButtonTintList(android.widget.CompoundButton);
+    method public static android.graphics.PorterDuff.Mode? getButtonTintMode(android.widget.CompoundButton);
+    method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList?);
+    method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode?);
+  }
+
+  public class ContentLoadingProgressBar extends android.widget.ProgressBar {
+    ctor public ContentLoadingProgressBar(android.content.Context);
+    ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet?);
+    method public void hide();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void show();
+  }
+
+  public final class EdgeEffectCompat {
+    ctor @Deprecated public EdgeEffectCompat(android.content.Context!);
+    method public static android.widget.EdgeEffect create(android.content.Context, android.util.AttributeSet?);
+    method @Deprecated public boolean draw(android.graphics.Canvas!);
+    method @Deprecated public void finish();
+    method public static float getDistance(android.widget.EdgeEffect);
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean onAbsorb(int);
+    method @Deprecated public boolean onPull(float);
+    method @Deprecated public boolean onPull(float, float);
+    method public static void onPull(android.widget.EdgeEffect, float, float);
+    method public static float onPullDistance(android.widget.EdgeEffect, float, float);
+    method @Deprecated public boolean onRelease();
+    method @Deprecated public void setSize(int, int);
+  }
+
+  public class ImageViewCompat {
+    method public static android.content.res.ColorStateList? getImageTintList(android.widget.ImageView);
+    method public static android.graphics.PorterDuff.Mode? getImageTintMode(android.widget.ImageView);
+    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList?);
+    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class ListPopupWindowCompat {
+    method @Deprecated public static android.view.View.OnTouchListener! createDragToOpenListener(Object!, android.view.View!);
+    method public static android.view.View.OnTouchListener? createDragToOpenListener(android.widget.ListPopupWindow, android.view.View);
+  }
+
+  public class ListViewAutoScrollHelper extends androidx.core.widget.AutoScrollHelper {
+    ctor public ListViewAutoScrollHelper(android.widget.ListView);
+    method public boolean canTargetScrollHorizontally(int);
+    method public boolean canTargetScrollVertically(int);
+    method public void scrollTargetBy(int, int);
+  }
+
+  public final class ListViewCompat {
+    method public static boolean canScrollList(android.widget.ListView, int);
+    method public static void scrollListBy(android.widget.ListView, int);
+  }
+
+  public class NestedScrollView extends android.widget.FrameLayout implements androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent3 androidx.core.view.ScrollingView {
+    ctor public NestedScrollView(android.content.Context);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean arrowScroll(int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollRange();
+    method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public boolean executeKeyEvent(android.view.KeyEvent);
+    method public void fling(int);
+    method public boolean fullScroll(int);
+    method public int getMaxScrollAmount();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean isFillViewport();
+    method public boolean isSmoothScrollingEnabled();
+    method public void onAttachedToWindow();
+    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View, int);
+    method public boolean pageScroll(int);
+    method public void setFillViewport(boolean);
+    method public void setOnScrollChangeListener(androidx.core.widget.NestedScrollView.OnScrollChangeListener?);
+    method public void setSmoothScrollingEnabled(boolean);
+    method public final void smoothScrollBy(int, int);
+    method public final void smoothScrollBy(int, int, int);
+    method public final void smoothScrollTo(int, int);
+    method public final void smoothScrollTo(int, int, int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+  }
+
+  public static interface NestedScrollView.OnScrollChangeListener {
+    method public void onScrollChange(androidx.core.widget.NestedScrollView, int, int, int, int);
+  }
+
+  public final class PopupMenuCompat {
+    method public static android.view.View.OnTouchListener? getDragToOpenListener(Object);
+  }
+
+  public final class PopupWindowCompat {
+    method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+    method public static int getWindowLayoutType(android.widget.PopupWindow);
+    method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
+    method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
+  }
+
+  @Deprecated public final class ScrollerCompat {
+    method @Deprecated public void abortAnimation();
+    method @Deprecated public boolean computeScrollOffset();
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!);
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!, android.view.animation.Interpolator!);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int, int, int);
+    method @Deprecated public float getCurrVelocity();
+    method @Deprecated public int getCurrX();
+    method @Deprecated public int getCurrY();
+    method @Deprecated public int getFinalX();
+    method @Deprecated public int getFinalY();
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean isOverScrolled();
+    method @Deprecated public void notifyHorizontalEdgeReached(int, int, int);
+    method @Deprecated public void notifyVerticalEdgeReached(int, int, int);
+    method @Deprecated public boolean springBack(int, int, int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int, int);
+  }
+
+  public final class TextViewCompat {
+    method public static int getAutoSizeMaxTextSize(android.widget.TextView);
+    method public static int getAutoSizeMinTextSize(android.widget.TextView);
+    method public static int getAutoSizeStepGranularity(android.widget.TextView);
+    method public static int[] getAutoSizeTextAvailableSizes(android.widget.TextView);
+    method public static int getAutoSizeTextType(android.widget.TextView);
+    method public static android.content.res.ColorStateList? getCompoundDrawableTintList(android.widget.TextView);
+    method public static android.graphics.PorterDuff.Mode? getCompoundDrawableTintMode(android.widget.TextView);
+    method public static android.graphics.drawable.Drawable![] getCompoundDrawablesRelative(android.widget.TextView);
+    method public static int getFirstBaselineToTopHeight(android.widget.TextView);
+    method public static int getLastBaselineToBottomHeight(android.widget.TextView);
+    method public static int getMaxLines(android.widget.TextView);
+    method public static int getMinLines(android.widget.TextView);
+    method public static androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParams(android.widget.TextView);
+    method public static void setAutoSizeTextTypeUniformWithConfiguration(android.widget.TextView, int, int, int, int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeUniformWithPresetSizes(android.widget.TextView, int[], int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeWithDefaults(android.widget.TextView, int);
+    method public static void setCompoundDrawableTintList(android.widget.TextView, android.content.res.ColorStateList?);
+    method public static void setCompoundDrawableTintMode(android.widget.TextView, android.graphics.PorterDuff.Mode?);
+    method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, @DrawableRes int, @DrawableRes int, @DrawableRes int, @DrawableRes int);
+    method public static void setCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback);
+    method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
+    method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
+    method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
+    field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0
+    field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
+  }
+
+  public interface TintableCompoundButton {
+    method public android.content.res.ColorStateList? getSupportButtonTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface TintableCompoundDrawablesView {
+    method public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+}
+
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 5033a53..f8aa350 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -3253,7 +3253,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
     method public int getLiveRegion();
     method public int getMaxTextLength();
-    method public int getMinMillisBetweenContentChanges();
+    method public long getMinDurationBetweenContentChangesMillis();
     method public int getMovementGranularities();
     method public CharSequence! getPackageName();
     method public CharSequence? getPaneTitle();
@@ -3339,7 +3339,7 @@
     method public void setLiveRegion(int);
     method public void setLongClickable(boolean);
     method public void setMaxTextLength(int);
-    method public void setMinMillisBetweenContentChanges(int);
+    method public void setMinDurationBetweenContentChangesMillis(long);
     method public void setMovementGranularities(int);
     method public void setMultiLine(boolean);
     method public void setPackageName(CharSequence!);
diff --git a/core/core/api/public_plus_experimental_1.10.0-beta01.txt b/core/core/api/public_plus_experimental_1.10.0-beta01.txt
new file mode 100644
index 0000000..a1e0e3c
--- /dev/null
+++ b/core/core/api/public_plus_experimental_1.10.0-beta01.txt
@@ -0,0 +1,3935 @@
+// Signature format: 4.0
+package androidx.core.accessibilityservice {
+
+  public final class AccessibilityServiceInfoCompat {
+    method public static String capabilityToString(int);
+    method public static String feedbackTypeToString(int);
+    method public static String? flagToString(int);
+    method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static String? loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
+    field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
+    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+    field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
+    field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
+    field public static final int FEEDBACK_BRAILLE = 32; // 0x20
+    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
+    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+  }
+
+}
+
+package androidx.core.app {
+
+  public class ActivityCompat extends androidx.core.content.ContextCompat {
+    ctor protected ActivityCompat();
+    method public static void finishAffinity(android.app.Activity);
+    method public static void finishAfterTransition(android.app.Activity);
+    method public static android.net.Uri? getReferrer(android.app.Activity);
+    method @Deprecated public static boolean invalidateOptionsMenu(android.app.Activity!);
+    method public static boolean isLaunchedFromBubble(android.app.Activity);
+    method public static void postponeEnterTransition(android.app.Activity);
+    method public static void recreate(android.app.Activity);
+    method public static androidx.core.view.DragAndDropPermissionsCompat? requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
+    method public static void requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+    method public static <T extends android.view.View> T requireViewById(android.app.Activity, @IdRes int);
+    method public static void setEnterSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setExitSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setLocusContext(android.app.Activity, androidx.core.content.LocusIdCompat?, android.os.Bundle?);
+    method public static void setPermissionCompatDelegate(androidx.core.app.ActivityCompat.PermissionCompatDelegate?);
+    method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, String);
+    method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle?);
+    method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public static void startPostponedEnterTransition(android.app.Activity);
+  }
+
+  public static interface ActivityCompat.OnRequestPermissionsResultCallback {
+    method public void onRequestPermissionsResult(int, String![], int[]);
+  }
+
+  public static interface ActivityCompat.PermissionCompatDelegate {
+    method public boolean onActivityResult(android.app.Activity, @IntRange(from=0) int, int, android.content.Intent?);
+    method public boolean requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+  }
+
+  public final class ActivityManagerCompat {
+    method public static boolean isLowRamDevice(android.app.ActivityManager);
+  }
+
+  public class ActivityOptionsCompat {
+    ctor protected ActivityOptionsCompat();
+    method public android.graphics.Rect? getLaunchBounds();
+    method public static androidx.core.app.ActivityOptionsCompat makeBasic();
+    method public static androidx.core.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, String);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, androidx.core.util.Pair<android.view.View!,java.lang.String!>!...);
+    method public static androidx.core.app.ActivityOptionsCompat makeTaskLaunchBehind();
+    method public static androidx.core.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
+    method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public androidx.core.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect?);
+    method public android.os.Bundle? toBundle();
+    method public void update(androidx.core.app.ActivityOptionsCompat);
+    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+    field public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
+  }
+
+  public final class AlarmManagerCompat {
+    method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
+    method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+  }
+
+  @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory {
+    ctor public AppComponentFactory();
+    method public final android.app.Activity instantiateActivity(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Activity instantiateActivityCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Application instantiateApplication(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Application instantiateApplicationCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.ContentProvider instantiateProvider(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.ContentProvider instantiateProviderCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.BroadcastReceiver instantiateReceiver(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.BroadcastReceiver instantiateReceiverCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Service instantiateService(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Service instantiateServiceCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+  }
+
+  public class AppLaunchChecker {
+    ctor @Deprecated public AppLaunchChecker();
+    method public static boolean hasStartedFromLauncher(android.content.Context);
+    method public static void onActivityCreate(android.app.Activity);
+  }
+
+  public final class AppOpsManagerCompat {
+    method public static int checkOrNoteProxyOp(android.content.Context, int, String, String);
+    method public static int noteOp(android.content.Context, String, int, String);
+    method public static int noteOpNoThrow(android.content.Context, String, int, String);
+    method public static int noteProxyOp(android.content.Context, String, String);
+    method public static int noteProxyOpNoThrow(android.content.Context, String, String);
+    method public static String? permissionToOp(String);
+    field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_DEFAULT = 3; // 0x3
+    field public static final int MODE_ERRORED = 2; // 0x2
+    field public static final int MODE_IGNORED = 1; // 0x1
+  }
+
+  public final class BundleCompat {
+    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  }
+
+  public class DialogCompat {
+    method public static android.view.View requireViewById(android.app.Dialog, int);
+  }
+
+  public class FrameMetricsAggregator {
+    ctor public FrameMetricsAggregator();
+    ctor public FrameMetricsAggregator(int);
+    method public void add(android.app.Activity);
+    method public android.util.SparseIntArray![]? getMetrics();
+    method public android.util.SparseIntArray![]? remove(android.app.Activity);
+    method public android.util.SparseIntArray![]? reset();
+    method public android.util.SparseIntArray![]? stop();
+    field public static final int ANIMATION_DURATION = 256; // 0x100
+    field public static final int ANIMATION_INDEX = 8; // 0x8
+    field public static final int COMMAND_DURATION = 32; // 0x20
+    field public static final int COMMAND_INDEX = 5; // 0x5
+    field public static final int DELAY_DURATION = 128; // 0x80
+    field public static final int DELAY_INDEX = 7; // 0x7
+    field public static final int DRAW_DURATION = 8; // 0x8
+    field public static final int DRAW_INDEX = 3; // 0x3
+    field public static final int EVERY_DURATION = 511; // 0x1ff
+    field public static final int INPUT_DURATION = 2; // 0x2
+    field public static final int INPUT_INDEX = 1; // 0x1
+    field public static final int LAYOUT_MEASURE_DURATION = 4; // 0x4
+    field public static final int LAYOUT_MEASURE_INDEX = 2; // 0x2
+    field public static final int SWAP_DURATION = 64; // 0x40
+    field public static final int SWAP_INDEX = 6; // 0x6
+    field public static final int SYNC_DURATION = 16; // 0x10
+    field public static final int SYNC_INDEX = 4; // 0x4
+    field public static final int TOTAL_DURATION = 1; // 0x1
+    field public static final int TOTAL_INDEX = 0; // 0x0
+  }
+
+  @Deprecated public abstract class JobIntentService extends android.app.Service {
+    ctor @Deprecated public JobIntentService();
+    method @Deprecated public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
+    method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
+    method @Deprecated public boolean isStopped();
+    method @Deprecated public android.os.IBinder! onBind(android.content.Intent);
+    method @Deprecated protected abstract void onHandleWork(android.content.Intent);
+    method @Deprecated public boolean onStopCurrentWork();
+    method @Deprecated public void setInterruptIfStopped(boolean);
+  }
+
+  public final class LocaleManagerCompat {
+    method @AnyThread public static androidx.core.os.LocaleListCompat getSystemLocales(android.content.Context);
+  }
+
+  public final class MultiWindowModeChangedInfo {
+    ctor public MultiWindowModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public MultiWindowModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInMultiWindowMode();
+  }
+
+  public final class NavUtils {
+    method public static android.content.Intent? getParentActivityIntent(android.app.Activity);
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static String? getParentActivityName(android.app.Activity);
+    method public static String? getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void navigateUpFromSameTask(android.app.Activity);
+    method public static void navigateUpTo(android.app.Activity, android.content.Intent);
+    method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
+    field public static final String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
+  }
+
+  public class NotificationChannelCompat {
+    method public boolean canBubble();
+    method public boolean canBypassDnd();
+    method public boolean canShowBadge();
+    method public android.media.AudioAttributes? getAudioAttributes();
+    method public String? getConversationId();
+    method public String? getDescription();
+    method public String? getGroup();
+    method public String getId();
+    method public int getImportance();
+    method public int getLightColor();
+    method public int getLockscreenVisibility();
+    method public CharSequence? getName();
+    method public String? getParentChannelId();
+    method public android.net.Uri? getSound();
+    method public long[]? getVibrationPattern();
+    method public boolean isImportantConversation();
+    method public boolean shouldShowLights();
+    method public boolean shouldVibrate();
+    method public androidx.core.app.NotificationChannelCompat.Builder toBuilder();
+    field public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
+  }
+
+  public static class NotificationChannelCompat.Builder {
+    ctor public NotificationChannelCompat.Builder(String, int);
+    method public androidx.core.app.NotificationChannelCompat build();
+    method public androidx.core.app.NotificationChannelCompat.Builder setConversationId(String, String);
+    method public androidx.core.app.NotificationChannelCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setImportance(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightColor(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightsEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setName(CharSequence?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setShowBadge(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setSound(android.net.Uri?, android.media.AudioAttributes?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationPattern(long[]?);
+  }
+
+  public class NotificationChannelGroupCompat {
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getChannels();
+    method public String? getDescription();
+    method public String getId();
+    method public CharSequence? getName();
+    method public boolean isBlocked();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder toBuilder();
+  }
+
+  public static class NotificationChannelGroupCompat.Builder {
+    ctor public NotificationChannelGroupCompat.Builder(String);
+    method public androidx.core.app.NotificationChannelGroupCompat build();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setName(CharSequence?);
+  }
+
+  public class NotificationCompat {
+    ctor @Deprecated public NotificationCompat();
+    method public static androidx.core.app.NotificationCompat.Action? getAction(android.app.Notification, int);
+    method public static int getActionCount(android.app.Notification);
+    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification);
+    method public static boolean getAutoCancel(android.app.Notification);
+    method public static int getBadgeIconType(android.app.Notification);
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata(android.app.Notification);
+    method public static String? getCategory(android.app.Notification);
+    method public static String? getChannelId(android.app.Notification);
+    method public static int getColor(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentInfo(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentText(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentTitle(android.app.Notification);
+    method public static android.os.Bundle? getExtras(android.app.Notification);
+    method public static String? getGroup(android.app.Notification);
+    method public static int getGroupAlertBehavior(android.app.Notification);
+    method @RequiresApi(21) public static java.util.List<androidx.core.app.NotificationCompat.Action!> getInvisibleActions(android.app.Notification);
+    method public static boolean getLocalOnly(android.app.Notification);
+    method public static androidx.core.content.LocusIdCompat? getLocusId(android.app.Notification);
+    method public static boolean getOngoing(android.app.Notification);
+    method public static boolean getOnlyAlertOnce(android.app.Notification);
+    method public static java.util.List<androidx.core.app.Person!> getPeople(android.app.Notification);
+    method public static android.app.Notification? getPublicVersion(android.app.Notification);
+    method public static CharSequence? getSettingsText(android.app.Notification);
+    method public static String? getShortcutId(android.app.Notification);
+    method @RequiresApi(19) public static boolean getShowWhen(android.app.Notification);
+    method public static String? getSortKey(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getSubText(android.app.Notification);
+    method public static long getTimeoutAfter(android.app.Notification);
+    method @RequiresApi(19) public static boolean getUsesChronometer(android.app.Notification);
+    method public static int getVisibility(android.app.Notification);
+    method public static boolean isGroupSummary(android.app.Notification);
+    field public static final int BADGE_ICON_LARGE = 2; // 0x2
+    field public static final int BADGE_ICON_NONE = 0; // 0x0
+    field public static final int BADGE_ICON_SMALL = 1; // 0x1
+    field public static final String CATEGORY_ALARM = "alarm";
+    field public static final String CATEGORY_CALL = "call";
+    field public static final String CATEGORY_EMAIL = "email";
+    field public static final String CATEGORY_ERROR = "err";
+    field public static final String CATEGORY_EVENT = "event";
+    field public static final String CATEGORY_LOCATION_SHARING = "location_sharing";
+    field public static final String CATEGORY_MESSAGE = "msg";
+    field public static final String CATEGORY_MISSED_CALL = "missed_call";
+    field public static final String CATEGORY_NAVIGATION = "navigation";
+    field public static final String CATEGORY_PROGRESS = "progress";
+    field public static final String CATEGORY_PROMO = "promo";
+    field public static final String CATEGORY_RECOMMENDATION = "recommendation";
+    field public static final String CATEGORY_REMINDER = "reminder";
+    field public static final String CATEGORY_SERVICE = "service";
+    field public static final String CATEGORY_SOCIAL = "social";
+    field public static final String CATEGORY_STATUS = "status";
+    field public static final String CATEGORY_STOPWATCH = "stopwatch";
+    field public static final String CATEGORY_SYSTEM = "sys";
+    field public static final String CATEGORY_TRANSPORT = "transport";
+    field public static final String CATEGORY_WORKOUT = "workout";
+    field @ColorInt public static final int COLOR_DEFAULT = 0; // 0x0
+    field public static final int DEFAULT_ALL = -1; // 0xffffffff
+    field public static final int DEFAULT_LIGHTS = 4; // 0x4
+    field public static final int DEFAULT_SOUND = 1; // 0x1
+    field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final String EXTRA_ANSWER_COLOR = "android.answerColor";
+    field public static final String EXTRA_ANSWER_INTENT = "android.answerIntent";
+    field public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
+    field public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+    field public static final String EXTRA_BIG_TEXT = "android.bigText";
+    field public static final String EXTRA_CALL_IS_VIDEO = "android.callIsVideo";
+    field public static final String EXTRA_CALL_PERSON = "android.callPerson";
+    field public static final String EXTRA_CALL_PERSON_COMPAT = "android.callPersonCompat";
+    field public static final String EXTRA_CALL_TYPE = "android.callType";
+    field public static final String EXTRA_CHANNEL_GROUP_ID = "android.intent.extra.CHANNEL_GROUP_ID";
+    field public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
+    field public static final String EXTRA_CHRONOMETER_COUNT_DOWN = "android.chronometerCountDown";
+    field public static final String EXTRA_COLORIZED = "android.colorized";
+    field public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final String EXTRA_COMPAT_TEMPLATE = "androidx.core.app.extra.COMPAT_TEMPLATE";
+    field public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
+    field public static final String EXTRA_DECLINE_COLOR = "android.declineColor";
+    field public static final String EXTRA_DECLINE_INTENT = "android.declineIntent";
+    field public static final String EXTRA_HANG_UP_INTENT = "android.hangUpIntent";
+    field public static final String EXTRA_HIDDEN_CONVERSATION_TITLE = "android.hiddenConversationTitle";
+    field public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic";
+    field public static final String EXTRA_INFO_TEXT = "android.infoText";
+    field public static final String EXTRA_IS_GROUP_CONVERSATION = "android.isGroupConversation";
+    field public static final String EXTRA_LARGE_ICON = "android.largeIcon";
+    field public static final String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+    field public static final String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final String EXTRA_MESSAGES = "android.messages";
+    field public static final String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
+    field public static final String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+    field public static final String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
+    field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
+    field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
+    field public static final String EXTRA_PICTURE = "android.picture";
+    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
+    field public static final String EXTRA_PICTURE_ICON = "android.pictureIcon";
+    field public static final String EXTRA_PROGRESS = "android.progress";
+    field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+    field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
+    field public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+    field public static final String EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED = "android.showBigPictureWhenCollapsed";
+    field public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+    field public static final String EXTRA_SHOW_WHEN = "android.showWhen";
+    field public static final String EXTRA_SMALL_ICON = "android.icon";
+    field public static final String EXTRA_SUB_TEXT = "android.subText";
+    field public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
+    field public static final String EXTRA_TEMPLATE = "android.template";
+    field public static final String EXTRA_TEXT = "android.text";
+    field public static final String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final String EXTRA_TITLE = "android.title";
+    field public static final String EXTRA_TITLE_BIG = "android.title.big";
+    field public static final String EXTRA_VERIFICATION_ICON = "android.verificationIcon";
+    field public static final String EXTRA_VERIFICATION_ICON_COMPAT = "android.verificationIconCompat";
+    field public static final String EXTRA_VERIFICATION_TEXT = "android.verificationText";
+    field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
+    field public static final int FLAG_BUBBLE = 4096; // 0x1000
+    field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
+    field @Deprecated public static final int FLAG_HIGH_PRIORITY = 128; // 0x80
+    field public static final int FLAG_INSISTENT = 4; // 0x4
+    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
+    field public static final int FLAG_NO_CLEAR = 32; // 0x20
+    field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
+    field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
+    field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int FOREGROUND_SERVICE_DEFAULT = 0; // 0x0
+    field public static final int FOREGROUND_SERVICE_DEFERRED = 2; // 0x2
+    field public static final int FOREGROUND_SERVICE_IMMEDIATE = 1; // 0x1
+    field public static final int GROUP_ALERT_ALL = 0; // 0x0
+    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
+    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
+    field public static final String GROUP_KEY_SILENT = "silent";
+    field public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
+    field public static final int PRIORITY_DEFAULT = 0; // 0x0
+    field public static final int PRIORITY_HIGH = 1; // 0x1
+    field public static final int PRIORITY_LOW = -1; // 0xffffffff
+    field public static final int PRIORITY_MAX = 2; // 0x2
+    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
+    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
+  }
+
+  public static class NotificationCompat.Action {
+    ctor public NotificationCompat.Action(int, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    method public android.app.PendingIntent? getActionIntent();
+    method public boolean getAllowGeneratedReplies();
+    method public androidx.core.app.RemoteInput![]? getDataOnlyRemoteInputs();
+    method public android.os.Bundle getExtras();
+    method @Deprecated public int getIcon();
+    method public androidx.core.graphics.drawable.IconCompat? getIconCompat();
+    method public androidx.core.app.RemoteInput![]? getRemoteInputs();
+    method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
+    method public boolean getShowsUserInterface();
+    method public CharSequence? getTitle();
+    method public boolean isAuthenticationRequired();
+    method public boolean isContextual();
+    field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
+    field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
+    field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
+    field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2
+    field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3
+    field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6
+    field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0
+    field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1
+    field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9
+    field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8
+    field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7
+    field public android.app.PendingIntent? actionIntent;
+    field @Deprecated public int icon;
+    field public CharSequence! title;
+  }
+
+  public static final class NotificationCompat.Action.Builder {
+    ctor public NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action.Builder(int, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action.Builder(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Action.Builder addRemoteInput(androidx.core.app.RemoteInput?);
+    method public androidx.core.app.NotificationCompat.Action build();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Extender);
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setAuthenticationRequired(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
+    method public androidx.core.app.NotificationCompat.Action.Builder setShowsUserInterface(boolean);
+  }
+
+  public static interface NotificationCompat.Action.Extender {
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_NONE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_REPLY, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_UNREAD, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_DELETE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_ARCHIVE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_UNMUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_UP, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_DOWN, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_CALL}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.Action.SemanticAction {
+  }
+
+  public static final class NotificationCompat.Action.WearableExtender implements androidx.core.app.NotificationCompat.Action.Extender {
+    ctor public NotificationCompat.Action.WearableExtender();
+    ctor public NotificationCompat.Action.WearableExtender(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+    method @Deprecated public CharSequence? getCancelLabel();
+    method @Deprecated public CharSequence? getConfirmLabel();
+    method public boolean getHintDisplayActionInline();
+    method public boolean getHintLaunchesActivity();
+    method @Deprecated public CharSequence? getInProgressLabel();
+    method public boolean isAvailableOffline();
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setCancelLabel(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setConfirmLabel(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setInProgressLabel(CharSequence?);
+  }
+
+  public static class NotificationCompat.BigPictureStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigPictureStyle();
+    ctor public NotificationCompat.BigPictureStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap?);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setBigContentTitle(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle setContentDescription(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setSummaryText(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle showBigPictureWhenCollapsed(boolean);
+  }
+
+  public static class NotificationCompat.BigTextStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigTextStyle();
+    ctor public NotificationCompat.BigTextStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle bigText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setSummaryText(CharSequence?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata {
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? fromPlatform(android.app.Notification.BubbleMetadata?);
+    method public boolean getAutoExpandBubble();
+    method public android.app.PendingIntent? getDeleteIntent();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getDesiredHeight();
+    method @DimenRes public int getDesiredHeightResId();
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public android.app.PendingIntent? getIntent();
+    method public String? getShortcutId();
+    method public boolean isNotificationSuppressed();
+    method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata.Builder {
+    ctor @Deprecated public NotificationCompat.BubbleMetadata.Builder();
+    ctor @RequiresApi(30) public NotificationCompat.BubbleMetadata.Builder(String);
+    ctor public NotificationCompat.BubbleMetadata.Builder(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata build();
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setAutoExpandBubble(boolean);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setSuppressNotification(boolean);
+  }
+
+  public static class NotificationCompat.Builder {
+    ctor @RequiresApi(19) public NotificationCompat.Builder(android.content.Context, android.app.Notification);
+    ctor public NotificationCompat.Builder(android.content.Context, String);
+    ctor @Deprecated public NotificationCompat.Builder(android.content.Context);
+    method public androidx.core.app.NotificationCompat.Builder addAction(int, CharSequence?, android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder addAction(androidx.core.app.NotificationCompat.Action?);
+    method public androidx.core.app.NotificationCompat.Builder addExtras(android.os.Bundle?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(int, CharSequence?, android.app.PendingIntent?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(androidx.core.app.NotificationCompat.Action?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder addPerson(String?);
+    method public androidx.core.app.NotificationCompat.Builder addPerson(androidx.core.app.Person?);
+    method public android.app.Notification build();
+    method public androidx.core.app.NotificationCompat.Builder clearActions();
+    method public androidx.core.app.NotificationCompat.Builder clearInvisibleActions();
+    method public androidx.core.app.NotificationCompat.Builder clearPeople();
+    method public android.widget.RemoteViews? createBigContentView();
+    method public android.widget.RemoteViews? createContentView();
+    method public android.widget.RemoteViews? createHeadsUpContentView();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Extender);
+    method public android.os.Bundle getExtras();
+    method @Deprecated public android.app.Notification getNotification();
+    method protected static CharSequence? limitCharSequenceLength(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setAutoCancel(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setBadgeIconType(int);
+    method public androidx.core.app.NotificationCompat.Builder setBubbleMetadata(androidx.core.app.NotificationCompat.BubbleMetadata?);
+    method public androidx.core.app.NotificationCompat.Builder setCategory(String?);
+    method public androidx.core.app.NotificationCompat.Builder setChannelId(String);
+    method @RequiresApi(24) public androidx.core.app.NotificationCompat.Builder setChronometerCountDown(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.Builder setColorized(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setContent(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setContentInfo(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setContentText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setDefaults(int);
+    method public androidx.core.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Builder setForegroundServiceBehavior(int);
+    method public androidx.core.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent?, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationCompat.Builder setGroupAlertBehavior(int);
+    method public androidx.core.app.NotificationCompat.Builder setGroupSummary(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.Builder setLights(@ColorInt int, int, int);
+    method public androidx.core.app.NotificationCompat.Builder setLocalOnly(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setNotificationSilent();
+    method public androidx.core.app.NotificationCompat.Builder setNumber(int);
+    method public androidx.core.app.NotificationCompat.Builder setOngoing(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPriority(int);
+    method public androidx.core.app.NotificationCompat.Builder setProgress(int, int, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPublicVersion(android.app.Notification?);
+    method public androidx.core.app.NotificationCompat.Builder setRemoteInputHistory(CharSequence![]?);
+    method public androidx.core.app.NotificationCompat.Builder setSettingsText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutId(String?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutInfo(androidx.core.content.pm.ShortcutInfoCompat?);
+    method public androidx.core.app.NotificationCompat.Builder setShowWhen(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setSilent(boolean);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.Builder setSmallIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int, int);
+    method public androidx.core.app.NotificationCompat.Builder setSortKey(String?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?, int);
+    method public androidx.core.app.NotificationCompat.Builder setStyle(androidx.core.app.NotificationCompat.Style?);
+    method public androidx.core.app.NotificationCompat.Builder setSubText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?, android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setTimeoutAfter(long);
+    method public androidx.core.app.NotificationCompat.Builder setUsesChronometer(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setVibrate(long[]?);
+    method public androidx.core.app.NotificationCompat.Builder setVisibility(int);
+    method public androidx.core.app.NotificationCompat.Builder setWhen(long);
+    field @Deprecated public java.util.ArrayList<java.lang.String!>! mPeople;
+  }
+
+  public static class NotificationCompat.CallStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.CallStyle();
+    ctor public NotificationCompat.CallStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public static androidx.core.app.NotificationCompat.CallStyle forIncomingCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forOngoingCall(androidx.core.app.Person, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forScreeningCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method public androidx.core.app.NotificationCompat.CallStyle setAnswerButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setDeclineButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setIsVideo(boolean);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationText(CharSequence?);
+    field public static final int CALL_TYPE_INCOMING = 1; // 0x1
+    field public static final int CALL_TYPE_ONGOING = 2; // 0x2
+    field public static final int CALL_TYPE_SCREENING = 3; // 0x3
+    field public static final int CALL_TYPE_UNKNOWN = 0; // 0x0
+  }
+
+  public static final class NotificationCompat.CarExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.CarExtender();
+    ctor public NotificationCompat.CarExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method @ColorInt public int getColor();
+    method public android.graphics.Bitmap? getLargeIcon();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation? getUnreadConversation();
+    method public androidx.core.app.NotificationCompat.CarExtender setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation?);
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation {
+    method @Deprecated public long getLatestTimestamp();
+    method @Deprecated public String![]? getMessages();
+    method @Deprecated public String? getParticipant();
+    method @Deprecated public String![]? getParticipants();
+    method @Deprecated public android.app.PendingIntent? getReadPendingIntent();
+    method @Deprecated public androidx.core.app.RemoteInput? getRemoteInput();
+    method @Deprecated public android.app.PendingIntent? getReplyPendingIntent();
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+    ctor @Deprecated public NotificationCompat.CarExtender.UnreadConversation.Builder(String);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation build();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent?, androidx.core.app.RemoteInput?);
+  }
+
+  public static class NotificationCompat.DecoratedCustomViewStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.DecoratedCustomViewStyle();
+  }
+
+  public static interface NotificationCompat.Extender {
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+  }
+
+  public static class NotificationCompat.InboxStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.InboxStyle();
+    ctor public NotificationCompat.InboxStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.InboxStyle addLine(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setSummaryText(CharSequence?);
+  }
+
+  public static class NotificationCompat.MessagingStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor @Deprecated public NotificationCompat.MessagingStyle(CharSequence);
+    ctor public NotificationCompat.MessagingStyle(androidx.core.app.Person);
+    method public void addCompatExtras(android.os.Bundle);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addHistoricMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method @Deprecated public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, CharSequence?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, androidx.core.app.Person?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method public static androidx.core.app.NotificationCompat.MessagingStyle? extractMessagingStyleFromNotification(android.app.Notification);
+    method public CharSequence? getConversationTitle();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getHistoricMessages();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getMessages();
+    method public androidx.core.app.Person getUser();
+    method @Deprecated public CharSequence? getUserDisplayName();
+    method public boolean isGroupConversation();
+    method public androidx.core.app.NotificationCompat.MessagingStyle setConversationTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle setGroupConversation(boolean);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class NotificationCompat.MessagingStyle.Message {
+    ctor public NotificationCompat.MessagingStyle.Message(CharSequence?, long, androidx.core.app.Person?);
+    ctor @Deprecated public NotificationCompat.MessagingStyle.Message(CharSequence?, long, CharSequence?);
+    method public String? getDataMimeType();
+    method public android.net.Uri? getDataUri();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.Person? getPerson();
+    method @Deprecated public CharSequence? getSender();
+    method public CharSequence? getText();
+    method public long getTimestamp();
+    method public androidx.core.app.NotificationCompat.MessagingStyle.Message setData(String?, android.net.Uri?);
+  }
+
+  public abstract static class NotificationCompat.Style {
+    ctor public NotificationCompat.Style();
+    method public android.app.Notification? build();
+    method public void setBuilder(androidx.core.app.NotificationCompat.Builder?);
+  }
+
+  public static final class NotificationCompat.WearableExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.WearableExtender();
+    ctor public NotificationCompat.WearableExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.WearableExtender addAction(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.WearableExtender addActions(java.util.List<androidx.core.app.NotificationCompat.Action!>);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification!>);
+    method public androidx.core.app.NotificationCompat.WearableExtender clearActions();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender clearPages();
+    method public androidx.core.app.NotificationCompat.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method public java.util.List<androidx.core.app.NotificationCompat.Action!> getActions();
+    method @Deprecated public android.graphics.Bitmap? getBackground();
+    method public String? getBridgeTag();
+    method public int getContentAction();
+    method @Deprecated public int getContentIcon();
+    method @Deprecated public int getContentIconGravity();
+    method public boolean getContentIntentAvailableOffline();
+    method @Deprecated public int getCustomContentHeight();
+    method @Deprecated public int getCustomSizePreset();
+    method public String? getDismissalId();
+    method @Deprecated public android.app.PendingIntent? getDisplayIntent();
+    method @Deprecated public int getGravity();
+    method @Deprecated public boolean getHintAmbientBigPicture();
+    method @Deprecated public boolean getHintAvoidBackgroundClipping();
+    method public boolean getHintContentIntentLaunchesActivity();
+    method @Deprecated public boolean getHintHideIcon();
+    method @Deprecated public int getHintScreenTimeout();
+    method @Deprecated public boolean getHintShowBackgroundOnly();
+    method @Deprecated public java.util.List<android.app.Notification!> getPages();
+    method public boolean getStartScrollBottom();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setBridgeTag(String?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentAction(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIcon(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIconGravity(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setDismissalId(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setGravity(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
+    field @Deprecated public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+    field @Deprecated public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
+    field @Deprecated public static final int SIZE_DEFAULT = 0; // 0x0
+    field @Deprecated public static final int SIZE_FULL_SCREEN = 5; // 0x5
+    field @Deprecated public static final int SIZE_LARGE = 4; // 0x4
+    field @Deprecated public static final int SIZE_MEDIUM = 3; // 0x3
+    field @Deprecated public static final int SIZE_SMALL = 2; // 0x2
+    field @Deprecated public static final int SIZE_XSMALL = 1; // 0x1
+    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+  }
+
+  public final class NotificationCompatExtras {
+    field public static final String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
+    field public static final String EXTRA_GROUP_KEY = "android.support.groupKey";
+    field public static final String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
+    field public static final String EXTRA_LOCAL_ONLY = "android.support.localOnly";
+    field public static final String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+    field public static final String EXTRA_SORT_KEY = "android.support.sortKey";
+  }
+
+  public abstract class NotificationCompatSideChannelService extends android.app.Service {
+    ctor public NotificationCompatSideChannelService();
+    method public abstract void cancel(String!, int, String!);
+    method public abstract void cancelAll(String!);
+    method public abstract void notify(String!, int, String!, android.app.Notification!);
+    method public android.os.IBinder! onBind(android.content.Intent!);
+  }
+
+  public final class NotificationManagerCompat {
+    method public boolean areNotificationsEnabled();
+    method public void cancel(int);
+    method public void cancel(String?, int);
+    method public void cancelAll();
+    method public void createNotificationChannel(android.app.NotificationChannel);
+    method public void createNotificationChannel(androidx.core.app.NotificationChannelCompat);
+    method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
+    method public void createNotificationChannelGroup(androidx.core.app.NotificationChannelGroupCompat);
+    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
+    method public void createNotificationChannelGroupsCompat(java.util.List<androidx.core.app.NotificationChannelGroupCompat!>);
+    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
+    method public void createNotificationChannelsCompat(java.util.List<androidx.core.app.NotificationChannelCompat!>);
+    method public void deleteNotificationChannel(String);
+    method public void deleteNotificationChannelGroup(String);
+    method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
+    method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
+    method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
+    method public int getImportance();
+    method public android.app.NotificationChannel? getNotificationChannel(String);
+    method public android.app.NotificationChannel? getNotificationChannel(String, String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String, String);
+    method public android.app.NotificationChannelGroup? getNotificationChannelGroup(String);
+    method public androidx.core.app.NotificationChannelGroupCompat? getNotificationChannelGroupCompat(String);
+    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
+    method public java.util.List<androidx.core.app.NotificationChannelGroupCompat!> getNotificationChannelGroupsCompat();
+    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getNotificationChannelsCompat();
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(int, android.app.Notification);
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(String?, int, android.app.Notification);
+    field public static final String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
+    field public static final String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
+    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
+    field public static final int IMPORTANCE_HIGH = 4; // 0x4
+    field public static final int IMPORTANCE_LOW = 2; // 0x2
+    field public static final int IMPORTANCE_MAX = 5; // 0x5
+    field public static final int IMPORTANCE_MIN = 1; // 0x1
+    field public static final int IMPORTANCE_NONE = 0; // 0x0
+    field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+  }
+
+  public interface OnMultiWindowModeChangedProvider {
+    method public void addOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+    method public void removeOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+  }
+
+  public interface OnNewIntentProvider {
+    method public void addOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+    method public void removeOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+  }
+
+  public interface OnPictureInPictureModeChangedProvider {
+    method public void addOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+    method public void removeOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+  }
+
+  public final class PendingIntentCompat {
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getBroadcast(android.content.Context, int, android.content.Intent, int, boolean);
+    method @RequiresApi(26) public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int, boolean);
+  }
+
+  public class Person {
+    method public static androidx.core.app.Person fromBundle(android.os.Bundle);
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public String? getKey();
+    method public CharSequence? getName();
+    method public String? getUri();
+    method public boolean isBot();
+    method public boolean isImportant();
+    method public androidx.core.app.Person.Builder toBuilder();
+    method public android.os.Bundle toBundle();
+  }
+
+  public static class Person.Builder {
+    ctor public Person.Builder();
+    method public androidx.core.app.Person build();
+    method public androidx.core.app.Person.Builder setBot(boolean);
+    method public androidx.core.app.Person.Builder setIcon(androidx.core.graphics.drawable.IconCompat?);
+    method public androidx.core.app.Person.Builder setImportant(boolean);
+    method public androidx.core.app.Person.Builder setKey(String?);
+    method public androidx.core.app.Person.Builder setName(CharSequence?);
+    method public androidx.core.app.Person.Builder setUri(String?);
+  }
+
+  public final class PictureInPictureModeChangedInfo {
+    ctor public PictureInPictureModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public PictureInPictureModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInPictureInPictureMode();
+  }
+
+  public final class RemoteActionCompat implements androidx.versionedparcelable.VersionedParcelable {
+    ctor public RemoteActionCompat(androidx.core.graphics.drawable.IconCompat, CharSequence, CharSequence, android.app.PendingIntent);
+    ctor public RemoteActionCompat(androidx.core.app.RemoteActionCompat);
+    method @RequiresApi(26) public static androidx.core.app.RemoteActionCompat createFromRemoteAction(android.app.RemoteAction);
+    method public android.app.PendingIntent getActionIntent();
+    method public CharSequence getContentDescription();
+    method public androidx.core.graphics.drawable.IconCompat getIcon();
+    method public CharSequence getTitle();
+    method public boolean isEnabled();
+    method public void setEnabled(boolean);
+    method public void setShouldShowIcon(boolean);
+    method public boolean shouldShowIcon();
+    method @RequiresApi(26) public android.app.RemoteAction toRemoteAction();
+  }
+
+  public final class RemoteInput {
+    method public static void addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String!,android.net.Uri!>);
+    method public static void addResultsToIntent(androidx.core.app.RemoteInput![], android.content.Intent, android.os.Bundle);
+    method public boolean getAllowFreeFormInput();
+    method public java.util.Set<java.lang.String!>? getAllowedDataTypes();
+    method public CharSequence![]? getChoices();
+    method public static java.util.Map<java.lang.String!,android.net.Uri!>? getDataResultsFromIntent(android.content.Intent, String);
+    method public int getEditChoicesBeforeSending();
+    method public android.os.Bundle getExtras();
+    method public CharSequence? getLabel();
+    method public String getResultKey();
+    method public static android.os.Bundle? getResultsFromIntent(android.content.Intent);
+    method public static int getResultsSource(android.content.Intent);
+    method public boolean isDataOnly();
+    method public static void setResultsSource(android.content.Intent, int);
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
+    field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+    field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+    field public static final int SOURCE_CHOICE = 1; // 0x1
+    field public static final int SOURCE_FREE_FORM_INPUT = 0; // 0x0
+  }
+
+  public static final class RemoteInput.Builder {
+    ctor public RemoteInput.Builder(String);
+    method public androidx.core.app.RemoteInput.Builder addExtras(android.os.Bundle);
+    method public androidx.core.app.RemoteInput build();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
+    method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+    method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence![]?);
+    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(int);
+    method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
+  }
+
+  public final class ServiceCompat {
+    method public static void stopForeground(android.app.Service, int);
+    field public static final int START_STICKY = 1; // 0x1
+    field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+    field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
+  }
+
+  public final class ShareCompat {
+    method @Deprecated public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
+    method @Deprecated public static void configureMenuItem(android.view.Menu, @IdRes int, androidx.core.app.ShareCompat.IntentBuilder);
+    method public static android.content.ComponentName? getCallingActivity(android.app.Activity);
+    method public static String? getCallingPackage(android.app.Activity);
+    field public static final String EXTRA_CALLING_ACTIVITY = "androidx.core.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_ACTIVITY_INTEROP = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_PACKAGE = "androidx.core.app.EXTRA_CALLING_PACKAGE";
+    field public static final String EXTRA_CALLING_PACKAGE_INTEROP = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
+  }
+
+  public static class ShareCompat.IntentBuilder {
+    ctor public ShareCompat.IntentBuilder(android.content.Context);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
+    method public android.content.Intent createChooserIntent();
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentBuilder from(android.app.Activity);
+    method public android.content.Intent getIntent();
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(@StringRes int);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailBcc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailCc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailTo(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setHtmlText(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setStream(android.net.Uri?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setSubject(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setText(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setType(String?);
+    method public void startChooser();
+  }
+
+  public static class ShareCompat.IntentReader {
+    ctor public ShareCompat.IntentReader(android.app.Activity);
+    ctor public ShareCompat.IntentReader(android.content.Context, android.content.Intent);
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentReader from(android.app.Activity);
+    method public android.content.ComponentName? getCallingActivity();
+    method public android.graphics.drawable.Drawable? getCallingActivityIcon();
+    method public android.graphics.drawable.Drawable? getCallingApplicationIcon();
+    method public CharSequence? getCallingApplicationLabel();
+    method public String? getCallingPackage();
+    method public String![]? getEmailBcc();
+    method public String![]? getEmailCc();
+    method public String![]? getEmailTo();
+    method public String? getHtmlText();
+    method public android.net.Uri? getStream();
+    method public android.net.Uri? getStream(int);
+    method public int getStreamCount();
+    method public String? getSubject();
+    method public CharSequence? getText();
+    method public String? getType();
+    method public boolean isMultipleShare();
+    method public boolean isShareIntent();
+    method public boolean isSingleShare();
+  }
+
+  public abstract class SharedElementCallback {
+    ctor public SharedElementCallback();
+    method public android.os.Parcelable! onCaptureSharedElementSnapshot(android.view.View!, android.graphics.Matrix!, android.graphics.RectF!);
+    method public android.view.View! onCreateSnapshotView(android.content.Context!, android.os.Parcelable!);
+    method public void onMapSharedElements(java.util.List<java.lang.String!>!, java.util.Map<java.lang.String!,android.view.View!>!);
+    method public void onRejectSharedElements(java.util.List<android.view.View!>!);
+    method public void onSharedElementEnd(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementStart(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementsArrived(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener!);
+  }
+
+  public static interface SharedElementCallback.OnSharedElementsReadyListener {
+    method public void onSharedElementsReady();
+  }
+
+  public final class TaskStackBuilder implements java.lang.Iterable<android.content.Intent> {
+    method public androidx.core.app.TaskStackBuilder addNextIntent(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.app.Activity);
+    method public androidx.core.app.TaskStackBuilder addParentStack(Class<?>);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.content.ComponentName);
+    method public static androidx.core.app.TaskStackBuilder create(android.content.Context);
+    method public android.content.Intent? editIntentAt(int);
+    method @Deprecated public static androidx.core.app.TaskStackBuilder! from(android.content.Context!);
+    method @Deprecated public android.content.Intent! getIntent(int);
+    method public int getIntentCount();
+    method public android.content.Intent![] getIntents();
+    method public android.app.PendingIntent? getPendingIntent(int, int);
+    method public android.app.PendingIntent? getPendingIntent(int, int, android.os.Bundle?);
+    method @Deprecated public java.util.Iterator<android.content.Intent!> iterator();
+    method public void startActivities();
+    method public void startActivities(android.os.Bundle?);
+  }
+
+  public static interface TaskStackBuilder.SupportParentable {
+    method public android.content.Intent? getSupportParentActivityIntent();
+  }
+
+}
+
+package androidx.core.content {
+
+  public final class ContentProviderCompat {
+    method public static android.content.Context requireContext(android.content.ContentProvider);
+  }
+
+  public final class ContentResolverCompat {
+    method public static android.database.Cursor? query(android.content.ContentResolver, android.net.Uri, String![]?, String?, String![]?, String?, androidx.core.os.CancellationSignal?);
+  }
+
+  public class ContextCompat {
+    ctor protected ContextCompat();
+    method public static int checkSelfPermission(android.content.Context, String);
+    method public static android.content.Context? createDeviceProtectedStorageContext(android.content.Context);
+    method public static String? getAttributionTag(android.content.Context);
+    method public static java.io.File getCodeCacheDir(android.content.Context);
+    method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
+    method public static java.io.File? getDataDir(android.content.Context);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
+    method public static java.io.File![] getExternalCacheDirs(android.content.Context);
+    method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
+    method public static java.util.concurrent.Executor getMainExecutor(android.content.Context);
+    method public static java.io.File? getNoBackupFilesDir(android.content.Context);
+    method public static java.io.File![] getObbDirs(android.content.Context);
+    method public static <T> T? getSystemService(android.content.Context, Class<T!>);
+    method public static String? getSystemServiceName(android.content.Context, Class<?>);
+    method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, int);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, String?, android.os.Handler?, int);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![]);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
+    method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
+    method public static void startForegroundService(android.content.Context, android.content.Intent);
+    field public static final int RECEIVER_EXPORTED = 2; // 0x2
+    field public static final int RECEIVER_NOT_EXPORTED = 4; // 0x4
+    field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
+  }
+
+  public class FileProvider extends android.content.ContentProvider {
+    ctor public FileProvider();
+    ctor protected FileProvider(@XmlRes int);
+    method public int delete(android.net.Uri, String?, String![]?);
+    method public String? getType(android.net.Uri);
+    method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
+    method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
+    method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
+    method public boolean onCreate();
+    method public android.database.Cursor query(android.net.Uri, String![]?, String?, String![]?, String?);
+    method public int update(android.net.Uri, android.content.ContentValues, String?, String![]?);
+  }
+
+  public final class IntentCompat {
+    method public static android.content.Intent createManageUnusedAppRestrictionsIntent(android.content.Context, String);
+    method public static android.os.Parcelable![]? getParcelableArrayExtra(android.content.Intent, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayListExtra(android.content.Intent, String?, Class<? extends T>);
+    method public static <T> T? getParcelableExtra(android.content.Intent, String?, Class<T!>);
+    method public static android.content.Intent makeMainSelectorActivity(String, String);
+    field public static final String ACTION_CREATE_REMINDER = "android.intent.action.CREATE_REMINDER";
+    field public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+    field public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
+    field public static final String EXTRA_TIME = "android.intent.extra.TIME";
+  }
+
+  public class IntentSanitizer {
+    method public android.content.Intent sanitize(android.content.Intent, androidx.core.util.Consumer<java.lang.String!>);
+    method public android.content.Intent sanitizeByFiltering(android.content.Intent);
+    method public android.content.Intent sanitizeByThrowing(android.content.Intent);
+  }
+
+  public static final class IntentSanitizer.Builder {
+    ctor public IntentSanitizer.Builder();
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowAnyComponent();
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipData(androidx.core.util.Predicate<android.content.ClipData!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataText();
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUri(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(android.content.ComponentName);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(androidx.core.util.Predicate<android.content.ComponentName!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponentWithPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowData(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowDataWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<?>);
+    method public <T> androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<T!>, androidx.core.util.Predicate<T!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, androidx.core.util.Predicate<java.lang.Object!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStream(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStreamUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowFlags(int);
+    method public androidx.core.content.IntentSanitizer.Builder allowHistoryStackFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowIdentifier();
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowReceiverFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowSelector();
+    method public androidx.core.content.IntentSanitizer.Builder allowSourceBounds();
+    method public androidx.core.content.IntentSanitizer.Builder allowType(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowType(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer build();
+  }
+
+  public final class LocusIdCompat {
+    ctor public LocusIdCompat(String);
+    method public String getId();
+    method @RequiresApi(29) public android.content.LocusId toLocusId();
+    method @RequiresApi(29) public static androidx.core.content.LocusIdCompat toLocusIdCompat(android.content.LocusId);
+  }
+
+  public final class MimeTypeFilter {
+    method public static boolean matches(String?, String);
+    method public static String? matches(String?, String![]);
+    method public static String? matches(String![]?, String);
+    method public static String![] matchesMany(String![]?, String);
+  }
+
+  public interface OnConfigurationChangedProvider {
+    method public void addOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+    method public void removeOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+  }
+
+  public interface OnTrimMemoryProvider {
+    method public void addOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+    method public void removeOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+  }
+
+  public final class PackageManagerCompat {
+    method public static com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> getUnusedAppRestrictionsStatus(android.content.Context);
+    field public static final String ACTION_PERMISSION_REVOCATION_SETTINGS = "android.intent.action.AUTO_REVOKE_PERMISSIONS";
+  }
+
+  public final class PermissionChecker {
+    method public static int checkCallingOrSelfPermission(android.content.Context, String);
+    method public static int checkCallingPermission(android.content.Context, String, String?);
+    method public static int checkPermission(android.content.Context, String, int, int, String?);
+    method public static int checkSelfPermission(android.content.Context, String);
+    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
+    field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
+    field public static final int PERMISSION_GRANTED = 0; // 0x0
+  }
+
+  @Deprecated public final class SharedPreferencesCompat {
+  }
+
+  @Deprecated public static final class SharedPreferencesCompat.EditorCompat {
+    method @Deprecated public void apply(android.content.SharedPreferences.Editor);
+    method @Deprecated public static androidx.core.content.SharedPreferencesCompat.EditorCompat! getInstance();
+  }
+
+  public class UnusedAppRestrictionsBackportCallback {
+    method public void onResult(boolean, boolean) throws android.os.RemoteException;
+  }
+
+  public abstract class UnusedAppRestrictionsBackportService extends android.app.Service {
+    ctor public UnusedAppRestrictionsBackportService();
+    method protected abstract void isPermissionRevocationEnabled(androidx.core.content.UnusedAppRestrictionsBackportCallback);
+    method public android.os.IBinder? onBind(android.content.Intent?);
+    field public static final String ACTION_UNUSED_APP_RESTRICTIONS_BACKPORT_CONNECTION = "android.support.unusedapprestrictions.action.CustomUnusedAppRestrictionsBackportService";
+  }
+
+  public final class UnusedAppRestrictionsConstants {
+    field public static final int API_30 = 4; // 0x4
+    field public static final int API_30_BACKPORT = 3; // 0x3
+    field public static final int API_31 = 5; // 0x5
+    field public static final int DISABLED = 2; // 0x2
+    field public static final int ERROR = 0; // 0x0
+    field public static final int FEATURE_NOT_AVAILABLE = 1; // 0x1
+  }
+
+  public class UriMatcherCompat {
+    method public static androidx.core.util.Predicate<android.net.Uri!> asPredicate(android.content.UriMatcher);
+  }
+
+}
+
+package androidx.core.content.pm {
+
+  @Deprecated public final class ActivityInfoCompat {
+    field @Deprecated public static final int CONFIG_UI_MODE = 512; // 0x200
+  }
+
+  public final class PackageInfoCompat {
+    method public static long getLongVersionCode(android.content.pm.PackageInfo);
+    method public static java.util.List<android.content.pm.Signature!> getSignatures(android.content.pm.PackageManager, String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static boolean hasSignatures(android.content.pm.PackageManager, String, @Size(min=1) java.util.Map<byte[]!,java.lang.Integer!>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
+  }
+
+  public final class PermissionInfoCompat {
+    method public static int getProtection(android.content.pm.PermissionInfo);
+    method public static int getProtectionFlags(android.content.pm.PermissionInfo);
+  }
+
+  public class ShortcutInfoCompat {
+    method public android.content.ComponentName? getActivity();
+    method public java.util.Set<java.lang.String!>? getCategories();
+    method public CharSequence? getDisabledMessage();
+    method public int getDisabledReason();
+    method public int getExcludedFromSurfaces();
+    method public android.os.PersistableBundle? getExtras();
+    method public String getId();
+    method public android.content.Intent getIntent();
+    method public android.content.Intent![] getIntents();
+    method public long getLastChangedTimestamp();
+    method public androidx.core.content.LocusIdCompat? getLocusId();
+    method public CharSequence? getLongLabel();
+    method public String getPackage();
+    method public int getRank();
+    method public CharSequence getShortLabel();
+    method public android.os.UserHandle? getUserHandle();
+    method public boolean hasKeyFieldsOnly();
+    method public boolean isCached();
+    method public boolean isDeclaredInManifest();
+    method public boolean isDynamic();
+    method public boolean isEnabled();
+    method public boolean isExcludedFromSurfaces(int);
+    method public boolean isImmutable();
+    method public boolean isPinned();
+    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
+    field public static final int SURFACE_LAUNCHER = 1; // 0x1
+  }
+
+  public static class ShortcutInfoCompat.Builder {
+    ctor public ShortcutInfoCompat.Builder(android.content.Context, String);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String, String, java.util.List<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat build();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setAlwaysBadged();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setCategories(java.util.Set<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExcludedFromSurfaces(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExtras(android.os.PersistableBundle);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIcon(androidx.core.graphics.drawable.IconCompat!);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIsConversation();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLabel(CharSequence);
+    method @Deprecated public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived(boolean);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPerson(androidx.core.app.Person);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPersons(androidx.core.app.Person![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setRank(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setShortLabel(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setSliceUri(android.net.Uri);
+  }
+
+  public class ShortcutManagerCompat {
+    method public static boolean addDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static android.content.Intent createShortcutResultIntent(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void disableShortcuts(android.content.Context, java.util.List<java.lang.String!>, CharSequence?);
+    method public static void enableShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
+    method public static int getIconMaxHeight(android.content.Context);
+    method public static int getIconMaxWidth(android.content.Context);
+    method public static int getMaxShortcutCountPerActivity(android.content.Context);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getShortcuts(android.content.Context, int);
+    method public static boolean isRateLimitingActive(android.content.Context);
+    method public static boolean isRequestPinShortcutSupported(android.content.Context);
+    method public static boolean pushDynamicShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void removeAllDynamicShortcuts(android.content.Context);
+    method public static void removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void removeLongLivedShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void reportShortcutUsed(android.content.Context, String);
+    method public static boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
+    method public static boolean setDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static boolean updateShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    field public static final String EXTRA_SHORTCUT_ID = "android.intent.extra.shortcut.ID";
+    field public static final int FLAG_MATCH_CACHED = 8; // 0x8
+    field public static final int FLAG_MATCH_DYNAMIC = 2; // 0x2
+    field public static final int FLAG_MATCH_MANIFEST = 1; // 0x1
+    field public static final int FLAG_MATCH_PINNED = 4; // 0x4
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class ConfigurationHelper {
+    method public static int getDensityDpi(android.content.res.Resources);
+  }
+
+  public final class ResourcesCompat {
+    method public static void clearCachesForTheme(android.content.res.Resources.Theme);
+    method public static android.graphics.Typeface? getCachedFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method @ColorInt public static int getColor(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.Resources, @DrawableRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawableForDensity(android.content.res.Resources, @DrawableRes int, int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static float getFloat(android.content.res.Resources, @DimenRes int);
+    method public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method public static void getFont(android.content.Context, @FontRes int, androidx.core.content.res.ResourcesCompat.FontCallback, android.os.Handler?) throws android.content.res.Resources.NotFoundException;
+    field @AnyRes public static final int ID_NULL = 0; // 0x0
+  }
+
+  public abstract static class ResourcesCompat.FontCallback {
+    ctor public ResourcesCompat.FontCallback();
+    method public abstract void onFontRetrievalFailed(int);
+    method public abstract void onFontRetrieved(android.graphics.Typeface);
+  }
+
+  public static final class ResourcesCompat.ThemeCompat {
+    method public static void rebase(android.content.res.Resources.Theme);
+  }
+
+}
+
+package androidx.core.database {
+
+  public final class CursorWindowCompat {
+    method public static android.database.CursorWindow create(String?, long);
+  }
+
+  @Deprecated public final class DatabaseUtilsCompat {
+    method @Deprecated public static String![]! appendSelectionArgs(String![]!, String![]!);
+    method @Deprecated public static String! concatenateWhere(String!, String!);
+  }
+
+}
+
+package androidx.core.database.sqlite {
+
+  public final class SQLiteCursorCompat {
+    method public static void setFillWindowForwardOnly(android.database.sqlite.SQLiteCursor, boolean);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapCompat {
+    method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, android.graphics.Rect?, boolean);
+    method public static int getAllocationByteCount(android.graphics.Bitmap);
+    method public static boolean hasMipMap(android.graphics.Bitmap);
+    method public static void setHasMipMap(android.graphics.Bitmap, boolean);
+  }
+
+  public class BlendModeColorFilterCompat {
+    method public static android.graphics.ColorFilter? createBlendModeColorFilterCompat(int, androidx.core.graphics.BlendModeCompat);
+  }
+
+  public enum BlendModeCompat {
+    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HUE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SATURATION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
+  }
+
+  public final class ColorUtils {
+    method @ColorInt public static int HSLToColor(float[]);
+    method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
+    method public static void LABToXYZ(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double, double[]);
+    method public static void RGBToHSL(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, float[]);
+    method public static void RGBToLAB(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method public static void RGBToXYZ(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method @ColorInt public static int XYZToColor(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double);
+    method public static void XYZToLAB(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double, double[]);
+    method @ColorInt public static int blendARGB(@ColorInt int, @ColorInt int, @FloatRange(from=0.0, to=1.0) float);
+    method public static void blendHSL(float[], float[], @FloatRange(from=0.0, to=1.0) float, float[]);
+    method public static void blendLAB(double[], double[], @FloatRange(from=0.0, to=1.0) double, double[]);
+    method public static double calculateContrast(@ColorInt int, @ColorInt int);
+    method @FloatRange(from=0.0, to=1.0) public static double calculateLuminance(@ColorInt int);
+    method public static int calculateMinimumAlpha(@ColorInt int, @ColorInt int, float);
+    method public static void colorToHSL(@ColorInt int, float[]);
+    method public static void colorToLAB(@ColorInt int, double[]);
+    method public static void colorToXYZ(@ColorInt int, double[]);
+    method public static int compositeColors(@ColorInt int, @ColorInt int);
+    method @RequiresApi(26) public static android.graphics.Color compositeColors(android.graphics.Color, android.graphics.Color);
+    method public static double distanceEuclidean(double[], double[]);
+    method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
+  }
+
+  public final class Insets {
+    method public static androidx.core.graphics.Insets add(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets max(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets min(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets of(int, int, int, int);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    method public static androidx.core.graphics.Insets subtract(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method @RequiresApi(api=29) public static androidx.core.graphics.Insets toCompatInsets(android.graphics.Insets);
+    method @RequiresApi(29) public android.graphics.Insets toPlatformInsets();
+    field public static final androidx.core.graphics.Insets NONE;
+    field public final int bottom;
+    field public final int left;
+    field public final int right;
+    field public final int top;
+  }
+
+  public final class PaintCompat {
+    method public static boolean hasGlyph(android.graphics.Paint, String);
+    method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
+  }
+
+  public final class PathSegment {
+    ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
+    method public android.graphics.PointF getEnd();
+    method public float getEndFraction();
+    method public android.graphics.PointF getStart();
+    method public float getStartFraction();
+  }
+
+  public final class PathUtils {
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path);
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path, @FloatRange(from=0) float);
+  }
+
+  public class TypefaceCompat {
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, int);
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, @IntRange(from=1, to=1000) int, boolean);
+  }
+
+}
+
+package androidx.core.graphics.drawable {
+
+  public final class DrawableCompat {
+    method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
+    method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
+    method public static void clearColorFilter(android.graphics.drawable.Drawable);
+    method public static int getAlpha(android.graphics.drawable.Drawable);
+    method public static android.graphics.ColorFilter? getColorFilter(android.graphics.drawable.Drawable);
+    method public static int getLayoutDirection(android.graphics.drawable.Drawable);
+    method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
+    method @Deprecated public static void jumpToCurrentState(android.graphics.drawable.Drawable);
+    method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
+    method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
+    method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
+    method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
+    method public static void setTint(android.graphics.drawable.Drawable, @ColorInt int);
+    method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList?);
+    method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode?);
+    method public static <T extends android.graphics.drawable.Drawable> T! unwrap(android.graphics.drawable.Drawable);
+    method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
+  }
+
+  public class IconCompat implements androidx.versionedparcelable.VersionedParcelable {
+    method public static androidx.core.graphics.drawable.IconCompat? createFromBundle(android.os.Bundle);
+    method @RequiresApi(23) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.content.Context, android.graphics.drawable.Icon);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithData(byte[], int, int);
+    method public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.Context, @DrawableRes int);
+    method @DrawableRes public int getResId();
+    method public String getResPackage();
+    method public int getType();
+    method public android.net.Uri getUri();
+    method public android.graphics.drawable.Drawable? loadDrawable(android.content.Context);
+    method public void onPostParceling();
+    method public void onPreParceling(boolean);
+    method public androidx.core.graphics.drawable.IconCompat setTint(@ColorInt int);
+    method public androidx.core.graphics.drawable.IconCompat setTintList(android.content.res.ColorStateList?);
+    method public androidx.core.graphics.drawable.IconCompat setTintMode(android.graphics.PorterDuff.Mode?);
+    method public android.os.Bundle toBundle();
+    method @Deprecated @RequiresApi(23) public android.graphics.drawable.Icon toIcon();
+    method @RequiresApi(23) public android.graphics.drawable.Icon toIcon(android.content.Context?);
+    field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
+    field public static final int TYPE_BITMAP = 1; // 0x1
+    field public static final int TYPE_DATA = 3; // 0x3
+    field public static final int TYPE_RESOURCE = 2; // 0x2
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int TYPE_URI = 4; // 0x4
+    field public static final int TYPE_URI_ADAPTIVE_BITMAP = 6; // 0x6
+  }
+
+  public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.Bitmap? getBitmap();
+    method public float getCornerRadius();
+    method public int getGravity();
+    method public int getOpacity();
+    method public final android.graphics.Paint getPaint();
+    method public boolean hasAntiAlias();
+    method public boolean hasMipMap();
+    method public boolean isCircular();
+    method public void setAlpha(int);
+    method public void setAntiAlias(boolean);
+    method public void setCircular(boolean);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setCornerRadius(float);
+    method public void setDither(boolean);
+    method public void setGravity(int);
+    method public void setMipMap(boolean);
+    method public void setTargetDensity(android.graphics.Canvas);
+    method public void setTargetDensity(android.util.DisplayMetrics);
+    method public void setTargetDensity(int);
+  }
+
+  public final class RoundedBitmapDrawableFactory {
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap?);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, String);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
+  }
+
+}
+
+package androidx.core.hardware.display {
+
+  public final class DisplayManagerCompat {
+    method public android.view.Display? getDisplay(int);
+    method public android.view.Display![] getDisplays();
+    method public android.view.Display![] getDisplays(String?);
+    method public static androidx.core.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
+    field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+  }
+
+}
+
+package androidx.core.hardware.fingerprint {
+
+  @Deprecated public class FingerprintManagerCompat {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public void authenticate(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject?, int, androidx.core.os.CancellationSignal?, androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler?);
+    method @Deprecated public static androidx.core.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean hasEnrolledFingerprints();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean isHardwareDetected();
+  }
+
+  @Deprecated public abstract static class FingerprintManagerCompat.AuthenticationCallback {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationCallback();
+    method @Deprecated public void onAuthenticationError(int, CharSequence!);
+    method @Deprecated public void onAuthenticationFailed();
+    method @Deprecated public void onAuthenticationHelp(int, CharSequence!);
+    method @Deprecated public void onAuthenticationSucceeded(androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult!);
+  }
+
+  @Deprecated public static final class FingerprintManagerCompat.AuthenticationResult {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationResult(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject!);
+    method @Deprecated public androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject! getCryptoObject();
+  }
+
+  @Deprecated public static class FingerprintManagerCompat.CryptoObject {
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
+    method @Deprecated public javax.crypto.Cipher? getCipher();
+    method @Deprecated public javax.crypto.Mac? getMac();
+    method @Deprecated public java.security.Signature? getSignature();
+  }
+
+}
+
+package androidx.core.location {
+
+  public abstract class GnssStatusCompat {
+    method @FloatRange(from=0, to=360) public abstract float getAzimuthDegrees(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getBasebandCn0DbHz(@IntRange(from=0) int);
+    method @FloatRange(from=0) public abstract float getCarrierFrequencyHz(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getCn0DbHz(@IntRange(from=0) int);
+    method public abstract int getConstellationType(@IntRange(from=0) int);
+    method @FloatRange(from=0xffffffa6, to=90) public abstract float getElevationDegrees(@IntRange(from=0) int);
+    method @IntRange(from=0) public abstract int getSatelliteCount();
+    method @IntRange(from=1, to=200) public abstract int getSvid(@IntRange(from=0) int);
+    method public abstract boolean hasAlmanacData(@IntRange(from=0) int);
+    method public abstract boolean hasBasebandCn0DbHz(@IntRange(from=0) int);
+    method public abstract boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
+    method public abstract boolean hasEphemerisData(@IntRange(from=0) int);
+    method public abstract boolean usedInFix(@IntRange(from=0) int);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static androidx.core.location.GnssStatusCompat wrap(android.location.GnssStatus);
+    method public static androidx.core.location.GnssStatusCompat wrap(android.location.GpsStatus);
+    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
+    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
+    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
+    field public static final int CONSTELLATION_GPS = 1; // 0x1
+    field public static final int CONSTELLATION_IRNSS = 7; // 0x7
+    field public static final int CONSTELLATION_QZSS = 4; // 0x4
+    field public static final int CONSTELLATION_SBAS = 2; // 0x2
+    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
+  }
+
+  public abstract static class GnssStatusCompat.Callback {
+    ctor public GnssStatusCompat.Callback();
+    method public void onFirstFix(@IntRange(from=0) int);
+    method public void onSatelliteStatusChanged(androidx.core.location.GnssStatusCompat);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public final class LocationCompat {
+    method public static float getBearingAccuracyDegrees(android.location.Location);
+    method public static long getElapsedRealtimeMillis(android.location.Location);
+    method public static long getElapsedRealtimeNanos(android.location.Location);
+    method @FloatRange(from=0.0) public static float getMslAltitudeAccuracyMeters(android.location.Location);
+    method public static double getMslAltitudeMeters(android.location.Location);
+    method public static float getSpeedAccuracyMetersPerSecond(android.location.Location);
+    method public static float getVerticalAccuracyMeters(android.location.Location);
+    method public static boolean hasBearingAccuracy(android.location.Location);
+    method public static boolean hasMslAltitude(android.location.Location);
+    method public static boolean hasMslAltitudeAccuracy(android.location.Location);
+    method public static boolean hasSpeedAccuracy(android.location.Location);
+    method public static boolean hasVerticalAccuracy(android.location.Location);
+    method public static boolean isMock(android.location.Location);
+    method public static void removeMslAltitude(android.location.Location);
+    method public static void removeMslAltitudeAccuracy(android.location.Location);
+    method public static void setBearingAccuracyDegrees(android.location.Location, float);
+    method public static void setMock(android.location.Location, boolean);
+    method public static void setMslAltitudeAccuracyMeters(android.location.Location, @FloatRange(from=0.0) float);
+    method public static void setMslAltitudeMeters(android.location.Location, double);
+    method public static void setSpeedAccuracyMetersPerSecond(android.location.Location, float);
+    method public static void setVerticalAccuracyMeters(android.location.Location, float);
+    field public static final String EXTRA_BEARING_ACCURACY = "bearingAccuracy";
+    field public static final String EXTRA_IS_MOCK = "mockLocation";
+    field public static final String EXTRA_MSL_ALTITUDE = "androidx.core.location.extra.MSL_ALTITUDE";
+    field public static final String EXTRA_MSL_ALTITUDE_ACCURACY = "androidx.core.location.extra.MSL_ALTITUDE_ACCURACY";
+    field public static final String EXTRA_SPEED_ACCURACY = "speedAccuracy";
+    field public static final String EXTRA_VERTICAL_ACCURACY = "verticalAccuracy";
+  }
+
+  public interface LocationListenerCompat extends android.location.LocationListener {
+    method public default void onStatusChanged(String, int, android.os.Bundle?);
+  }
+
+  public final class LocationManagerCompat {
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void getCurrentLocation(android.location.LocationManager, String, androidx.core.os.CancellationSignal?, java.util.concurrent.Executor, androidx.core.util.Consumer<android.location.Location!>);
+    method public static String? getGnssHardwareModelName(android.location.LocationManager);
+    method public static int getGnssYearOfHardware(android.location.LocationManager);
+    method public static boolean hasProvider(android.location.LocationManager, String);
+    method public static boolean isLocationEnabled(android.location.LocationManager);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
+    method @RequiresApi(android.os.Build.VERSION_CODES.R) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, java.util.concurrent.Executor, android.location.GnssMeasurementsEvent.Callback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback, android.os.Handler);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, java.util.concurrent.Executor, androidx.core.location.GnssStatusCompat.Callback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void removeUpdates(android.location.LocationManager, androidx.core.location.LocationListenerCompat);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, java.util.concurrent.Executor, androidx.core.location.LocationListenerCompat);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, androidx.core.location.LocationListenerCompat, android.os.Looper);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static void unregisterGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback);
+    method public static void unregisterGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback);
+  }
+
+  public final class LocationRequestCompat {
+    method @IntRange(from=1) public long getDurationMillis();
+    method @IntRange(from=0) public long getIntervalMillis();
+    method @IntRange(from=0) public long getMaxUpdateDelayMillis();
+    method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates();
+    method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters();
+    method @IntRange(from=0) public long getMinUpdateIntervalMillis();
+    method public int getQuality();
+    method @RequiresApi(31) public android.location.LocationRequest toLocationRequest();
+    method @RequiresApi(19) public android.location.LocationRequest? toLocationRequest(String);
+    field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL
+    field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66
+    field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64
+    field public static final int QUALITY_LOW_POWER = 104; // 0x68
+  }
+
+  public static final class LocationRequestCompat.Builder {
+    ctor public LocationRequestCompat.Builder(long);
+    ctor public LocationRequestCompat.Builder(androidx.core.location.LocationRequestCompat);
+    method public androidx.core.location.LocationRequestCompat build();
+    method public androidx.core.location.LocationRequestCompat.Builder clearMinUpdateIntervalMillis();
+    method public androidx.core.location.LocationRequestCompat.Builder setDurationMillis(@IntRange(from=1) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdateDelayMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setQuality(int);
+  }
+
+}
+
+package androidx.core.math {
+
+  public class MathUtils {
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
+    method public static float clamp(float, float, float);
+    method public static double clamp(double, double, double);
+    method public static int clamp(int, int, int);
+    method public static long clamp(long, long, long);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
+    method public static int toIntExact(long);
+  }
+
+}
+
+package androidx.core.net {
+
+  public final class ConnectivityManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static android.net.NetworkInfo? getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
+    method public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
+    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+  }
+
+  public final class MailTo {
+    method public String? getBcc();
+    method public String? getBody();
+    method public String? getCc();
+    method public java.util.Map<java.lang.String!,java.lang.String!>? getHeaders();
+    method public String? getSubject();
+    method public String? getTo();
+    method public static boolean isMailTo(String?);
+    method public static boolean isMailTo(android.net.Uri?);
+    method public static androidx.core.net.MailTo parse(String) throws androidx.core.net.ParseException;
+    method public static androidx.core.net.MailTo parse(android.net.Uri) throws androidx.core.net.ParseException;
+    field public static final String MAILTO_SCHEME = "mailto:";
+  }
+
+  public class ParseException extends java.lang.RuntimeException {
+    field public final String response;
+  }
+
+  public final class TrafficStatsCompat {
+    method @Deprecated public static void clearThreadStatsTag();
+    method @Deprecated public static int getThreadStatsTag();
+    method @Deprecated public static void incrementOperationCount(int);
+    method @Deprecated public static void incrementOperationCount(int, int);
+    method @Deprecated public static void setThreadStatsTag(int);
+    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void tagSocket(java.net.Socket!) throws java.net.SocketException;
+    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void untagSocket(java.net.Socket!) throws java.net.SocketException;
+  }
+
+  public final class UriCompat {
+    method public static String toSafeString(android.net.Uri);
+  }
+
+}
+
+package androidx.core.os {
+
+  public class BuildCompat {
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N) public static boolean isAtLeastN();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N_MR1) public static boolean isAtLeastNMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O) public static boolean isAtLeastO();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O_MR1) public static boolean isAtLeastOMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.P) public static boolean isAtLeastP();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
+    method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
+    method @Deprecated @ChecksSdkIntAtLeast(api=32, codename="Sv2") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastSv2();
+    method @ChecksSdkIntAtLeast(api=33, codename="Tiramisu") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastT();
+    method @ChecksSdkIntAtLeast(codename="UpsideDownCake") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastU();
+    field @ChecksSdkIntAtLeast(extension=android.os.ext.SdkExtensions.AD_SERVICES) public static final int AD_SERVICES_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.R) public static final int R_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.S) public static final int S_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.TIRAMISU) public static final int T_EXTENSION_INT;
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface BuildCompat.PrereleaseSdkCheck {
+  }
+
+  public final class BundleCompat {
+    method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
+    method public static android.os.Parcelable![]? getParcelableArray(android.os.Bundle, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayList(android.os.Bundle, String?, Class<? extends T>);
+    method public static <T> android.util.SparseArray<T!>? getSparseParcelableArray(android.os.Bundle, String?, Class<? extends T>);
+  }
+
+  public final class CancellationSignal {
+    ctor public CancellationSignal();
+    method public void cancel();
+    method public Object? getCancellationSignalObject();
+    method public boolean isCanceled();
+    method public void setOnCancelListener(androidx.core.os.CancellationSignal.OnCancelListener?);
+    method public void throwIfCanceled();
+  }
+
+  public static interface CancellationSignal.OnCancelListener {
+    method public void onCancel();
+  }
+
+  public final class ConfigurationCompat {
+    method public static androidx.core.os.LocaleListCompat getLocales(android.content.res.Configuration);
+  }
+
+  public final class EnvironmentCompat {
+    method public static String getStorageState(java.io.File);
+    field public static final String MEDIA_UNKNOWN = "unknown";
+  }
+
+  public final class ExecutorCompat {
+    method public static java.util.concurrent.Executor create(android.os.Handler);
+  }
+
+  public final class HandlerCompat {
+    method public static android.os.Handler createAsync(android.os.Looper);
+    method public static android.os.Handler createAsync(android.os.Looper, android.os.Handler.Callback);
+    method @RequiresApi(16) public static boolean hasCallbacks(android.os.Handler, Runnable);
+    method public static boolean postDelayed(android.os.Handler, Runnable, Object?, long);
+  }
+
+  public final class LocaleListCompat {
+    method public static androidx.core.os.LocaleListCompat create(java.util.Locale!...);
+    method public static androidx.core.os.LocaleListCompat forLanguageTags(String?);
+    method public java.util.Locale? get(int);
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getAdjustedDefault();
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getDefault();
+    method public static androidx.core.os.LocaleListCompat getEmptyLocaleList();
+    method public java.util.Locale? getFirstMatch(String![]);
+    method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
+    method public boolean isEmpty();
+    method @RequiresApi(21) public static boolean matchesLanguageAndScript(java.util.Locale, java.util.Locale);
+    method @IntRange(from=0) public int size();
+    method public String toLanguageTags();
+    method public Object? unwrap();
+    method @Deprecated @RequiresApi(24) public static androidx.core.os.LocaleListCompat! wrap(Object!);
+    method @RequiresApi(24) public static androidx.core.os.LocaleListCompat wrap(android.os.LocaleList);
+  }
+
+  public final class MessageCompat {
+    method public static boolean isAsynchronous(android.os.Message);
+    method public static void setAsynchronous(android.os.Message, boolean);
+  }
+
+  public class OperationCanceledException extends java.lang.RuntimeException {
+    ctor public OperationCanceledException();
+    ctor public OperationCanceledException(String?);
+  }
+
+  public final class ParcelCompat {
+    method public static <T> Object![]? readArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> java.util.ArrayList<T!>? readArrayList(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static boolean readBoolean(android.os.Parcel);
+    method public static <K, V> java.util.HashMap<K!,V!>? readHashMap(android.os.Parcel, ClassLoader?, Class<? extends K>, Class<? extends V>);
+    method public static <T> void readList(android.os.Parcel, java.util.List<? super T>, ClassLoader?, Class<T!>);
+    method public static <K, V> void readMap(android.os.Parcel, java.util.Map<? super K,? super V>, ClassLoader?, Class<K!>, Class<V!>);
+    method public static <T extends android.os.Parcelable> T? readParcelable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @Deprecated public static <T> T![]? readParcelableArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.os.Parcelable![]? readParcelableArrayTyped(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(30) public static <T> android.os.Parcelable.Creator<T!>? readParcelableCreator(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.Q) public static <T> java.util.List<T!> readParcelableList(android.os.Parcel, java.util.List<T!>, ClassLoader?, Class<T!>);
+    method public static <T extends java.io.Serializable> T? readSerializable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.util.SparseArray<T!>? readSparseArray(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static void writeBoolean(android.os.Parcel, boolean);
+  }
+
+  @Deprecated public final class ParcelableCompat {
+    method @Deprecated public static <T> android.os.Parcelable.Creator<T!>! newCreator(androidx.core.os.ParcelableCompatCreatorCallbacks<T!>!);
+  }
+
+  @Deprecated public interface ParcelableCompatCreatorCallbacks<T> {
+    method @Deprecated public T! createFromParcel(android.os.Parcel!, ClassLoader!);
+    method @Deprecated public T![]! newArray(int);
+  }
+
+  public final class ProcessCompat {
+    method public static boolean isApplicationUid(int);
+  }
+
+  @Deprecated public final class TraceCompat {
+    method @Deprecated public static void beginAsyncSection(String, int);
+    method @Deprecated public static void beginSection(String);
+    method @Deprecated public static void endAsyncSection(String, int);
+    method @Deprecated public static void endSection();
+    method @Deprecated public static boolean isEnabled();
+    method @Deprecated public static void setCounter(String, int);
+  }
+
+  @RequiresApi(17) public class UserHandleCompat {
+    method public static android.os.UserHandle getUserHandleForUid(int);
+  }
+
+  public class UserManagerCompat {
+    method public static boolean isUserUnlocked(android.content.Context);
+  }
+
+}
+
+package androidx.core.provider {
+
+  public final class DocumentsContractCompat {
+    method public static android.net.Uri? buildChildDocumentsUri(String, String?);
+    method public static android.net.Uri? buildChildDocumentsUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildDocumentUri(String, String);
+    method public static android.net.Uri? buildDocumentUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildTreeDocumentUri(String, String);
+    method public static android.net.Uri? createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException;
+    method public static String? getDocumentId(android.net.Uri);
+    method public static String? getTreeDocumentId(android.net.Uri);
+    method public static boolean isDocumentUri(android.content.Context, android.net.Uri?);
+    method public static boolean isTreeUri(android.net.Uri);
+    method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.net.Uri? renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException;
+  }
+
+  public static final class DocumentsContractCompat.DocumentCompat {
+    field public static final int FLAG_VIRTUAL_DOCUMENT = 512; // 0x200
+  }
+
+  public final class FontRequest {
+    ctor public FontRequest(String, String, String, java.util.List<java.util.List<byte[]!>!>);
+    ctor public FontRequest(String, String, String, @ArrayRes int);
+    method public java.util.List<java.util.List<byte[]!>!>? getCertificates();
+    method @ArrayRes public int getCertificatesArrayResId();
+    method public String getProviderAuthority();
+    method public String getProviderPackage();
+    method public String getQuery();
+  }
+
+  public class FontsContractCompat {
+    method public static android.graphics.Typeface? buildTypeface(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![]);
+    method public static androidx.core.provider.FontsContractCompat.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void requestFont(android.content.Context, androidx.core.provider.FontRequest, androidx.core.provider.FontsContractCompat.FontRequestCallback, android.os.Handler);
+  }
+
+  public static final class FontsContractCompat.Columns implements android.provider.BaseColumns {
+    ctor public FontsContractCompat.Columns();
+    field public static final String FILE_ID = "file_id";
+    field public static final String ITALIC = "font_italic";
+    field public static final String RESULT_CODE = "result_code";
+    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
+    field public static final int RESULT_CODE_OK = 0; // 0x0
+    field public static final String TTC_INDEX = "font_ttc_index";
+    field public static final String VARIATION_SETTINGS = "font_variation_settings";
+    field public static final String WEIGHT = "font_weight";
+  }
+
+  public static class FontsContractCompat.FontFamilyResult {
+    method public androidx.core.provider.FontsContractCompat.FontInfo![]! getFonts();
+    method public int getStatusCode();
+    field public static final int STATUS_OK = 0; // 0x0
+    field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
+    field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
+  }
+
+  public static class FontsContractCompat.FontInfo {
+    method public int getResultCode();
+    method @IntRange(from=0) public int getTtcIndex();
+    method public android.net.Uri getUri();
+    method @IntRange(from=1, to=1000) public int getWeight();
+    method public boolean isItalic();
+  }
+
+  public static class FontsContractCompat.FontRequestCallback {
+    ctor public FontsContractCompat.FontRequestCallback();
+    method public void onTypefaceRequestFailed(int);
+    method public void onTypefaceRetrieved(android.graphics.Typeface!);
+    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+    field public static final int FAIL_REASON_SECURITY_VIOLATION = -4; // 0xfffffffc
+    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
+  }
+
+}
+
+package androidx.core.telephony {
+
+  @RequiresApi(22) public class SubscriptionManagerCompat {
+    method public static int getSlotIndex(int);
+  }
+
+  public class TelephonyManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static String? getImei(android.telephony.TelephonyManager);
+    method public static int getSubscriptionId(android.telephony.TelephonyManager);
+  }
+
+}
+
+package androidx.core.telephony.mbms {
+
+  public final class MbmsHelper {
+    method public static CharSequence? getBestNameForService(android.content.Context, android.telephony.mbms.ServiceInfo);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class BidiFormatter {
+    method public static androidx.core.text.BidiFormatter! getInstance();
+    method public static androidx.core.text.BidiFormatter! getInstance(boolean);
+    method public static androidx.core.text.BidiFormatter! getInstance(java.util.Locale!);
+    method public boolean getStereoReset();
+    method public boolean isRtl(String!);
+    method public boolean isRtl(CharSequence!);
+    method public boolean isRtlContext();
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public String! unicodeWrap(String!, boolean);
+    method public CharSequence! unicodeWrap(CharSequence!, boolean);
+    method public String! unicodeWrap(String!);
+    method public CharSequence! unicodeWrap(CharSequence!);
+  }
+
+  public static final class BidiFormatter.Builder {
+    ctor public BidiFormatter.Builder();
+    ctor public BidiFormatter.Builder(boolean);
+    ctor public BidiFormatter.Builder(java.util.Locale!);
+    method public androidx.core.text.BidiFormatter! build();
+    method public androidx.core.text.BidiFormatter.Builder! setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat!);
+    method public androidx.core.text.BidiFormatter.Builder! stereoReset(boolean);
+  }
+
+  public final class HtmlCompat {
+    method public static android.text.Spanned fromHtml(String, int);
+    method public static android.text.Spanned fromHtml(String, int, android.text.Html.ImageGetter?, android.text.Html.TagHandler?);
+    method public static String toHtml(android.text.Spanned, int);
+    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
+    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
+    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
+    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
+    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
+  }
+
+  public final class ICUCompat {
+    method public static String? maximizeAndGetScript(java.util.Locale);
+  }
+
+  public class PrecomputedTextCompat implements android.text.Spannable {
+    method public char charAt(int);
+    method public static androidx.core.text.PrecomputedTextCompat! create(CharSequence, androidx.core.text.PrecomputedTextCompat.Params);
+    method @IntRange(from=0) public int getParagraphCount();
+    method @IntRange(from=0) public int getParagraphEnd(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getParagraphStart(@IntRange(from=0) int);
+    method public androidx.core.text.PrecomputedTextCompat.Params getParams();
+    method public int getSpanEnd(Object!);
+    method public int getSpanFlags(Object!);
+    method public int getSpanStart(Object!);
+    method public <T> T![]! getSpans(int, int, Class<T!>!);
+    method @UiThread public static java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>! getTextFuture(CharSequence, androidx.core.text.PrecomputedTextCompat.Params, java.util.concurrent.Executor?);
+    method public int length();
+    method public int nextSpanTransition(int, int, Class!);
+    method public void removeSpan(Object!);
+    method public void setSpan(Object!, int, int, int);
+    method public CharSequence! subSequence(int, int);
+  }
+
+  public static final class PrecomputedTextCompat.Params {
+    ctor @RequiresApi(28) public PrecomputedTextCompat.Params(android.text.PrecomputedText.Params);
+    method @RequiresApi(23) public int getBreakStrategy();
+    method @RequiresApi(23) public int getHyphenationFrequency();
+    method @RequiresApi(18) public android.text.TextDirectionHeuristic? getTextDirection();
+    method public android.text.TextPaint getTextPaint();
+  }
+
+  public static class PrecomputedTextCompat.Params.Builder {
+    ctor public PrecomputedTextCompat.Params.Builder(android.text.TextPaint);
+    method public androidx.core.text.PrecomputedTextCompat.Params build();
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setBreakStrategy(int);
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setHyphenationFrequency(int);
+    method @RequiresApi(18) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setTextDirection(android.text.TextDirectionHeuristic);
+  }
+
+  public interface TextDirectionHeuristicCompat {
+    method public boolean isRtl(char[]!, int, int);
+    method public boolean isRtl(CharSequence!, int, int);
+  }
+
+  public final class TextDirectionHeuristicsCompat {
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! ANYRTL_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_RTL;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LOCALE;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! RTL;
+  }
+
+  public final class TextUtilsCompat {
+    method public static int getLayoutDirectionFromLocale(java.util.Locale?);
+    method public static String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.text.util {
+
+  public final class LinkifyCompat {
+    method public static boolean addLinks(android.text.Spannable, int);
+    method public static boolean addLinks(android.widget.TextView, int);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+  }
+
+}
+
+package androidx.core.util {
+
+  public class AtomicFile {
+    ctor public AtomicFile(java.io.File);
+    method public void delete();
+    method public void failWrite(java.io.FileOutputStream?);
+    method public void finishWrite(java.io.FileOutputStream?);
+    method public java.io.File getBaseFile();
+    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
+    method public byte[] readFully() throws java.io.IOException;
+    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+  }
+
+  public interface Consumer<T> {
+    method public void accept(T!);
+  }
+
+  public class ObjectsCompat {
+    method public static boolean equals(Object?, Object?);
+    method public static int hash(java.lang.Object!...);
+    method public static int hashCode(Object?);
+    method public static <T> T requireNonNull(T?);
+    method public static <T> T requireNonNull(T?, String);
+    method public static String? toString(Object?, String?);
+  }
+
+  public class Pair<F, S> {
+    ctor public Pair(F!, S!);
+    method public static <A, B> androidx.core.util.Pair<A!,B!> create(A!, B!);
+    field public final F! first;
+    field public final S! second;
+  }
+
+  public final class PatternsCompat {
+    field public static final java.util.regex.Pattern DOMAIN_NAME;
+    field public static final java.util.regex.Pattern EMAIL_ADDRESS;
+    field public static final java.util.regex.Pattern IP_ADDRESS;
+    field public static final java.util.regex.Pattern WEB_URL;
+  }
+
+  public final class Pools {
+  }
+
+  public static interface Pools.Pool<T> {
+    method public T? acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SimplePool<T> implements androidx.core.util.Pools.Pool<T> {
+    ctor public Pools.SimplePool(int);
+    method public T! acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SynchronizedPool<T> extends androidx.core.util.Pools.SimplePool<T> {
+    ctor public Pools.SynchronizedPool(int);
+  }
+
+  public interface Predicate<T> {
+    method public default androidx.core.util.Predicate<T!>! and(androidx.core.util.Predicate<? super T>!);
+    method public static <T> androidx.core.util.Predicate<T!>! isEqual(Object!);
+    method public default androidx.core.util.Predicate<T!>! negate();
+    method public static <T> androidx.core.util.Predicate<T!>! not(androidx.core.util.Predicate<? super T>!);
+    method public default androidx.core.util.Predicate<T!>! or(androidx.core.util.Predicate<? super T>!);
+    method public boolean test(T!);
+  }
+
+  public final class SizeFCompat {
+    ctor public SizeFCompat(float, float);
+    method public float getHeight();
+    method public float getWidth();
+    method @RequiresApi(21) public android.util.SizeF toSizeF();
+    method @RequiresApi(21) public static androidx.core.util.SizeFCompat toSizeFCompat(android.util.SizeF);
+  }
+
+  public interface Supplier<T> {
+    method public T! get();
+  }
+
+}
+
+package androidx.core.view {
+
+  public class AccessibilityDelegateCompat {
+    ctor public AccessibilityDelegateCompat();
+    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public void sendAccessibilityEvent(android.view.View, int);
+    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+  }
+
+  public abstract class ActionProvider {
+    ctor public ActionProvider(android.content.Context);
+    method public android.content.Context getContext();
+    method public boolean hasSubMenu();
+    method public boolean isVisible();
+    method public abstract android.view.View onCreateActionView();
+    method public android.view.View onCreateActionView(android.view.MenuItem);
+    method public boolean onPerformDefaultAction();
+    method public void onPrepareSubMenu(android.view.SubMenu);
+    method public boolean overridesItemVisibility();
+    method public void refreshVisibility();
+    method public void setVisibilityListener(androidx.core.view.ActionProvider.VisibilityListener?);
+  }
+
+  public static interface ActionProvider.VisibilityListener {
+    method public void onActionProviderVisibilityChanged(boolean);
+  }
+
+  public final class ContentInfoCompat {
+    method public android.content.ClipData getClip();
+    method public android.os.Bundle? getExtras();
+    method public int getFlags();
+    method public android.net.Uri? getLinkUri();
+    method public int getSource();
+    method public android.util.Pair<androidx.core.view.ContentInfoCompat!,androidx.core.view.ContentInfoCompat!> partition(androidx.core.util.Predicate<android.content.ClipData.Item!>);
+    method @RequiresApi(31) public static android.util.Pair<android.view.ContentInfo!,android.view.ContentInfo!> partition(android.view.ContentInfo, java.util.function.Predicate<android.content.ClipData.Item!>);
+    method @RequiresApi(31) public android.view.ContentInfo toContentInfo();
+    method @RequiresApi(31) public static androidx.core.view.ContentInfoCompat toContentInfoCompat(android.view.ContentInfo);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_APP = 0; // 0x0
+    field public static final int SOURCE_AUTOFILL = 4; // 0x4
+    field public static final int SOURCE_CLIPBOARD = 1; // 0x1
+    field public static final int SOURCE_DRAG_AND_DROP = 3; // 0x3
+    field public static final int SOURCE_INPUT_METHOD = 2; // 0x2
+    field public static final int SOURCE_PROCESS_TEXT = 5; // 0x5
+  }
+
+  public static final class ContentInfoCompat.Builder {
+    ctor public ContentInfoCompat.Builder(androidx.core.view.ContentInfoCompat);
+    ctor public ContentInfoCompat.Builder(android.content.ClipData, int);
+    method public androidx.core.view.ContentInfoCompat build();
+    method public androidx.core.view.ContentInfoCompat.Builder setClip(android.content.ClipData);
+    method public androidx.core.view.ContentInfoCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.view.ContentInfoCompat.Builder setFlags(int);
+    method public androidx.core.view.ContentInfoCompat.Builder setLinkUri(android.net.Uri?);
+    method public androidx.core.view.ContentInfoCompat.Builder setSource(int);
+  }
+
+  public final class DisplayCompat {
+    method public static androidx.core.view.DisplayCompat.ModeCompat getMode(android.content.Context, android.view.Display);
+    method public static androidx.core.view.DisplayCompat.ModeCompat![] getSupportedModes(android.content.Context, android.view.Display);
+  }
+
+  public static final class DisplayCompat.ModeCompat {
+    method public int getPhysicalHeight();
+    method public int getPhysicalWidth();
+    method @Deprecated public boolean isNative();
+    method @RequiresApi(android.os.Build.VERSION_CODES.M) public android.view.Display.Mode? toMode();
+  }
+
+  public final class DisplayCutoutCompat {
+    ctor public DisplayCutoutCompat(android.graphics.Rect?, java.util.List<android.graphics.Rect!>?);
+    ctor public DisplayCutoutCompat(androidx.core.graphics.Insets, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, androidx.core.graphics.Insets);
+    method public java.util.List<android.graphics.Rect!> getBoundingRects();
+    method public int getSafeInsetBottom();
+    method public int getSafeInsetLeft();
+    method public int getSafeInsetRight();
+    method public int getSafeInsetTop();
+    method public androidx.core.graphics.Insets getWaterfallInsets();
+  }
+
+  public final class DragAndDropPermissionsCompat {
+    method public void release();
+  }
+
+  public class DragStartHelper {
+    ctor public DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener);
+    method public void attach();
+    method public void detach();
+    method public void getTouchPosition(android.graphics.Point);
+    method public boolean onLongClick(android.view.View);
+    method public boolean onTouch(android.view.View, android.view.MotionEvent);
+  }
+
+  public static interface DragStartHelper.OnDragStartListener {
+    method public boolean onDragStart(android.view.View, androidx.core.view.DragStartHelper);
+  }
+
+  public final class GestureDetectorCompat {
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler?);
+    method public boolean isLongpressEnabled();
+    method public boolean onTouchEvent(android.view.MotionEvent);
+    method public void setIsLongpressEnabled(boolean);
+    method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener?);
+  }
+
+  public final class GravityCompat {
+    method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
+    method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static int getAbsoluteGravity(int, int);
+    field public static final int END = 8388613; // 0x800005
+    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
+    field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
+    field public static final int START = 8388611; // 0x800003
+  }
+
+  public final class InputDeviceCompat {
+    field public static final int SOURCE_ANY = -256; // 0xffffff00
+    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
+    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
+    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
+    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
+    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
+    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
+    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
+    field public static final int SOURCE_DPAD = 513; // 0x201
+    field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
+    field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
+    field public static final int SOURCE_KEYBOARD = 257; // 0x101
+    field public static final int SOURCE_MOUSE = 8194; // 0x2002
+    field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
+    field public static final int SOURCE_STYLUS = 16386; // 0x4002
+    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
+    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
+    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
+    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
+    field public static final int SOURCE_UNKNOWN = 0; // 0x0
+  }
+
+  public final class LayoutInflaterCompat {
+    method @Deprecated public static androidx.core.view.LayoutInflaterFactory! getFactory(android.view.LayoutInflater!);
+    method @Deprecated public static void setFactory(android.view.LayoutInflater, androidx.core.view.LayoutInflaterFactory);
+    method public static void setFactory2(android.view.LayoutInflater, android.view.LayoutInflater.Factory2);
+  }
+
+  @Deprecated public interface LayoutInflaterFactory {
+    method @Deprecated public android.view.View! onCreateView(android.view.View!, String!, android.content.Context!, android.util.AttributeSet!);
+  }
+
+  public final class MarginLayoutParamsCompat {
+    method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
+    method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
+    method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
+  }
+
+  public final class MenuCompat {
+    method public static void setGroupDividerEnabled(android.view.Menu, boolean);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+  }
+
+  public interface MenuHost {
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void invalidateMenu();
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public class MenuHostHelper {
+    ctor public MenuHostHelper(Runnable);
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public void onPrepareMenu(android.view.Menu);
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public final class MenuItemCompat {
+    method @Deprecated public static boolean collapseActionView(android.view.MenuItem!);
+    method @Deprecated public static boolean expandActionView(android.view.MenuItem!);
+    method public static androidx.core.view.ActionProvider? getActionProvider(android.view.MenuItem);
+    method @Deprecated public static android.view.View! getActionView(android.view.MenuItem!);
+    method public static int getAlphabeticModifiers(android.view.MenuItem);
+    method public static CharSequence? getContentDescription(android.view.MenuItem);
+    method public static android.content.res.ColorStateList? getIconTintList(android.view.MenuItem);
+    method public static android.graphics.PorterDuff.Mode? getIconTintMode(android.view.MenuItem);
+    method public static int getNumericModifiers(android.view.MenuItem);
+    method public static CharSequence? getTooltipText(android.view.MenuItem);
+    method @Deprecated public static boolean isActionViewExpanded(android.view.MenuItem!);
+    method public static android.view.MenuItem? setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider?);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, android.view.View!);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, int);
+    method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
+    method public static void setContentDescription(android.view.MenuItem, CharSequence?);
+    method public static void setIconTintList(android.view.MenuItem, android.content.res.ColorStateList?);
+    method public static void setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode?);
+    method public static void setNumericShortcut(android.view.MenuItem, char, int);
+    method @Deprecated public static android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem!, androidx.core.view.MenuItemCompat.OnActionExpandListener!);
+    method public static void setShortcut(android.view.MenuItem, char, char, int, int);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+    method public static void setTooltipText(android.view.MenuItem, CharSequence?);
+    field @Deprecated public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+    field @Deprecated public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+    field @Deprecated public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+    field @Deprecated public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+    field @Deprecated public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+  }
+
+  @Deprecated public static interface MenuItemCompat.OnActionExpandListener {
+    method @Deprecated public boolean onMenuItemActionCollapse(android.view.MenuItem!);
+    method @Deprecated public boolean onMenuItemActionExpand(android.view.MenuItem!);
+  }
+
+  public interface MenuProvider {
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public default void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public default void onPrepareMenu(android.view.Menu);
+  }
+
+  public final class MotionEventCompat {
+    method @Deprecated public static int findPointerIndex(android.view.MotionEvent!, int);
+    method @Deprecated public static int getActionIndex(android.view.MotionEvent!);
+    method @Deprecated public static int getActionMasked(android.view.MotionEvent!);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int, int);
+    method @Deprecated public static int getButtonState(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerCount(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerId(android.view.MotionEvent!, int);
+    method @Deprecated public static int getSource(android.view.MotionEvent!);
+    method @Deprecated public static float getX(android.view.MotionEvent!, int);
+    method @Deprecated public static float getY(android.view.MotionEvent!, int);
+    method public static boolean isFromSource(android.view.MotionEvent, int);
+    field @Deprecated public static final int ACTION_HOVER_ENTER = 9; // 0x9
+    field @Deprecated public static final int ACTION_HOVER_EXIT = 10; // 0xa
+    field @Deprecated public static final int ACTION_HOVER_MOVE = 7; // 0x7
+    field @Deprecated public static final int ACTION_MASK = 255; // 0xff
+    field @Deprecated public static final int ACTION_POINTER_DOWN = 5; // 0x5
+    field @Deprecated public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
+    field @Deprecated public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+    field @Deprecated public static final int ACTION_POINTER_UP = 6; // 0x6
+    field @Deprecated public static final int ACTION_SCROLL = 8; // 0x8
+    field @Deprecated public static final int AXIS_BRAKE = 23; // 0x17
+    field @Deprecated public static final int AXIS_DISTANCE = 24; // 0x18
+    field @Deprecated public static final int AXIS_GAS = 22; // 0x16
+    field @Deprecated public static final int AXIS_GENERIC_1 = 32; // 0x20
+    field @Deprecated public static final int AXIS_GENERIC_10 = 41; // 0x29
+    field @Deprecated public static final int AXIS_GENERIC_11 = 42; // 0x2a
+    field @Deprecated public static final int AXIS_GENERIC_12 = 43; // 0x2b
+    field @Deprecated public static final int AXIS_GENERIC_13 = 44; // 0x2c
+    field @Deprecated public static final int AXIS_GENERIC_14 = 45; // 0x2d
+    field @Deprecated public static final int AXIS_GENERIC_15 = 46; // 0x2e
+    field @Deprecated public static final int AXIS_GENERIC_16 = 47; // 0x2f
+    field @Deprecated public static final int AXIS_GENERIC_2 = 33; // 0x21
+    field @Deprecated public static final int AXIS_GENERIC_3 = 34; // 0x22
+    field @Deprecated public static final int AXIS_GENERIC_4 = 35; // 0x23
+    field @Deprecated public static final int AXIS_GENERIC_5 = 36; // 0x24
+    field @Deprecated public static final int AXIS_GENERIC_6 = 37; // 0x25
+    field @Deprecated public static final int AXIS_GENERIC_7 = 38; // 0x26
+    field @Deprecated public static final int AXIS_GENERIC_8 = 39; // 0x27
+    field @Deprecated public static final int AXIS_GENERIC_9 = 40; // 0x28
+    field @Deprecated public static final int AXIS_HAT_X = 15; // 0xf
+    field @Deprecated public static final int AXIS_HAT_Y = 16; // 0x10
+    field @Deprecated public static final int AXIS_HSCROLL = 10; // 0xa
+    field @Deprecated public static final int AXIS_LTRIGGER = 17; // 0x11
+    field @Deprecated public static final int AXIS_ORIENTATION = 8; // 0x8
+    field @Deprecated public static final int AXIS_PRESSURE = 2; // 0x2
+    field public static final int AXIS_RELATIVE_X = 27; // 0x1b
+    field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
+    field @Deprecated public static final int AXIS_RTRIGGER = 18; // 0x12
+    field @Deprecated public static final int AXIS_RUDDER = 20; // 0x14
+    field @Deprecated public static final int AXIS_RX = 12; // 0xc
+    field @Deprecated public static final int AXIS_RY = 13; // 0xd
+    field @Deprecated public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SCROLL = 26; // 0x1a
+    field @Deprecated public static final int AXIS_SIZE = 3; // 0x3
+    field @Deprecated public static final int AXIS_THROTTLE = 19; // 0x13
+    field @Deprecated public static final int AXIS_TILT = 25; // 0x19
+    field @Deprecated public static final int AXIS_TOOL_MAJOR = 6; // 0x6
+    field @Deprecated public static final int AXIS_TOOL_MINOR = 7; // 0x7
+    field @Deprecated public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
+    field @Deprecated public static final int AXIS_TOUCH_MINOR = 5; // 0x5
+    field @Deprecated public static final int AXIS_VSCROLL = 9; // 0x9
+    field @Deprecated public static final int AXIS_WHEEL = 21; // 0x15
+    field @Deprecated public static final int AXIS_X = 0; // 0x0
+    field @Deprecated public static final int AXIS_Y = 1; // 0x1
+    field @Deprecated public static final int AXIS_Z = 11; // 0xb
+    field @Deprecated public static final int BUTTON_PRIMARY = 1; // 0x1
+  }
+
+  public interface NestedScrollingChild {
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean isNestedScrollingEnabled();
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(int);
+    method public void stopNestedScroll();
+  }
+
+  public interface NestedScrollingChild2 extends androidx.core.view.NestedScrollingChild {
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+  }
+
+  public interface NestedScrollingChild3 extends androidx.core.view.NestedScrollingChild2 {
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+  }
+
+  public class NestedScrollingChildHelper {
+    ctor public NestedScrollingChildHelper(android.view.View);
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean isNestedScrollingEnabled();
+    method public void onDetachedFromWindow();
+    method public void onStopNestedScroll(android.view.View);
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll();
+    method public void stopNestedScroll(int);
+  }
+
+  public interface NestedScrollingParent {
+    method public int getNestedScrollAxes();
+    method public boolean onNestedFling(android.view.View, float, float, boolean);
+    method public boolean onNestedPreFling(android.view.View, float, float);
+    method public void onNestedPreScroll(android.view.View, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int);
+    method public void onStopNestedScroll(android.view.View);
+  }
+
+  public interface NestedScrollingParent2 extends androidx.core.view.NestedScrollingParent {
+    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View, int);
+  }
+
+  public interface NestedScrollingParent3 extends androidx.core.view.NestedScrollingParent2 {
+    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+  }
+
+  public class NestedScrollingParentHelper {
+    ctor public NestedScrollingParentHelper(android.view.ViewGroup);
+    method public int getNestedScrollAxes();
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View);
+    method public void onStopNestedScroll(android.view.View, int);
+  }
+
+  public interface OnApplyWindowInsetsListener {
+    method public androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+  }
+
+  public interface OnReceiveContentListener {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+  }
+
+  public interface OnReceiveContentViewBehavior {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
+  }
+
+  public final class OneShotPreDrawListener implements android.view.View.OnAttachStateChangeListener android.view.ViewTreeObserver.OnPreDrawListener {
+    method public static androidx.core.view.OneShotPreDrawListener add(android.view.View, Runnable);
+    method public boolean onPreDraw();
+    method public void onViewAttachedToWindow(android.view.View);
+    method public void onViewDetachedFromWindow(android.view.View);
+    method public void removeListener();
+  }
+
+  public final class PointerIconCompat {
+    method public static androidx.core.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
+    method public static androidx.core.view.PointerIconCompat getSystemIcon(android.content.Context, int);
+    method public static androidx.core.view.PointerIconCompat load(android.content.res.Resources, int);
+    field public static final int TYPE_ALIAS = 1010; // 0x3f2
+    field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
+    field public static final int TYPE_ARROW = 1000; // 0x3e8
+    field public static final int TYPE_CELL = 1006; // 0x3ee
+    field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
+    field public static final int TYPE_COPY = 1011; // 0x3f3
+    field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
+    field public static final int TYPE_DEFAULT = 1000; // 0x3e8
+    field public static final int TYPE_GRAB = 1020; // 0x3fc
+    field public static final int TYPE_GRABBING = 1021; // 0x3fd
+    field public static final int TYPE_HAND = 1002; // 0x3ea
+    field public static final int TYPE_HELP = 1003; // 0x3eb
+    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
+    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
+    field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_TEXT = 1008; // 0x3f0
+    field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
+    field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
+    field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
+    field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
+    field public static final int TYPE_WAIT = 1004; // 0x3ec
+    field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
+    field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
+  }
+
+  public final class ScaleGestureDetectorCompat {
+    method @Deprecated public static boolean isQuickScaleEnabled(Object!);
+    method public static boolean isQuickScaleEnabled(android.view.ScaleGestureDetector);
+    method @Deprecated public static void setQuickScaleEnabled(Object!, boolean);
+    method public static void setQuickScaleEnabled(android.view.ScaleGestureDetector, boolean);
+  }
+
+  public interface ScrollingView {
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+  }
+
+  public interface TintableBackgroundView {
+    method public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  @Deprecated public final class VelocityTrackerCompat {
+    method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
+    method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
+  }
+
+  public class ViewCompat {
+    ctor @Deprecated protected ViewCompat();
+    method public static int addAccessibilityAction(android.view.View, CharSequence, androidx.core.view.accessibility.AccessibilityViewCommand);
+    method public static void addKeyboardNavigationClusters(android.view.View, java.util.Collection<android.view.View!>, int);
+    method public static void addOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static androidx.core.view.ViewPropertyAnimatorCompat animate(android.view.View);
+    method @Deprecated public static boolean canScrollHorizontally(android.view.View!, int);
+    method @Deprecated public static boolean canScrollVertically(android.view.View!, int);
+    method public static void cancelDragAndDrop(android.view.View);
+    method @Deprecated public static int combineMeasuredStates(int, int);
+    method public static androidx.core.view.WindowInsetsCompat computeSystemWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat, android.graphics.Rect);
+    method public static androidx.core.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method public static void dispatchFinishTemporaryDetach(android.view.View);
+    method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
+    method public static boolean dispatchNestedPreFling(android.view.View, float, float);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?, int);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?);
+    method public static void dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int, int[]);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int);
+    method public static void dispatchStartTemporaryDetach(android.view.View);
+    method public static void enableAccessibleClickableSpanSupport(android.view.View);
+    method public static int generateViewId();
+    method public static androidx.core.view.AccessibilityDelegateCompat? getAccessibilityDelegate(android.view.View);
+    method public static int getAccessibilityLiveRegion(android.view.View);
+    method public static androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method @UiThread public static CharSequence? getAccessibilityPaneTitle(android.view.View);
+    method @Deprecated public static float getAlpha(android.view.View!);
+    method public static android.content.res.ColorStateList? getBackgroundTintList(android.view.View);
+    method public static android.graphics.PorterDuff.Mode? getBackgroundTintMode(android.view.View);
+    method public static android.graphics.Rect? getClipBounds(android.view.View);
+    method public static android.view.Display? getDisplay(android.view.View);
+    method public static float getElevation(android.view.View);
+    method public static boolean getFitsSystemWindows(android.view.View);
+    method public static int getImportantForAccessibility(android.view.View);
+    method public static int getImportantForAutofill(android.view.View);
+    method public static int getLabelFor(android.view.View);
+    method @Deprecated public static int getLayerType(android.view.View!);
+    method public static int getLayoutDirection(android.view.View);
+    method @Deprecated public static android.graphics.Matrix? getMatrix(android.view.View!);
+    method @Deprecated public static int getMeasuredHeightAndState(android.view.View!);
+    method @Deprecated public static int getMeasuredState(android.view.View!);
+    method @Deprecated public static int getMeasuredWidthAndState(android.view.View!);
+    method public static int getMinimumHeight(android.view.View);
+    method public static int getMinimumWidth(android.view.View);
+    method public static int getNextClusterForwardId(android.view.View);
+    method public static String![]? getOnReceiveContentMimeTypes(android.view.View);
+    method @Deprecated public static int getOverScrollMode(android.view.View!);
+    method @Px public static int getPaddingEnd(android.view.View);
+    method @Px public static int getPaddingStart(android.view.View);
+    method public static android.view.ViewParent? getParentForAccessibility(android.view.View);
+    method @Deprecated public static float getPivotX(android.view.View!);
+    method @Deprecated public static float getPivotY(android.view.View!);
+    method public static androidx.core.view.WindowInsetsCompat? getRootWindowInsets(android.view.View);
+    method @Deprecated public static float getRotation(android.view.View!);
+    method @Deprecated public static float getRotationX(android.view.View!);
+    method @Deprecated public static float getRotationY(android.view.View!);
+    method @Deprecated public static float getScaleX(android.view.View!);
+    method @Deprecated public static float getScaleY(android.view.View!);
+    method public static int getScrollIndicators(android.view.View);
+    method @UiThread public static CharSequence? getStateDescription(android.view.View);
+    method public static java.util.List<android.graphics.Rect!> getSystemGestureExclusionRects(android.view.View);
+    method public static String? getTransitionName(android.view.View);
+    method @Deprecated public static float getTranslationX(android.view.View!);
+    method @Deprecated public static float getTranslationY(android.view.View!);
+    method public static float getTranslationZ(android.view.View);
+    method @Deprecated public static androidx.core.view.WindowInsetsControllerCompat? getWindowInsetsController(android.view.View);
+    method @Deprecated public static int getWindowSystemUiVisibility(android.view.View);
+    method @Deprecated public static float getX(android.view.View!);
+    method @Deprecated public static float getY(android.view.View!);
+    method public static float getZ(android.view.View);
+    method public static boolean hasAccessibilityDelegate(android.view.View);
+    method public static boolean hasExplicitFocusable(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View, int);
+    method public static boolean hasOnClickListeners(android.view.View);
+    method public static boolean hasOverlappingRendering(android.view.View);
+    method public static boolean hasTransientState(android.view.View);
+    method @UiThread public static boolean isAccessibilityHeading(android.view.View);
+    method public static boolean isAttachedToWindow(android.view.View);
+    method public static boolean isFocusedByDefault(android.view.View);
+    method public static boolean isImportantForAccessibility(android.view.View);
+    method public static boolean isImportantForAutofill(android.view.View);
+    method public static boolean isInLayout(android.view.View);
+    method public static boolean isKeyboardNavigationCluster(android.view.View);
+    method public static boolean isLaidOut(android.view.View);
+    method public static boolean isLayoutDirectionResolved(android.view.View);
+    method public static boolean isNestedScrollingEnabled(android.view.View);
+    method @Deprecated public static boolean isOpaque(android.view.View!);
+    method public static boolean isPaddingRelative(android.view.View);
+    method @UiThread public static boolean isScreenReaderFocusable(android.view.View);
+    method @Deprecated public static void jumpDrawablesToCurrentState(android.view.View!);
+    method public static android.view.View? keyboardNavigationClusterSearch(android.view.View, android.view.View?, int);
+    method public static void offsetLeftAndRight(android.view.View, int);
+    method public static void offsetTopAndBottom(android.view.View, int);
+    method public static androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method @Deprecated public static void onInitializeAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+    method public static void postInvalidateOnAnimation(android.view.View);
+    method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
+    method public static void postOnAnimation(android.view.View, Runnable);
+    method public static void postOnAnimationDelayed(android.view.View, Runnable, long);
+    method public static void removeAccessibilityAction(android.view.View, int);
+    method public static void removeOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static void replaceAccessibilityAction(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat, CharSequence?, androidx.core.view.accessibility.AccessibilityViewCommand?);
+    method public static void requestApplyInsets(android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.View, @IdRes int);
+    method @Deprecated public static int resolveSizeAndState(int, int, int);
+    method public static boolean restoreDefaultFocus(android.view.View);
+    method public static void saveAttributeDataForStyleable(android.view.View, android.content.Context, int[], android.util.AttributeSet?, android.content.res.TypedArray, int, int);
+    method public static void setAccessibilityDelegate(android.view.View, androidx.core.view.AccessibilityDelegateCompat?);
+    method @UiThread public static void setAccessibilityHeading(android.view.View, boolean);
+    method public static void setAccessibilityLiveRegion(android.view.View, int);
+    method @UiThread public static void setAccessibilityPaneTitle(android.view.View, CharSequence?);
+    method @Deprecated public static void setActivated(android.view.View!, boolean);
+    method @Deprecated public static void setAlpha(android.view.View!, @FloatRange(from=0.0, to=1.0) float);
+    method public static void setAutofillHints(android.view.View, java.lang.String!...);
+    method public static void setBackground(android.view.View, android.graphics.drawable.Drawable?);
+    method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList?);
+    method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode?);
+    method @Deprecated public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup!, boolean);
+    method public static void setClipBounds(android.view.View, android.graphics.Rect?);
+    method public static void setElevation(android.view.View, float);
+    method @Deprecated public static void setFitsSystemWindows(android.view.View!, boolean);
+    method public static void setFocusedByDefault(android.view.View, boolean);
+    method public static void setHasTransientState(android.view.View, boolean);
+    method @UiThread public static void setImportantForAccessibility(android.view.View, int);
+    method public static void setImportantForAutofill(android.view.View, int);
+    method public static void setKeyboardNavigationCluster(android.view.View, boolean);
+    method public static void setLabelFor(android.view.View, @IdRes int);
+    method public static void setLayerPaint(android.view.View, android.graphics.Paint?);
+    method @Deprecated public static void setLayerType(android.view.View!, int, android.graphics.Paint!);
+    method public static void setLayoutDirection(android.view.View, int);
+    method public static void setNestedScrollingEnabled(android.view.View, boolean);
+    method public static void setNextClusterForwardId(android.view.View, int);
+    method public static void setOnApplyWindowInsetsListener(android.view.View, androidx.core.view.OnApplyWindowInsetsListener?);
+    method public static void setOnReceiveContentListener(android.view.View, String![]?, androidx.core.view.OnReceiveContentListener?);
+    method @Deprecated public static void setOverScrollMode(android.view.View!, int);
+    method public static void setPaddingRelative(android.view.View, @Px int, @Px int, @Px int, @Px int);
+    method @Deprecated public static void setPivotX(android.view.View!, float);
+    method @Deprecated public static void setPivotY(android.view.View!, float);
+    method public static void setPointerIcon(android.view.View, androidx.core.view.PointerIconCompat?);
+    method @Deprecated public static void setRotation(android.view.View!, float);
+    method @Deprecated public static void setRotationX(android.view.View!, float);
+    method @Deprecated public static void setRotationY(android.view.View!, float);
+    method @Deprecated public static void setSaveFromParentEnabled(android.view.View!, boolean);
+    method @Deprecated public static void setScaleX(android.view.View!, float);
+    method @Deprecated public static void setScaleY(android.view.View!, float);
+    method @UiThread public static void setScreenReaderFocusable(android.view.View, boolean);
+    method public static void setScrollIndicators(android.view.View, int);
+    method public static void setScrollIndicators(android.view.View, int, int);
+    method @UiThread public static void setStateDescription(android.view.View, CharSequence?);
+    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect!>);
+    method public static void setTooltipText(android.view.View, CharSequence?);
+    method public static void setTransitionName(android.view.View, String?);
+    method @Deprecated public static void setTranslationX(android.view.View!, float);
+    method @Deprecated public static void setTranslationY(android.view.View!, float);
+    method public static void setTranslationZ(android.view.View, float);
+    method public static void setWindowInsetsAnimationCallback(android.view.View, androidx.core.view.WindowInsetsAnimationCompat.Callback?);
+    method @Deprecated public static void setX(android.view.View!, float);
+    method @Deprecated public static void setY(android.view.View!, float);
+    method public static void setZ(android.view.View, float);
+    method public static boolean startDragAndDrop(android.view.View, android.content.ClipData?, android.view.View.DragShadowBuilder, Object?, int);
+    method public static boolean startNestedScroll(android.view.View, int);
+    method public static boolean startNestedScroll(android.view.View, int, int);
+    method public static void stopNestedScroll(android.view.View);
+    method public static void stopNestedScroll(android.view.View, int);
+    method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
+    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
+    field @Deprecated public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
+    field @Deprecated public static final int LAYER_TYPE_NONE = 0; // 0x0
+    field @Deprecated public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
+    field @Deprecated public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+    field @Deprecated public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+    field @Deprecated public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
+    field @Deprecated public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+    field @Deprecated public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
+    field @Deprecated public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
+    field @Deprecated public static final int OVER_SCROLL_NEVER = 2; // 0x2
+    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+    field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+    field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+    field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
+    field public static final int TYPE_NON_TOUCH = 1; // 0x1
+    field public static final int TYPE_TOUCH = 0; // 0x0
+  }
+
+  public static interface ViewCompat.OnUnhandledKeyEventListenerCompat {
+    method public boolean onUnhandledKeyEvent(android.view.View, android.view.KeyEvent);
+  }
+
+  public final class ViewConfigurationCompat {
+    method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method public static int getScaledHoverSlop(android.view.ViewConfiguration);
+    method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
+    method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
+    method public static boolean shouldShowMenuShortcutsWhenKeyboardPresent(android.view.ViewConfiguration, android.content.Context);
+  }
+
+  public final class ViewGroupCompat {
+    method public static int getLayoutMode(android.view.ViewGroup);
+    method public static int getNestedScrollAxes(android.view.ViewGroup);
+    method public static boolean isTransitionGroup(android.view.ViewGroup);
+    method @Deprecated public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void setLayoutMode(android.view.ViewGroup, int);
+    method @Deprecated public static void setMotionEventSplittingEnabled(android.view.ViewGroup!, boolean);
+    method public static void setTransitionGroup(android.view.ViewGroup, boolean);
+    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
+  }
+
+  public final class ViewParentCompat {
+    method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
+    method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View, int);
+    method @Deprecated public static boolean requestSendAccessibilityEvent(android.view.ViewParent!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+  }
+
+  public final class ViewPropertyAnimatorCompat {
+    method public androidx.core.view.ViewPropertyAnimatorCompat alpha(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat alphaBy(float);
+    method public void cancel();
+    method public long getDuration();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public long getStartDelay();
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotation(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setDuration(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setListener(androidx.core.view.ViewPropertyAnimatorListener?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setStartDelay(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener?);
+    method public void start();
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZ(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withEndAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withLayer();
+    method public androidx.core.view.ViewPropertyAnimatorCompat withStartAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat x(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat xBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat y(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat yBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat z(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat zBy(float);
+  }
+
+  public interface ViewPropertyAnimatorListener {
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public class ViewPropertyAnimatorListenerAdapter implements androidx.core.view.ViewPropertyAnimatorListener {
+    ctor public ViewPropertyAnimatorListenerAdapter();
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public interface ViewPropertyAnimatorUpdateListener {
+    method public void onAnimationUpdate(android.view.View);
+  }
+
+  public final class WindowCompat {
+    method public static androidx.core.view.WindowInsetsControllerCompat getInsetsController(android.view.Window, android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
+    method public static void setDecorFitsSystemWindows(android.view.Window, boolean);
+    field public static final int FEATURE_ACTION_BAR = 8; // 0x8
+    field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+  }
+
+  public final class WindowInsetsAnimationCompat {
+    ctor public WindowInsetsAnimationCompat(int, android.view.animation.Interpolator?, long);
+    method @FloatRange(from=0.0f, to=1.0f) public float getAlpha();
+    method public long getDurationMillis();
+    method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
+    method public float getInterpolatedFraction();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public int getTypeMask();
+    method public void setAlpha(@FloatRange(from=0.0f, to=1.0f) float);
+    method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public static final class WindowInsetsAnimationCompat.BoundsCompat {
+    ctor public WindowInsetsAnimationCompat.BoundsCompat(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public androidx.core.graphics.Insets getLowerBound();
+    method public androidx.core.graphics.Insets getUpperBound();
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat inset(androidx.core.graphics.Insets);
+    method @RequiresApi(30) public android.view.WindowInsetsAnimation.Bounds toBounds();
+    method @RequiresApi(30) public static androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat toBoundsCompat(android.view.WindowInsetsAnimation.Bounds);
+  }
+
+  public abstract static class WindowInsetsAnimationCompat.Callback {
+    ctor public WindowInsetsAnimationCompat.Callback(int);
+    method public final int getDispatchMode();
+    method public void onEnd(androidx.core.view.WindowInsetsAnimationCompat);
+    method public void onPrepare(androidx.core.view.WindowInsetsAnimationCompat);
+    method public abstract androidx.core.view.WindowInsetsCompat onProgress(androidx.core.view.WindowInsetsCompat, java.util.List<androidx.core.view.WindowInsetsAnimationCompat!>);
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat onStart(androidx.core.view.WindowInsetsAnimationCompat, androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat);
+    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
+    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
+  }
+
+  public interface WindowInsetsAnimationControlListenerCompat {
+    method public void onCancelled(androidx.core.view.WindowInsetsAnimationControllerCompat?);
+    method public void onFinished(androidx.core.view.WindowInsetsAnimationControllerCompat);
+    method public void onReady(androidx.core.view.WindowInsetsAnimationControllerCompat, int);
+  }
+
+  public final class WindowInsetsAnimationControllerCompat {
+    method public void finish(boolean);
+    method public float getCurrentAlpha();
+    method @FloatRange(from=0.0f, to=1.0f) public float getCurrentFraction();
+    method public androidx.core.graphics.Insets getCurrentInsets();
+    method public androidx.core.graphics.Insets getHiddenStateInsets();
+    method public androidx.core.graphics.Insets getShownStateInsets();
+    method public int getTypes();
+    method public boolean isCancelled();
+    method public boolean isFinished();
+    method public boolean isReady();
+    method public void setInsetsAndAlpha(androidx.core.graphics.Insets?, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public class WindowInsetsCompat {
+    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat?);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeDisplayCutout();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeStableInsets();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeSystemWindowInsets();
+    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getInsets(int);
+    method public androidx.core.graphics.Insets getInsetsIgnoringVisibility(int);
+    method @Deprecated public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
+    method @Deprecated public int getStableInsetBottom();
+    method @Deprecated public int getStableInsetLeft();
+    method @Deprecated public int getStableInsetRight();
+    method @Deprecated public int getStableInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getStableInsets();
+    method @Deprecated public androidx.core.graphics.Insets getSystemGestureInsets();
+    method @Deprecated public int getSystemWindowInsetBottom();
+    method @Deprecated public int getSystemWindowInsetLeft();
+    method @Deprecated public int getSystemWindowInsetRight();
+    method @Deprecated public int getSystemWindowInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getSystemWindowInsets();
+    method @Deprecated public androidx.core.graphics.Insets getTappableElementInsets();
+    method public boolean hasInsets();
+    method @Deprecated public boolean hasStableInsets();
+    method @Deprecated public boolean hasSystemWindowInsets();
+    method public androidx.core.view.WindowInsetsCompat inset(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat inset(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+    method public boolean isConsumed();
+    method public boolean isRound();
+    method public boolean isVisible(int);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
+    method @RequiresApi(20) public android.view.WindowInsets? toWindowInsets();
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets);
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets, android.view.View?);
+    field public static final androidx.core.view.WindowInsetsCompat CONSUMED;
+  }
+
+  public static final class WindowInsetsCompat.Builder {
+    ctor public WindowInsetsCompat.Builder();
+    ctor public WindowInsetsCompat.Builder(androidx.core.view.WindowInsetsCompat);
+    method public androidx.core.view.WindowInsetsCompat build();
+    method public androidx.core.view.WindowInsetsCompat.Builder setDisplayCutout(androidx.core.view.DisplayCutoutCompat?);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsets(int, androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsetsIgnoringVisibility(int, androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setMandatorySystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setStableInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemWindowInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setTappableElementInsets(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setVisible(int, boolean);
+  }
+
+  public static final class WindowInsetsCompat.Type {
+    method public static int captionBar();
+    method public static int displayCutout();
+    method public static int ime();
+    method public static int mandatorySystemGestures();
+    method public static int navigationBars();
+    method public static int statusBars();
+    method public static int systemBars();
+    method public static int systemGestures();
+    method public static int tappableElement();
+  }
+
+  public final class WindowInsetsControllerCompat {
+    ctor public WindowInsetsControllerCompat(android.view.Window, android.view.View);
+    method public void addOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void controlWindowInsetsAnimation(int, long, android.view.animation.Interpolator?, android.os.CancellationSignal?, androidx.core.view.WindowInsetsAnimationControlListenerCompat);
+    method public int getSystemBarsBehavior();
+    method public void hide(int);
+    method public boolean isAppearanceLightNavigationBars();
+    method public boolean isAppearanceLightStatusBars();
+    method public void removeOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void setAppearanceLightNavigationBars(boolean);
+    method public void setAppearanceLightStatusBars(boolean);
+    method public void setSystemBarsBehavior(int);
+    method public void show(int);
+    method @Deprecated @RequiresApi(30) public static androidx.core.view.WindowInsetsControllerCompat toWindowInsetsControllerCompat(android.view.WindowInsetsController);
+    field public static final int BEHAVIOR_DEFAULT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_SWIPE = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0; // 0x0
+    field public static final int BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2; // 0x2
+  }
+
+  public static interface WindowInsetsControllerCompat.OnControllableInsetsChangedListener {
+    method public void onControllableInsetsChanged(androidx.core.view.WindowInsetsControllerCompat, int);
+  }
+
+}
+
+package androidx.core.view.accessibility {
+
+  public final class AccessibilityClickableSpanCompat extends android.text.style.ClickableSpan {
+    method public void onClick(android.view.View);
+  }
+
+  public final class AccessibilityEventCompat {
+    method @Deprecated public static void appendRecord(android.view.accessibility.AccessibilityEvent!, androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! asRecord(android.view.accessibility.AccessibilityEvent!);
+    method public static int getAction(android.view.accessibility.AccessibilityEvent);
+    method public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
+    method public static int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! getRecord(android.view.accessibility.AccessibilityEvent!, int);
+    method @Deprecated public static int getRecordCount(android.view.accessibility.AccessibilityEvent!);
+    method public static void setAction(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
+    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 512; // 0x200
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 256; // 0x100
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 128; // 0x80
+    field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
+    field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
+    field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
+    field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
+    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
+    field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+    field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
+    field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
+    field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
+    field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
+    field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
+    field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
+    field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
+    field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
+    field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+    field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
+    field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
+    field @Deprecated public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
+  }
+
+  public final class AccessibilityManagerCompat {
+    method @Deprecated public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!, int);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+  }
+
+  @Deprecated public static interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    method @Deprecated public void onAccessibilityStateChanged(boolean);
+  }
+
+  @Deprecated public abstract static class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    ctor @Deprecated public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
+  }
+
+  public static interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
+    method public void onTouchExplorationStateChanged(boolean);
+  }
+
+  public class AccessibilityNodeInfoCompat {
+    ctor @Deprecated public AccessibilityNodeInfoCompat(Object!);
+    method public void addAction(int);
+    method public void addAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public void addChild(android.view.View!);
+    method public void addChild(android.view.View!, int);
+    method public boolean canOpenPopup();
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByText(String!);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByViewId(String!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! findFocus(int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!>! getActionList();
+    method @Deprecated public int getActions();
+    method public java.util.List<java.lang.String!> getAvailableExtraData();
+    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
+    method public void getBoundsInScreen(android.graphics.Rect!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
+    method public int getChildCount();
+    method public CharSequence! getClassName();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! getCollectionInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! getCollectionItemInfo();
+    method public CharSequence! getContentDescription();
+    method public int getDrawingOrder();
+    method public CharSequence! getError();
+    method public android.view.accessibility.AccessibilityNodeInfo.ExtraRenderingInfo? getExtraRenderingInfo();
+    method public android.os.Bundle! getExtras();
+    method public CharSequence? getHintText();
+    method @Deprecated public Object! getInfo();
+    method public int getInputType();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabelFor();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
+    method public int getLiveRegion();
+    method public int getMaxTextLength();
+    method public long getMinDurationBetweenContentChangesMillis();
+    method public int getMovementGranularities();
+    method public CharSequence! getPackageName();
+    method public CharSequence? getPaneTitle();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getParent();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! getRangeInfo();
+    method public CharSequence? getRoleDescription();
+    method public CharSequence? getStateDescription();
+    method public CharSequence! getText();
+    method public int getTextSelectionEnd();
+    method public int getTextSelectionStart();
+    method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
+    method public String? getUniqueId();
+    method public String! getViewIdResourceName();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
+    method public int getWindowId();
+    method public boolean hasRequestInitialAccessibilityFocus();
+    method public boolean isAccessibilityFocused();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isClickable();
+    method public boolean isContentInvalid();
+    method public boolean isContextClickable();
+    method public boolean isDismissable();
+    method public boolean isEditable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public boolean isFocused();
+    method public boolean isHeading();
+    method public boolean isImportantForAccessibility();
+    method public boolean isLongClickable();
+    method public boolean isMultiLine();
+    method public boolean isPassword();
+    method public boolean isScreenReaderFocusable();
+    method public boolean isScrollable();
+    method public boolean isSelected();
+    method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
+    method public boolean isTextSelectable();
+    method public boolean isVisibleToUser();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat!);
+    method public boolean performAction(int);
+    method public boolean performAction(int, android.os.Bundle!);
+    method @Deprecated public void recycle();
+    method public boolean refresh();
+    method public boolean removeAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public boolean removeChild(android.view.View!);
+    method public boolean removeChild(android.view.View!, int);
+    method public void setAccessibilityFocused(boolean);
+    method public void setAvailableExtraData(java.util.List<java.lang.String!>);
+    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
+    method public void setBoundsInScreen(android.graphics.Rect!);
+    method public void setCanOpenPopup(boolean);
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setClassName(CharSequence!);
+    method public void setClickable(boolean);
+    method public void setCollectionInfo(Object!);
+    method public void setCollectionItemInfo(Object!);
+    method public void setContentDescription(CharSequence!);
+    method public void setContentInvalid(boolean);
+    method public void setContextClickable(boolean);
+    method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
+    method public void setEditable(boolean);
+    method public void setEnabled(boolean);
+    method public void setError(CharSequence!);
+    method public void setFocusable(boolean);
+    method public void setFocused(boolean);
+    method public void setHeading(boolean);
+    method public void setHintText(CharSequence?);
+    method public void setImportantForAccessibility(boolean);
+    method public void setInputType(int);
+    method public void setLabelFor(android.view.View!);
+    method public void setLabelFor(android.view.View!, int);
+    method public void setLabeledBy(android.view.View!);
+    method public void setLabeledBy(android.view.View!, int);
+    method public void setLiveRegion(int);
+    method public void setLongClickable(boolean);
+    method public void setMaxTextLength(int);
+    method public void setMinDurationBetweenContentChangesMillis(long);
+    method public void setMovementGranularities(int);
+    method public void setMultiLine(boolean);
+    method public void setPackageName(CharSequence!);
+    method public void setPaneTitle(CharSequence?);
+    method public void setParent(android.view.View!);
+    method public void setParent(android.view.View!, int);
+    method public void setPassword(boolean);
+    method public void setRangeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat!);
+    method public void setRequestInitialAccessibilityFocus(boolean);
+    method public void setRoleDescription(CharSequence?);
+    method public void setScreenReaderFocusable(boolean);
+    method public void setScrollable(boolean);
+    method public void setSelected(boolean);
+    method public void setShowingHintText(boolean);
+    method public void setSource(android.view.View!);
+    method public void setSource(android.view.View!, int);
+    method public void setStateDescription(CharSequence?);
+    method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
+    method public void setTextSelectable(boolean);
+    method public void setTextSelection(int, int);
+    method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
+    method public void setTraversalAfter(android.view.View!);
+    method public void setTraversalAfter(android.view.View!, int);
+    method public void setTraversalBefore(android.view.View!);
+    method public void setTraversalBefore(android.view.View!, int);
+    method public void setUniqueId(String?);
+    method public void setViewIdResourceName(String!);
+    method public void setVisibleToUser(boolean);
+    method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
+    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+    field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+    field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+    field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+    field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_X = "ACTION_ARGUMENT_MOVE_WINDOW_X";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y = "ACTION_ARGUMENT_MOVE_WINDOW_Y";
+    field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
+    field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
+    field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+    field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
+    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
+    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
+    field public static final int ACTION_CLICK = 16; // 0x10
+    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
+    field public static final int ACTION_COPY = 16384; // 0x4000
+    field public static final int ACTION_CUT = 65536; // 0x10000
+    field public static final int ACTION_DISMISS = 1048576; // 0x100000
+    field public static final int ACTION_EXPAND = 262144; // 0x40000
+    field public static final int ACTION_FOCUS = 1; // 0x1
+    field public static final int ACTION_LONG_CLICK = 32; // 0x20
+    field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
+    field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+    field public static final int ACTION_PASTE = 32768; // 0x8000
+    field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
+    field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
+    field public static final int ACTION_SELECT = 4; // 0x4
+    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH";
+    field public static final int EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_MAX_LENGTH = 20000; // 0x4e20
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX";
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY";
+    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+    field public static final int FOCUS_INPUT = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
+    field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
+    field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
+    field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
+  }
+
+  public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
+    ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!);
+    method public int getId();
+    method public CharSequence! getLabel();
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COLLAPSE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CONTEXT_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_CANCEL;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_DROP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_START;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_IME_ENTER;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_LONG_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PRESS_AND_HOLD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SELECT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_PROGRESS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_TEXT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_ON_SCREEN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SHOW_TEXT_SUGGESTIONS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_TOOLTIP;
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public int getSelectionMode();
+    method public boolean isHierarchical();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean, int);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
+    method public int getColumnIndex();
+    method public int getColumnSpan();
+    method public int getRowIndex();
+    method public int getRowSpan();
+    method @Deprecated public boolean isHeading();
+    method public boolean isSelected();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean, boolean);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean);
+  }
+
+  public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
+    method public float getCurrent();
+    method public float getMax();
+    method public float getMin();
+    method public int getType();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! obtain(int, float, float, float);
+    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+    field public static final int RANGE_TYPE_INT = 0; // 0x0
+    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+  }
+
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region!,android.view.View!>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
+  public class AccessibilityNodeProviderCompat {
+    ctor public AccessibilityNodeProviderCompat();
+    ctor public AccessibilityNodeProviderCompat(Object?);
+    method public void addExtraDataToAccessibilityNodeInfo(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, String, android.os.Bundle?);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? createAccessibilityNodeInfo(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>? findAccessibilityNodeInfosByText(String, int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? findFocus(int);
+    method public Object? getProvider();
+    method public boolean performAction(int, int, android.os.Bundle?);
+    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
+  }
+
+  public class AccessibilityRecordCompat {
+    ctor @Deprecated public AccessibilityRecordCompat(Object!);
+    method @Deprecated public boolean equals(Object?);
+    method @Deprecated public int getAddedCount();
+    method @Deprecated public CharSequence! getBeforeText();
+    method @Deprecated public CharSequence! getClassName();
+    method @Deprecated public CharSequence! getContentDescription();
+    method @Deprecated public int getCurrentItemIndex();
+    method @Deprecated public int getFromIndex();
+    method @Deprecated public Object! getImpl();
+    method @Deprecated public int getItemCount();
+    method @Deprecated public int getMaxScrollX();
+    method public static int getMaxScrollX(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public int getMaxScrollY();
+    method public static int getMaxScrollY(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public android.os.Parcelable! getParcelableData();
+    method @Deprecated public int getRemovedCount();
+    method @Deprecated public int getScrollX();
+    method @Deprecated public int getScrollY();
+    method @Deprecated public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getSource();
+    method @Deprecated public java.util.List<java.lang.CharSequence!>! getText();
+    method @Deprecated public int getToIndex();
+    method @Deprecated public int getWindowId();
+    method @Deprecated public int hashCode();
+    method @Deprecated public boolean isChecked();
+    method @Deprecated public boolean isEnabled();
+    method @Deprecated public boolean isFullScreen();
+    method @Deprecated public boolean isPassword();
+    method @Deprecated public boolean isScrollable();
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain(androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain();
+    method @Deprecated public void recycle();
+    method @Deprecated public void setAddedCount(int);
+    method @Deprecated public void setBeforeText(CharSequence!);
+    method @Deprecated public void setChecked(boolean);
+    method @Deprecated public void setClassName(CharSequence!);
+    method @Deprecated public void setContentDescription(CharSequence!);
+    method @Deprecated public void setCurrentItemIndex(int);
+    method @Deprecated public void setEnabled(boolean);
+    method @Deprecated public void setFromIndex(int);
+    method @Deprecated public void setFullScreen(boolean);
+    method @Deprecated public void setItemCount(int);
+    method @Deprecated public void setMaxScrollX(int);
+    method public static void setMaxScrollX(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setMaxScrollY(int);
+    method public static void setMaxScrollY(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setParcelableData(android.os.Parcelable!);
+    method @Deprecated public void setPassword(boolean);
+    method @Deprecated public void setRemovedCount(int);
+    method @Deprecated public void setScrollX(int);
+    method @Deprecated public void setScrollY(int);
+    method @Deprecated public void setScrollable(boolean);
+    method @Deprecated public void setSource(android.view.View!);
+    method @Deprecated public void setSource(android.view.View!, int);
+    method public static void setSource(android.view.accessibility.AccessibilityRecord, android.view.View?, int);
+    method @Deprecated public void setToIndex(int);
+  }
+
+  public interface AccessibilityViewCommand {
+    method public boolean perform(android.view.View, androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments?);
+  }
+
+  public abstract static class AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.CommandArguments();
+  }
+
+  public static final class AccessibilityViewCommand.MoveAtGranularityArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveAtGranularityArguments();
+    method public boolean getExtendSelection();
+    method public int getGranularity();
+  }
+
+  public static final class AccessibilityViewCommand.MoveHtmlArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveHtmlArguments();
+    method public String? getHTMLElement();
+  }
+
+  public static final class AccessibilityViewCommand.MoveWindowArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveWindowArguments();
+    method public int getX();
+    method public int getY();
+  }
+
+  public static final class AccessibilityViewCommand.ScrollToPositionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.ScrollToPositionArguments();
+    method public int getColumn();
+    method public int getRow();
+  }
+
+  public static final class AccessibilityViewCommand.SetProgressArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetProgressArguments();
+    method public float getProgress();
+  }
+
+  public static final class AccessibilityViewCommand.SetSelectionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetSelectionArguments();
+    method public int getEnd();
+    method public int getStart();
+  }
+
+  public static final class AccessibilityViewCommand.SetTextArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetTextArguments();
+    method public CharSequence? getText();
+  }
+
+  public class AccessibilityWindowInfoCompat {
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
+    method public int getChildCount();
+    method public int getDisplayId();
+    method public int getId();
+    method public int getLayer();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getParent();
+    method public void getRegionInScreen(android.graphics.Region);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getRoot();
+    method public CharSequence? getTitle();
+    method public int getType();
+    method public boolean isAccessibilityFocused();
+    method public boolean isActive();
+    method public boolean isFocused();
+    method public boolean isInPictureInPictureMode();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat?);
+    method @Deprecated public void recycle();
+    method public android.view.accessibility.AccessibilityWindowInfo? unwrap();
+    field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
+    field public static final int TYPE_APPLICATION = 1; // 0x1
+    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+    field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
+    field public static final int TYPE_SYSTEM = 3; // 0x3
+  }
+
+}
+
+package androidx.core.view.animation {
+
+  public final class PathInterpolatorCompat {
+    method public static android.view.animation.Interpolator create(android.graphics.Path);
+    method public static android.view.animation.Interpolator create(float, float);
+    method public static android.view.animation.Interpolator create(float, float, float, float);
+  }
+
+}
+
+package androidx.core.view.inputmethod {
+
+  public final class EditorInfoCompat {
+    ctor @Deprecated public EditorInfoCompat();
+    method public static String![] getContentMimeTypes(android.view.inputmethod.EditorInfo);
+    method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
+    method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
+    method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
+    method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
+    field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
+    field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
+  }
+
+  public final class InputConnectionCompat {
+    ctor @Deprecated public InputConnectionCompat();
+    method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+    method @Deprecated public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+    method public static android.view.inputmethod.InputConnection createWrapper(android.view.View, android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo);
+    field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
+  }
+
+  public static interface InputConnectionCompat.OnCommitContentListener {
+    method public boolean onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+  }
+
+  public final class InputContentInfoCompat {
+    ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri?);
+    method public android.net.Uri getContentUri();
+    method public android.content.ClipDescription getDescription();
+    method public android.net.Uri? getLinkUri();
+    method public void releasePermission();
+    method public void requestPermission();
+    method public Object? unwrap();
+    method public static androidx.core.view.inputmethod.InputContentInfoCompat? wrap(Object?);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
+    ctor public AutoScrollHelper(android.view.View);
+    method public abstract boolean canTargetScrollHorizontally(int);
+    method public abstract boolean canTargetScrollVertically(int);
+    method public boolean isEnabled();
+    method public boolean isExclusive();
+    method public boolean onTouch(android.view.View!, android.view.MotionEvent!);
+    method public abstract void scrollTargetBy(int, int);
+    method public androidx.core.widget.AutoScrollHelper setActivationDelay(int);
+    method public androidx.core.widget.AutoScrollHelper setEdgeType(int);
+    method public androidx.core.widget.AutoScrollHelper! setEnabled(boolean);
+    method public androidx.core.widget.AutoScrollHelper! setExclusive(boolean);
+    method public androidx.core.widget.AutoScrollHelper setMaximumEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMaximumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMinimumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRampDownDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRampUpDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRelativeEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRelativeVelocity(float, float);
+    field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
+    field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
+    field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
+    field public static final float NO_MAX = 3.4028235E38f;
+    field public static final float NO_MIN = 0.0f;
+    field public static final float RELATIVE_UNSPECIFIED = 0.0f;
+  }
+
+  public final class CheckedTextViewCompat {
+    method public static android.graphics.drawable.Drawable? getCheckMarkDrawable(android.widget.CheckedTextView);
+    method public static android.content.res.ColorStateList? getCheckMarkTintList(android.widget.CheckedTextView);
+    method public static android.graphics.PorterDuff.Mode? getCheckMarkTintMode(android.widget.CheckedTextView);
+    method public static void setCheckMarkTintList(android.widget.CheckedTextView, android.content.res.ColorStateList?);
+    method public static void setCheckMarkTintMode(android.widget.CheckedTextView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class CompoundButtonCompat {
+    method public static android.graphics.drawable.Drawable? getButtonDrawable(android.widget.CompoundButton);
+    method public static android.content.res.ColorStateList? getButtonTintList(android.widget.CompoundButton);
+    method public static android.graphics.PorterDuff.Mode? getButtonTintMode(android.widget.CompoundButton);
+    method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList?);
+    method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode?);
+  }
+
+  public class ContentLoadingProgressBar extends android.widget.ProgressBar {
+    ctor public ContentLoadingProgressBar(android.content.Context);
+    ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet?);
+    method public void hide();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void show();
+  }
+
+  public final class EdgeEffectCompat {
+    ctor @Deprecated public EdgeEffectCompat(android.content.Context!);
+    method public static android.widget.EdgeEffect create(android.content.Context, android.util.AttributeSet?);
+    method @Deprecated public boolean draw(android.graphics.Canvas!);
+    method @Deprecated public void finish();
+    method public static float getDistance(android.widget.EdgeEffect);
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean onAbsorb(int);
+    method @Deprecated public boolean onPull(float);
+    method @Deprecated public boolean onPull(float, float);
+    method public static void onPull(android.widget.EdgeEffect, float, float);
+    method public static float onPullDistance(android.widget.EdgeEffect, float, float);
+    method @Deprecated public boolean onRelease();
+    method @Deprecated public void setSize(int, int);
+  }
+
+  public class ImageViewCompat {
+    method public static android.content.res.ColorStateList? getImageTintList(android.widget.ImageView);
+    method public static android.graphics.PorterDuff.Mode? getImageTintMode(android.widget.ImageView);
+    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList?);
+    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class ListPopupWindowCompat {
+    method @Deprecated public static android.view.View.OnTouchListener! createDragToOpenListener(Object!, android.view.View!);
+    method public static android.view.View.OnTouchListener? createDragToOpenListener(android.widget.ListPopupWindow, android.view.View);
+  }
+
+  public class ListViewAutoScrollHelper extends androidx.core.widget.AutoScrollHelper {
+    ctor public ListViewAutoScrollHelper(android.widget.ListView);
+    method public boolean canTargetScrollHorizontally(int);
+    method public boolean canTargetScrollVertically(int);
+    method public void scrollTargetBy(int, int);
+  }
+
+  public final class ListViewCompat {
+    method public static boolean canScrollList(android.widget.ListView, int);
+    method public static void scrollListBy(android.widget.ListView, int);
+  }
+
+  public class NestedScrollView extends android.widget.FrameLayout implements androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent3 androidx.core.view.ScrollingView {
+    ctor public NestedScrollView(android.content.Context);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean arrowScroll(int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollRange();
+    method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public boolean executeKeyEvent(android.view.KeyEvent);
+    method public void fling(int);
+    method public boolean fullScroll(int);
+    method public int getMaxScrollAmount();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean isFillViewport();
+    method public boolean isSmoothScrollingEnabled();
+    method public void onAttachedToWindow();
+    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View, int);
+    method public boolean pageScroll(int);
+    method public void setFillViewport(boolean);
+    method public void setOnScrollChangeListener(androidx.core.widget.NestedScrollView.OnScrollChangeListener?);
+    method public void setSmoothScrollingEnabled(boolean);
+    method public final void smoothScrollBy(int, int);
+    method public final void smoothScrollBy(int, int, int);
+    method public final void smoothScrollTo(int, int);
+    method public final void smoothScrollTo(int, int, int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+  }
+
+  public static interface NestedScrollView.OnScrollChangeListener {
+    method public void onScrollChange(androidx.core.widget.NestedScrollView, int, int, int, int);
+  }
+
+  public final class PopupMenuCompat {
+    method public static android.view.View.OnTouchListener? getDragToOpenListener(Object);
+  }
+
+  public final class PopupWindowCompat {
+    method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+    method public static int getWindowLayoutType(android.widget.PopupWindow);
+    method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
+    method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
+  }
+
+  @Deprecated public final class ScrollerCompat {
+    method @Deprecated public void abortAnimation();
+    method @Deprecated public boolean computeScrollOffset();
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!);
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!, android.view.animation.Interpolator!);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int, int, int);
+    method @Deprecated public float getCurrVelocity();
+    method @Deprecated public int getCurrX();
+    method @Deprecated public int getCurrY();
+    method @Deprecated public int getFinalX();
+    method @Deprecated public int getFinalY();
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean isOverScrolled();
+    method @Deprecated public void notifyHorizontalEdgeReached(int, int, int);
+    method @Deprecated public void notifyVerticalEdgeReached(int, int, int);
+    method @Deprecated public boolean springBack(int, int, int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int, int);
+  }
+
+  public final class TextViewCompat {
+    method public static int getAutoSizeMaxTextSize(android.widget.TextView);
+    method public static int getAutoSizeMinTextSize(android.widget.TextView);
+    method public static int getAutoSizeStepGranularity(android.widget.TextView);
+    method public static int[] getAutoSizeTextAvailableSizes(android.widget.TextView);
+    method public static int getAutoSizeTextType(android.widget.TextView);
+    method public static android.content.res.ColorStateList? getCompoundDrawableTintList(android.widget.TextView);
+    method public static android.graphics.PorterDuff.Mode? getCompoundDrawableTintMode(android.widget.TextView);
+    method public static android.graphics.drawable.Drawable![] getCompoundDrawablesRelative(android.widget.TextView);
+    method public static int getFirstBaselineToTopHeight(android.widget.TextView);
+    method public static int getLastBaselineToBottomHeight(android.widget.TextView);
+    method public static int getMaxLines(android.widget.TextView);
+    method public static int getMinLines(android.widget.TextView);
+    method public static androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParams(android.widget.TextView);
+    method public static void setAutoSizeTextTypeUniformWithConfiguration(android.widget.TextView, int, int, int, int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeUniformWithPresetSizes(android.widget.TextView, int[], int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeWithDefaults(android.widget.TextView, int);
+    method public static void setCompoundDrawableTintList(android.widget.TextView, android.content.res.ColorStateList?);
+    method public static void setCompoundDrawableTintMode(android.widget.TextView, android.graphics.PorterDuff.Mode?);
+    method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, @DrawableRes int, @DrawableRes int, @DrawableRes int, @DrawableRes int);
+    method public static void setCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback);
+    method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
+    method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
+    method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
+    field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0
+    field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
+  }
+
+  public interface TintableCompoundButton {
+    method public android.content.res.ColorStateList? getSupportButtonTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface TintableCompoundDrawablesView {
+    method public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+}
+
diff --git a/core/core/api/public_plus_experimental_current.txt b/core/core/api/public_plus_experimental_current.txt
index 2b431b6..a1e0e3c 100644
--- a/core/core/api/public_plus_experimental_current.txt
+++ b/core/core/api/public_plus_experimental_current.txt
@@ -3259,7 +3259,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
     method public int getLiveRegion();
     method public int getMaxTextLength();
-    method public int getMinMillisBetweenContentChanges();
+    method public long getMinDurationBetweenContentChangesMillis();
     method public int getMovementGranularities();
     method public CharSequence! getPackageName();
     method public CharSequence? getPaneTitle();
@@ -3345,7 +3345,7 @@
     method public void setLiveRegion(int);
     method public void setLongClickable(boolean);
     method public void setMaxTextLength(int);
-    method public void setMinMillisBetweenContentChanges(int);
+    method public void setMinDurationBetweenContentChangesMillis(long);
     method public void setMovementGranularities(int);
     method public void setMultiLine(boolean);
     method public void setPackageName(CharSequence!);
diff --git a/core/core/api/res-1.10.0-beta01.txt b/core/core/api/res-1.10.0-beta01.txt
new file mode 100644
index 0000000..dd913d3
--- /dev/null
+++ b/core/core/api/res-1.10.0-beta01.txt
@@ -0,0 +1,21 @@
+attr alpha
+attr font
+attr fontProviderAuthority
+attr fontProviderCerts
+attr fontProviderFetchStrategy
+attr fontProviderFetchTimeout
+attr fontProviderPackage
+attr fontProviderQuery
+attr fontProviderSystemFontFamily
+attr fontStyle
+attr fontVariationSettings
+attr fontWeight
+attr lStar
+attr queryPatterns
+attr shortcutMatchRequired
+attr ttcIndex
+style TextAppearance_Compat_Notification
+style TextAppearance_Compat_Notification_Info
+style TextAppearance_Compat_Notification_Line2
+style TextAppearance_Compat_Notification_Time
+style TextAppearance_Compat_Notification_Title
diff --git a/core/core/api/restricted_1.10.0-beta01.txt b/core/core/api/restricted_1.10.0-beta01.txt
new file mode 100644
index 0000000..07bd416
--- /dev/null
+++ b/core/core/api/restricted_1.10.0-beta01.txt
@@ -0,0 +1,4438 @@
+// Signature format: 4.0
+package android.support.v4.os {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ResultReceiver implements android.os.Parcelable {
+    ctor public ResultReceiver(android.os.Handler!);
+    method public int describeContents();
+    method protected void onReceiveResult(int, android.os.Bundle!);
+    method public void send(int, android.os.Bundle!);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.os.ResultReceiver!>! CREATOR;
+  }
+
+}
+
+package androidx.core.accessibilityservice {
+
+  public final class AccessibilityServiceInfoCompat {
+    method public static String capabilityToString(int);
+    method public static String feedbackTypeToString(int);
+    method public static String? flagToString(int);
+    method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static String? loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
+    field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
+    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+    field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
+    field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
+    field public static final int FEEDBACK_BRAILLE = 32; // 0x20
+    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
+    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+  }
+
+}
+
+package androidx.core.app {
+
+  public class ActivityCompat extends androidx.core.content.ContextCompat {
+    ctor protected ActivityCompat();
+    method public static void finishAffinity(android.app.Activity);
+    method public static void finishAfterTransition(android.app.Activity);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.ActivityCompat.PermissionCompatDelegate? getPermissionCompatDelegate();
+    method public static android.net.Uri? getReferrer(android.app.Activity);
+    method @Deprecated public static boolean invalidateOptionsMenu(android.app.Activity!);
+    method public static boolean isLaunchedFromBubble(android.app.Activity);
+    method public static void postponeEnterTransition(android.app.Activity);
+    method public static void recreate(android.app.Activity);
+    method public static androidx.core.view.DragAndDropPermissionsCompat? requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
+    method public static void requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+    method public static <T extends android.view.View> T requireViewById(android.app.Activity, @IdRes int);
+    method public static void setEnterSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setExitSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setLocusContext(android.app.Activity, androidx.core.content.LocusIdCompat?, android.os.Bundle?);
+    method public static void setPermissionCompatDelegate(androidx.core.app.ActivityCompat.PermissionCompatDelegate?);
+    method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, String);
+    method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle?);
+    method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public static void startPostponedEnterTransition(android.app.Activity);
+  }
+
+  public static interface ActivityCompat.OnRequestPermissionsResultCallback {
+    method public void onRequestPermissionsResult(int, String![], int[]);
+  }
+
+  public static interface ActivityCompat.PermissionCompatDelegate {
+    method public boolean onActivityResult(android.app.Activity, @IntRange(from=0) int, int, android.content.Intent?);
+    method public boolean requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface ActivityCompat.RequestPermissionsRequestCodeValidator {
+    method public void validateRequestPermissionsRequestCode(int);
+  }
+
+  public final class ActivityManagerCompat {
+    method public static boolean isLowRamDevice(android.app.ActivityManager);
+  }
+
+  public class ActivityOptionsCompat {
+    ctor protected ActivityOptionsCompat();
+    method public android.graphics.Rect? getLaunchBounds();
+    method public static androidx.core.app.ActivityOptionsCompat makeBasic();
+    method public static androidx.core.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, String);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, androidx.core.util.Pair<android.view.View!,java.lang.String!>!...);
+    method public static androidx.core.app.ActivityOptionsCompat makeTaskLaunchBehind();
+    method public static androidx.core.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
+    method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public androidx.core.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect?);
+    method public android.os.Bundle? toBundle();
+    method public void update(androidx.core.app.ActivityOptionsCompat);
+    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+    field public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
+  }
+
+  public final class AlarmManagerCompat {
+    method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
+    method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+  }
+
+  @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory {
+    ctor public AppComponentFactory();
+    method public final android.app.Activity instantiateActivity(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Activity instantiateActivityCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Application instantiateApplication(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Application instantiateApplicationCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.ContentProvider instantiateProvider(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.ContentProvider instantiateProviderCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.BroadcastReceiver instantiateReceiver(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.BroadcastReceiver instantiateReceiverCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Service instantiateService(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Service instantiateServiceCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+  }
+
+  public class AppLaunchChecker {
+    ctor @Deprecated public AppLaunchChecker();
+    method public static boolean hasStartedFromLauncher(android.content.Context);
+    method public static void onActivityCreate(android.app.Activity);
+  }
+
+  public final class AppOpsManagerCompat {
+    method public static int checkOrNoteProxyOp(android.content.Context, int, String, String);
+    method public static int noteOp(android.content.Context, String, int, String);
+    method public static int noteOpNoThrow(android.content.Context, String, int, String);
+    method public static int noteProxyOp(android.content.Context, String, String);
+    method public static int noteProxyOpNoThrow(android.content.Context, String, String);
+    method public static String? permissionToOp(String);
+    field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_DEFAULT = 3; // 0x3
+    field public static final int MODE_ERRORED = 2; // 0x2
+    field public static final int MODE_IGNORED = 1; // 0x1
+  }
+
+  public final class BundleCompat {
+    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ComponentActivity extends android.app.Activity implements androidx.core.view.KeyEventDispatcher.Component androidx.lifecycle.LifecycleOwner {
+    ctor public ComponentActivity();
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public <T extends androidx.core.app.ComponentActivity.ExtraData> T! getExtraData(Class<T!>!);
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void putExtraData(androidx.core.app.ComponentActivity.ExtraData!);
+    method protected final boolean shouldDumpInternalState(String![]?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean superDispatchKeyEvent(android.view.KeyEvent);
+  }
+
+  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class ComponentActivity.ExtraData {
+    ctor @Deprecated public ComponentActivity.ExtraData();
+  }
+
+  @RequiresApi(api=28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class CoreComponentFactory extends android.app.AppComponentFactory {
+    ctor public CoreComponentFactory();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface CoreComponentFactory.CompatWrapped {
+    method public Object! getWrapper();
+  }
+
+  public class DialogCompat {
+    method public static android.view.View requireViewById(android.app.Dialog, int);
+  }
+
+  public class FrameMetricsAggregator {
+    ctor public FrameMetricsAggregator();
+    ctor public FrameMetricsAggregator(@androidx.core.app.FrameMetricsAggregator.MetricType int);
+    method public void add(android.app.Activity);
+    method public android.util.SparseIntArray![]? getMetrics();
+    method public android.util.SparseIntArray![]? remove(android.app.Activity);
+    method public android.util.SparseIntArray![]? reset();
+    method public android.util.SparseIntArray![]? stop();
+    field public static final int ANIMATION_DURATION = 256; // 0x100
+    field public static final int ANIMATION_INDEX = 8; // 0x8
+    field public static final int COMMAND_DURATION = 32; // 0x20
+    field public static final int COMMAND_INDEX = 5; // 0x5
+    field public static final int DELAY_DURATION = 128; // 0x80
+    field public static final int DELAY_INDEX = 7; // 0x7
+    field public static final int DRAW_DURATION = 8; // 0x8
+    field public static final int DRAW_INDEX = 3; // 0x3
+    field public static final int EVERY_DURATION = 511; // 0x1ff
+    field public static final int INPUT_DURATION = 2; // 0x2
+    field public static final int INPUT_INDEX = 1; // 0x1
+    field public static final int LAYOUT_MEASURE_DURATION = 4; // 0x4
+    field public static final int LAYOUT_MEASURE_INDEX = 2; // 0x2
+    field public static final int SWAP_DURATION = 64; // 0x40
+    field public static final int SWAP_INDEX = 6; // 0x6
+    field public static final int SYNC_DURATION = 16; // 0x10
+    field public static final int SYNC_INDEX = 4; // 0x4
+    field public static final int TOTAL_DURATION = 1; // 0x1
+    field public static final int TOTAL_INDEX = 0; // 0x0
+  }
+
+  @IntDef(flag=true, value={androidx.core.app.FrameMetricsAggregator.TOTAL_DURATION, androidx.core.app.FrameMetricsAggregator.INPUT_DURATION, androidx.core.app.FrameMetricsAggregator.LAYOUT_MEASURE_DURATION, androidx.core.app.FrameMetricsAggregator.DRAW_DURATION, androidx.core.app.FrameMetricsAggregator.SYNC_DURATION, androidx.core.app.FrameMetricsAggregator.COMMAND_DURATION, androidx.core.app.FrameMetricsAggregator.SWAP_DURATION, androidx.core.app.FrameMetricsAggregator.DELAY_DURATION, androidx.core.app.FrameMetricsAggregator.ANIMATION_DURATION, androidx.core.app.FrameMetricsAggregator.EVERY_DURATION}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface FrameMetricsAggregator.MetricType {
+  }
+
+  @Deprecated public abstract class JobIntentService extends android.app.Service {
+    ctor @Deprecated public JobIntentService();
+    method @Deprecated public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
+    method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
+    method @Deprecated public boolean isStopped();
+    method @Deprecated public android.os.IBinder! onBind(android.content.Intent);
+    method @Deprecated protected abstract void onHandleWork(android.content.Intent);
+    method @Deprecated public boolean onStopCurrentWork();
+    method @Deprecated public void setInterruptIfStopped(boolean);
+  }
+
+  public final class LocaleManagerCompat {
+    method @AnyThread public static androidx.core.os.LocaleListCompat getSystemLocales(android.content.Context);
+  }
+
+  public final class MultiWindowModeChangedInfo {
+    ctor public MultiWindowModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public MultiWindowModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInMultiWindowMode();
+  }
+
+  public final class NavUtils {
+    method public static android.content.Intent? getParentActivityIntent(android.app.Activity);
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static String? getParentActivityName(android.app.Activity);
+    method public static String? getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void navigateUpFromSameTask(android.app.Activity);
+    method public static void navigateUpTo(android.app.Activity, android.content.Intent);
+    method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
+    field public static final String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface NotificationBuilderWithBuilderAccessor {
+    method public android.app.Notification.Builder! getBuilder();
+  }
+
+  public class NotificationChannelCompat {
+    method public boolean canBubble();
+    method public boolean canBypassDnd();
+    method public boolean canShowBadge();
+    method public android.media.AudioAttributes? getAudioAttributes();
+    method public String? getConversationId();
+    method public String? getDescription();
+    method public String? getGroup();
+    method public String getId();
+    method public int getImportance();
+    method public int getLightColor();
+    method @androidx.core.app.NotificationCompat.NotificationVisibility public int getLockscreenVisibility();
+    method public CharSequence? getName();
+    method public String? getParentChannelId();
+    method public android.net.Uri? getSound();
+    method public long[]? getVibrationPattern();
+    method public boolean isImportantConversation();
+    method public boolean shouldShowLights();
+    method public boolean shouldVibrate();
+    method public androidx.core.app.NotificationChannelCompat.Builder toBuilder();
+    field public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
+  }
+
+  public static class NotificationChannelCompat.Builder {
+    ctor public NotificationChannelCompat.Builder(String, int);
+    method public androidx.core.app.NotificationChannelCompat build();
+    method public androidx.core.app.NotificationChannelCompat.Builder setConversationId(String, String);
+    method public androidx.core.app.NotificationChannelCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setImportance(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightColor(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightsEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setName(CharSequence?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setShowBadge(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setSound(android.net.Uri?, android.media.AudioAttributes?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationPattern(long[]?);
+  }
+
+  public class NotificationChannelGroupCompat {
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getChannels();
+    method public String? getDescription();
+    method public String getId();
+    method public CharSequence? getName();
+    method public boolean isBlocked();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder toBuilder();
+  }
+
+  public static class NotificationChannelGroupCompat.Builder {
+    ctor public NotificationChannelGroupCompat.Builder(String);
+    method public androidx.core.app.NotificationChannelGroupCompat build();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setName(CharSequence?);
+  }
+
+  public class NotificationCompat {
+    ctor @Deprecated public NotificationCompat();
+    method public static androidx.core.app.NotificationCompat.Action? getAction(android.app.Notification, int);
+    method public static int getActionCount(android.app.Notification);
+    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification);
+    method public static boolean getAutoCancel(android.app.Notification);
+    method public static int getBadgeIconType(android.app.Notification);
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata(android.app.Notification);
+    method public static String? getCategory(android.app.Notification);
+    method public static String? getChannelId(android.app.Notification);
+    method public static int getColor(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentInfo(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentText(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentTitle(android.app.Notification);
+    method public static android.os.Bundle? getExtras(android.app.Notification);
+    method public static String? getGroup(android.app.Notification);
+    method @androidx.core.app.NotificationCompat.GroupAlertBehavior public static int getGroupAlertBehavior(android.app.Notification);
+    method @RequiresApi(21) public static java.util.List<androidx.core.app.NotificationCompat.Action!> getInvisibleActions(android.app.Notification);
+    method public static boolean getLocalOnly(android.app.Notification);
+    method public static androidx.core.content.LocusIdCompat? getLocusId(android.app.Notification);
+    method public static boolean getOngoing(android.app.Notification);
+    method public static boolean getOnlyAlertOnce(android.app.Notification);
+    method public static java.util.List<androidx.core.app.Person!> getPeople(android.app.Notification);
+    method public static android.app.Notification? getPublicVersion(android.app.Notification);
+    method public static CharSequence? getSettingsText(android.app.Notification);
+    method public static String? getShortcutId(android.app.Notification);
+    method @RequiresApi(19) public static boolean getShowWhen(android.app.Notification);
+    method public static String? getSortKey(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getSubText(android.app.Notification);
+    method public static long getTimeoutAfter(android.app.Notification);
+    method @RequiresApi(19) public static boolean getUsesChronometer(android.app.Notification);
+    method @androidx.core.app.NotificationCompat.NotificationVisibility public static int getVisibility(android.app.Notification);
+    method public static boolean isGroupSummary(android.app.Notification);
+    field public static final int BADGE_ICON_LARGE = 2; // 0x2
+    field public static final int BADGE_ICON_NONE = 0; // 0x0
+    field public static final int BADGE_ICON_SMALL = 1; // 0x1
+    field public static final String CATEGORY_ALARM = "alarm";
+    field public static final String CATEGORY_CALL = "call";
+    field public static final String CATEGORY_EMAIL = "email";
+    field public static final String CATEGORY_ERROR = "err";
+    field public static final String CATEGORY_EVENT = "event";
+    field public static final String CATEGORY_LOCATION_SHARING = "location_sharing";
+    field public static final String CATEGORY_MESSAGE = "msg";
+    field public static final String CATEGORY_MISSED_CALL = "missed_call";
+    field public static final String CATEGORY_NAVIGATION = "navigation";
+    field public static final String CATEGORY_PROGRESS = "progress";
+    field public static final String CATEGORY_PROMO = "promo";
+    field public static final String CATEGORY_RECOMMENDATION = "recommendation";
+    field public static final String CATEGORY_REMINDER = "reminder";
+    field public static final String CATEGORY_SERVICE = "service";
+    field public static final String CATEGORY_SOCIAL = "social";
+    field public static final String CATEGORY_STATUS = "status";
+    field public static final String CATEGORY_STOPWATCH = "stopwatch";
+    field public static final String CATEGORY_SYSTEM = "sys";
+    field public static final String CATEGORY_TRANSPORT = "transport";
+    field public static final String CATEGORY_WORKOUT = "workout";
+    field @ColorInt public static final int COLOR_DEFAULT = 0; // 0x0
+    field public static final int DEFAULT_ALL = -1; // 0xffffffff
+    field public static final int DEFAULT_LIGHTS = 4; // 0x4
+    field public static final int DEFAULT_SOUND = 1; // 0x1
+    field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final String EXTRA_ANSWER_COLOR = "android.answerColor";
+    field public static final String EXTRA_ANSWER_INTENT = "android.answerIntent";
+    field public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
+    field public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+    field public static final String EXTRA_BIG_TEXT = "android.bigText";
+    field public static final String EXTRA_CALL_IS_VIDEO = "android.callIsVideo";
+    field public static final String EXTRA_CALL_PERSON = "android.callPerson";
+    field public static final String EXTRA_CALL_PERSON_COMPAT = "android.callPersonCompat";
+    field public static final String EXTRA_CALL_TYPE = "android.callType";
+    field public static final String EXTRA_CHANNEL_GROUP_ID = "android.intent.extra.CHANNEL_GROUP_ID";
+    field public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
+    field public static final String EXTRA_CHRONOMETER_COUNT_DOWN = "android.chronometerCountDown";
+    field public static final String EXTRA_COLORIZED = "android.colorized";
+    field public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final String EXTRA_COMPAT_TEMPLATE = "androidx.core.app.extra.COMPAT_TEMPLATE";
+    field public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
+    field public static final String EXTRA_DECLINE_COLOR = "android.declineColor";
+    field public static final String EXTRA_DECLINE_INTENT = "android.declineIntent";
+    field public static final String EXTRA_HANG_UP_INTENT = "android.hangUpIntent";
+    field public static final String EXTRA_HIDDEN_CONVERSATION_TITLE = "android.hiddenConversationTitle";
+    field public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic";
+    field public static final String EXTRA_INFO_TEXT = "android.infoText";
+    field public static final String EXTRA_IS_GROUP_CONVERSATION = "android.isGroupConversation";
+    field public static final String EXTRA_LARGE_ICON = "android.largeIcon";
+    field public static final String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+    field public static final String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final String EXTRA_MESSAGES = "android.messages";
+    field public static final String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
+    field public static final String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+    field public static final String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
+    field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
+    field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
+    field public static final String EXTRA_PICTURE = "android.picture";
+    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
+    field public static final String EXTRA_PICTURE_ICON = "android.pictureIcon";
+    field public static final String EXTRA_PROGRESS = "android.progress";
+    field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+    field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
+    field public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+    field public static final String EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED = "android.showBigPictureWhenCollapsed";
+    field public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+    field public static final String EXTRA_SHOW_WHEN = "android.showWhen";
+    field public static final String EXTRA_SMALL_ICON = "android.icon";
+    field public static final String EXTRA_SUB_TEXT = "android.subText";
+    field public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
+    field public static final String EXTRA_TEMPLATE = "android.template";
+    field public static final String EXTRA_TEXT = "android.text";
+    field public static final String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final String EXTRA_TITLE = "android.title";
+    field public static final String EXTRA_TITLE_BIG = "android.title.big";
+    field public static final String EXTRA_VERIFICATION_ICON = "android.verificationIcon";
+    field public static final String EXTRA_VERIFICATION_ICON_COMPAT = "android.verificationIconCompat";
+    field public static final String EXTRA_VERIFICATION_TEXT = "android.verificationText";
+    field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
+    field public static final int FLAG_BUBBLE = 4096; // 0x1000
+    field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
+    field @Deprecated public static final int FLAG_HIGH_PRIORITY = 128; // 0x80
+    field public static final int FLAG_INSISTENT = 4; // 0x4
+    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
+    field public static final int FLAG_NO_CLEAR = 32; // 0x20
+    field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
+    field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
+    field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int FOREGROUND_SERVICE_DEFAULT = 0; // 0x0
+    field public static final int FOREGROUND_SERVICE_DEFERRED = 2; // 0x2
+    field public static final int FOREGROUND_SERVICE_IMMEDIATE = 1; // 0x1
+    field public static final int GROUP_ALERT_ALL = 0; // 0x0
+    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
+    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
+    field public static final String GROUP_KEY_SILENT = "silent";
+    field public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int MAX_ACTION_BUTTONS = 3; // 0x3
+    field public static final int PRIORITY_DEFAULT = 0; // 0x0
+    field public static final int PRIORITY_HIGH = 1; // 0x1
+    field public static final int PRIORITY_LOW = -1; // 0xffffffff
+    field public static final int PRIORITY_MAX = 2; // 0x2
+    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
+    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
+  }
+
+  public static class NotificationCompat.Action {
+    ctor public NotificationCompat.Action(int, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    method public android.app.PendingIntent? getActionIntent();
+    method public boolean getAllowGeneratedReplies();
+    method public androidx.core.app.RemoteInput![]? getDataOnlyRemoteInputs();
+    method public android.os.Bundle getExtras();
+    method @Deprecated public int getIcon();
+    method public androidx.core.graphics.drawable.IconCompat? getIconCompat();
+    method public androidx.core.app.RemoteInput![]? getRemoteInputs();
+    method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
+    method public boolean getShowsUserInterface();
+    method public CharSequence? getTitle();
+    method public boolean isAuthenticationRequired();
+    method public boolean isContextual();
+    field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
+    field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
+    field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
+    field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2
+    field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3
+    field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6
+    field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0
+    field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1
+    field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9
+    field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8
+    field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7
+    field public android.app.PendingIntent? actionIntent;
+    field @Deprecated public int icon;
+    field public CharSequence! title;
+  }
+
+  public static final class NotificationCompat.Action.Builder {
+    ctor public NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action.Builder(int, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action.Builder(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Action.Builder addRemoteInput(androidx.core.app.RemoteInput?);
+    method public androidx.core.app.NotificationCompat.Action build();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Extender);
+    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.NotificationCompat.Action.Builder fromAndroidAction(android.app.Notification.Action);
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setAuthenticationRequired(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
+    method public androidx.core.app.NotificationCompat.Action.Builder setShowsUserInterface(boolean);
+  }
+
+  public static interface NotificationCompat.Action.Extender {
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_NONE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_REPLY, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_UNREAD, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_DELETE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_ARCHIVE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_UNMUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_UP, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_DOWN, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_CALL}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.Action.SemanticAction {
+  }
+
+  public static final class NotificationCompat.Action.WearableExtender implements androidx.core.app.NotificationCompat.Action.Extender {
+    ctor public NotificationCompat.Action.WearableExtender();
+    ctor public NotificationCompat.Action.WearableExtender(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+    method @Deprecated public CharSequence? getCancelLabel();
+    method @Deprecated public CharSequence? getConfirmLabel();
+    method public boolean getHintDisplayActionInline();
+    method public boolean getHintLaunchesActivity();
+    method @Deprecated public CharSequence? getInProgressLabel();
+    method public boolean isAvailableOffline();
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setCancelLabel(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setConfirmLabel(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setInProgressLabel(CharSequence?);
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.BADGE_ICON_NONE, androidx.core.app.NotificationCompat.BADGE_ICON_SMALL, androidx.core.app.NotificationCompat.BADGE_ICON_LARGE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.BadgeIconType {
+  }
+
+  public static class NotificationCompat.BigPictureStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigPictureStyle();
+    ctor public NotificationCompat.BigPictureStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap?);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.drawable.Icon?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.drawable.IconCompat? getPictureIcon(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setBigContentTitle(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle setContentDescription(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setSummaryText(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle showBigPictureWhenCollapsed(boolean);
+  }
+
+  public static class NotificationCompat.BigTextStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigTextStyle();
+    ctor public NotificationCompat.BigTextStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle bigText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setSummaryText(CharSequence?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata {
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? fromPlatform(android.app.Notification.BubbleMetadata?);
+    method public boolean getAutoExpandBubble();
+    method public android.app.PendingIntent? getDeleteIntent();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getDesiredHeight();
+    method @DimenRes public int getDesiredHeightResId();
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public android.app.PendingIntent? getIntent();
+    method public String? getShortcutId();
+    method public boolean isNotificationSuppressed();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setFlags(int);
+    method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata.Builder {
+    ctor @Deprecated public NotificationCompat.BubbleMetadata.Builder();
+    ctor @RequiresApi(30) public NotificationCompat.BubbleMetadata.Builder(String);
+    ctor public NotificationCompat.BubbleMetadata.Builder(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata build();
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setAutoExpandBubble(boolean);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setSuppressNotification(boolean);
+  }
+
+  public static class NotificationCompat.Builder {
+    ctor @RequiresApi(19) public NotificationCompat.Builder(android.content.Context, android.app.Notification);
+    ctor public NotificationCompat.Builder(android.content.Context, String);
+    ctor @Deprecated public NotificationCompat.Builder(android.content.Context);
+    method public androidx.core.app.NotificationCompat.Builder addAction(int, CharSequence?, android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder addAction(androidx.core.app.NotificationCompat.Action?);
+    method public androidx.core.app.NotificationCompat.Builder addExtras(android.os.Bundle?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(int, CharSequence?, android.app.PendingIntent?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(androidx.core.app.NotificationCompat.Action?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder addPerson(String?);
+    method public androidx.core.app.NotificationCompat.Builder addPerson(androidx.core.app.Person?);
+    method public android.app.Notification build();
+    method public androidx.core.app.NotificationCompat.Builder clearActions();
+    method public androidx.core.app.NotificationCompat.Builder clearInvisibleActions();
+    method public androidx.core.app.NotificationCompat.Builder clearPeople();
+    method public android.widget.RemoteViews? createBigContentView();
+    method public android.widget.RemoteViews? createContentView();
+    method public android.widget.RemoteViews? createHeadsUpContentView();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Extender);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! getBigContentView();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata();
+    method @ColorInt @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getColor();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! getContentView();
+    method public android.os.Bundle getExtras();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getForegroundServiceBehavior();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! getHeadsUpContentView();
+    method @Deprecated public android.app.Notification getNotification();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getPriority();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public long getWhenIfShowing();
+    method protected static CharSequence? limitCharSequenceLength(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setAutoCancel(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setBadgeIconType(@androidx.core.app.NotificationCompat.BadgeIconType int);
+    method public androidx.core.app.NotificationCompat.Builder setBubbleMetadata(androidx.core.app.NotificationCompat.BubbleMetadata?);
+    method public androidx.core.app.NotificationCompat.Builder setCategory(String?);
+    method public androidx.core.app.NotificationCompat.Builder setChannelId(String);
+    method @RequiresApi(24) public androidx.core.app.NotificationCompat.Builder setChronometerCountDown(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.Builder setColorized(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setContent(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setContentInfo(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setContentText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setDefaults(int);
+    method public androidx.core.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Builder setForegroundServiceBehavior(@androidx.core.app.NotificationCompat.ServiceNotificationBehavior int);
+    method public androidx.core.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent?, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationCompat.Builder setGroupAlertBehavior(@androidx.core.app.NotificationCompat.GroupAlertBehavior int);
+    method public androidx.core.app.NotificationCompat.Builder setGroupSummary(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.Builder setLights(@ColorInt int, int, int);
+    method public androidx.core.app.NotificationCompat.Builder setLocalOnly(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setNotificationSilent();
+    method public androidx.core.app.NotificationCompat.Builder setNumber(int);
+    method public androidx.core.app.NotificationCompat.Builder setOngoing(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPriority(int);
+    method public androidx.core.app.NotificationCompat.Builder setProgress(int, int, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPublicVersion(android.app.Notification?);
+    method public androidx.core.app.NotificationCompat.Builder setRemoteInputHistory(CharSequence![]?);
+    method public androidx.core.app.NotificationCompat.Builder setSettingsText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutId(String?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutInfo(androidx.core.content.pm.ShortcutInfoCompat?);
+    method public androidx.core.app.NotificationCompat.Builder setShowWhen(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setSilent(boolean);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.Builder setSmallIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int, int);
+    method public androidx.core.app.NotificationCompat.Builder setSortKey(String?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?, @androidx.core.app.NotificationCompat.StreamType int);
+    method public androidx.core.app.NotificationCompat.Builder setStyle(androidx.core.app.NotificationCompat.Style?);
+    method public androidx.core.app.NotificationCompat.Builder setSubText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?, android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setTimeoutAfter(long);
+    method public androidx.core.app.NotificationCompat.Builder setUsesChronometer(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setVibrate(long[]?);
+    method public androidx.core.app.NotificationCompat.Builder setVisibility(@androidx.core.app.NotificationCompat.NotificationVisibility int);
+    method public androidx.core.app.NotificationCompat.Builder setWhen(long);
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public java.util.ArrayList<androidx.core.app.NotificationCompat.Action!>! mActions;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.Context! mContext;
+    field @Deprecated public java.util.ArrayList<java.lang.String!>! mPeople;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public java.util.ArrayList<androidx.core.app.Person!> mPersonList;
+  }
+
+  public static class NotificationCompat.CallStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.CallStyle();
+    ctor public NotificationCompat.CallStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public static androidx.core.app.NotificationCompat.CallStyle forIncomingCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forOngoingCall(androidx.core.app.Person, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forScreeningCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method @RequiresApi(20) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public java.util.ArrayList<androidx.core.app.NotificationCompat.Action!> getActionsListWithSystemActions();
+    method public androidx.core.app.NotificationCompat.CallStyle setAnswerButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setDeclineButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setIsVideo(boolean);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationText(CharSequence?);
+    field public static final int CALL_TYPE_INCOMING = 1; // 0x1
+    field public static final int CALL_TYPE_ONGOING = 2; // 0x2
+    field public static final int CALL_TYPE_SCREENING = 3; // 0x3
+    field public static final int CALL_TYPE_UNKNOWN = 0; // 0x0
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.CallStyle.CALL_TYPE_UNKNOWN, androidx.core.app.NotificationCompat.CallStyle.CALL_TYPE_INCOMING, androidx.core.app.NotificationCompat.CallStyle.CALL_TYPE_ONGOING, androidx.core.app.NotificationCompat.CallStyle.CALL_TYPE_SCREENING}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.CallStyle.CallType {
+  }
+
+  public static final class NotificationCompat.CarExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.CarExtender();
+    ctor public NotificationCompat.CarExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method @ColorInt public int getColor();
+    method public android.graphics.Bitmap? getLargeIcon();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation? getUnreadConversation();
+    method public androidx.core.app.NotificationCompat.CarExtender setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation?);
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation {
+    method @Deprecated public long getLatestTimestamp();
+    method @Deprecated public String![]? getMessages();
+    method @Deprecated public String? getParticipant();
+    method @Deprecated public String![]? getParticipants();
+    method @Deprecated public android.app.PendingIntent? getReadPendingIntent();
+    method @Deprecated public androidx.core.app.RemoteInput? getRemoteInput();
+    method @Deprecated public android.app.PendingIntent? getReplyPendingIntent();
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+    ctor @Deprecated public NotificationCompat.CarExtender.UnreadConversation.Builder(String);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation build();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent?, androidx.core.app.RemoteInput?);
+  }
+
+  public static class NotificationCompat.DecoratedCustomViewStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.DecoratedCustomViewStyle();
+  }
+
+  public static interface NotificationCompat.Extender {
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.GROUP_ALERT_ALL, androidx.core.app.NotificationCompat.GROUP_ALERT_SUMMARY, androidx.core.app.NotificationCompat.GROUP_ALERT_CHILDREN}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.GroupAlertBehavior {
+  }
+
+  public static class NotificationCompat.InboxStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.InboxStyle();
+    ctor public NotificationCompat.InboxStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.InboxStyle addLine(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setSummaryText(CharSequence?);
+  }
+
+  public static class NotificationCompat.MessagingStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor @Deprecated public NotificationCompat.MessagingStyle(CharSequence);
+    ctor public NotificationCompat.MessagingStyle(androidx.core.app.Person);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addHistoricMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method @Deprecated public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, CharSequence?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, androidx.core.app.Person?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method public static androidx.core.app.NotificationCompat.MessagingStyle? extractMessagingStyleFromNotification(android.app.Notification);
+    method public CharSequence? getConversationTitle();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getHistoricMessages();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getMessages();
+    method public androidx.core.app.Person getUser();
+    method @Deprecated public CharSequence? getUserDisplayName();
+    method public boolean isGroupConversation();
+    method public androidx.core.app.NotificationCompat.MessagingStyle setConversationTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle setGroupConversation(boolean);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class NotificationCompat.MessagingStyle.Message {
+    ctor public NotificationCompat.MessagingStyle.Message(CharSequence?, long, androidx.core.app.Person?);
+    ctor @Deprecated public NotificationCompat.MessagingStyle.Message(CharSequence?, long, CharSequence?);
+    method public String? getDataMimeType();
+    method public android.net.Uri? getDataUri();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.Person? getPerson();
+    method @Deprecated public CharSequence? getSender();
+    method public CharSequence? getText();
+    method public long getTimestamp();
+    method public androidx.core.app.NotificationCompat.MessagingStyle.Message setData(String?, android.net.Uri?);
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC, androidx.core.app.NotificationCompat.VISIBILITY_PRIVATE, androidx.core.app.NotificationCompat.VISIBILITY_SECRET}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.NotificationVisibility {
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_DEFAULT, androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE, androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_DEFERRED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.ServiceNotificationBehavior {
+  }
+
+  @IntDef({android.media.AudioManager.STREAM_VOICE_CALL, android.media.AudioManager.STREAM_SYSTEM, android.media.AudioManager.STREAM_RING, android.media.AudioManager.STREAM_MUSIC, android.media.AudioManager.STREAM_ALARM, android.media.AudioManager.STREAM_NOTIFICATION, android.media.AudioManager.STREAM_DTMF, android.media.AudioManager.STREAM_ACCESSIBILITY}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.StreamType {
+  }
+
+  public abstract static class NotificationCompat.Style {
+    ctor public NotificationCompat.Style();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addCompatExtras(android.os.Bundle);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void apply(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews applyStandardTemplate(boolean, int, boolean);
+    method public android.app.Notification? build();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void buildIntoRemoteViews(android.widget.RemoteViews!, android.widget.RemoteViews!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected void clearCompatExtraKeys(android.os.Bundle);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.Bitmap! createColoredBitmap(int, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean displayCustomViewInline();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.NotificationCompat.Style? extractStyleFromNotification(android.app.Notification);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected String? getClassName();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! makeBigContentView(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! makeContentView(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! makeHeadsUpContentView(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected void restoreFromCompatExtras(android.os.Bundle);
+    method public void setBuilder(androidx.core.app.NotificationCompat.Builder?);
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected androidx.core.app.NotificationCompat.Builder! mBuilder;
+  }
+
+  public static final class NotificationCompat.WearableExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.WearableExtender();
+    ctor public NotificationCompat.WearableExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.WearableExtender addAction(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.WearableExtender addActions(java.util.List<androidx.core.app.NotificationCompat.Action!>);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification!>);
+    method public androidx.core.app.NotificationCompat.WearableExtender clearActions();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender clearPages();
+    method public androidx.core.app.NotificationCompat.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method public java.util.List<androidx.core.app.NotificationCompat.Action!> getActions();
+    method @Deprecated public android.graphics.Bitmap? getBackground();
+    method public String? getBridgeTag();
+    method public int getContentAction();
+    method @Deprecated public int getContentIcon();
+    method @Deprecated public int getContentIconGravity();
+    method public boolean getContentIntentAvailableOffline();
+    method @Deprecated public int getCustomContentHeight();
+    method @Deprecated public int getCustomSizePreset();
+    method public String? getDismissalId();
+    method @Deprecated public android.app.PendingIntent? getDisplayIntent();
+    method @Deprecated public int getGravity();
+    method @Deprecated public boolean getHintAmbientBigPicture();
+    method @Deprecated public boolean getHintAvoidBackgroundClipping();
+    method public boolean getHintContentIntentLaunchesActivity();
+    method @Deprecated public boolean getHintHideIcon();
+    method @Deprecated public int getHintScreenTimeout();
+    method @Deprecated public boolean getHintShowBackgroundOnly();
+    method @Deprecated public java.util.List<android.app.Notification!> getPages();
+    method public boolean getStartScrollBottom();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setBridgeTag(String?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentAction(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIcon(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIconGravity(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setDismissalId(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setGravity(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
+    field @Deprecated public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+    field @Deprecated public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
+    field @Deprecated public static final int SIZE_DEFAULT = 0; // 0x0
+    field @Deprecated public static final int SIZE_FULL_SCREEN = 5; // 0x5
+    field @Deprecated public static final int SIZE_LARGE = 4; // 0x4
+    field @Deprecated public static final int SIZE_MEDIUM = 3; // 0x3
+    field @Deprecated public static final int SIZE_SMALL = 2; // 0x2
+    field @Deprecated public static final int SIZE_XSMALL = 1; // 0x1
+    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+  }
+
+  public final class NotificationCompatExtras {
+    field public static final String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
+    field public static final String EXTRA_GROUP_KEY = "android.support.groupKey";
+    field public static final String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
+    field public static final String EXTRA_LOCAL_ONLY = "android.support.localOnly";
+    field public static final String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+    field public static final String EXTRA_SORT_KEY = "android.support.sortKey";
+  }
+
+  public abstract class NotificationCompatSideChannelService extends android.app.Service {
+    ctor public NotificationCompatSideChannelService();
+    method public abstract void cancel(String!, int, String!);
+    method public abstract void cancelAll(String!);
+    method public abstract void notify(String!, int, String!, android.app.Notification!);
+    method public android.os.IBinder! onBind(android.content.Intent!);
+  }
+
+  public final class NotificationManagerCompat {
+    method public boolean areNotificationsEnabled();
+    method public void cancel(int);
+    method public void cancel(String?, int);
+    method public void cancelAll();
+    method public void createNotificationChannel(android.app.NotificationChannel);
+    method public void createNotificationChannel(androidx.core.app.NotificationChannelCompat);
+    method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
+    method public void createNotificationChannelGroup(androidx.core.app.NotificationChannelGroupCompat);
+    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
+    method public void createNotificationChannelGroupsCompat(java.util.List<androidx.core.app.NotificationChannelGroupCompat!>);
+    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
+    method public void createNotificationChannelsCompat(java.util.List<androidx.core.app.NotificationChannelCompat!>);
+    method public void deleteNotificationChannel(String);
+    method public void deleteNotificationChannelGroup(String);
+    method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
+    method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
+    method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
+    method public int getImportance();
+    method public android.app.NotificationChannel? getNotificationChannel(String);
+    method public android.app.NotificationChannel? getNotificationChannel(String, String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String, String);
+    method public android.app.NotificationChannelGroup? getNotificationChannelGroup(String);
+    method public androidx.core.app.NotificationChannelGroupCompat? getNotificationChannelGroupCompat(String);
+    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
+    method public java.util.List<androidx.core.app.NotificationChannelGroupCompat!> getNotificationChannelGroupsCompat();
+    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getNotificationChannelsCompat();
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(int, android.app.Notification);
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(String?, int, android.app.Notification);
+    field public static final String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
+    field public static final String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
+    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
+    field public static final int IMPORTANCE_HIGH = 4; // 0x4
+    field public static final int IMPORTANCE_LOW = 2; // 0x2
+    field public static final int IMPORTANCE_MAX = 5; // 0x5
+    field public static final int IMPORTANCE_MIN = 1; // 0x1
+    field public static final int IMPORTANCE_NONE = 0; // 0x0
+    field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+  }
+
+  public interface OnMultiWindowModeChangedProvider {
+    method public void addOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+    method public void removeOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+  }
+
+  public interface OnNewIntentProvider {
+    method public void addOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+    method public void removeOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+  }
+
+  public interface OnPictureInPictureModeChangedProvider {
+    method public void addOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+    method public void removeOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+  }
+
+  public final class PendingIntentCompat {
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getBroadcast(android.content.Context, int, android.content.Intent, int, boolean);
+    method @RequiresApi(26) public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int, boolean);
+  }
+
+  public class Person {
+    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.Person fromAndroidPerson(android.app.Person);
+    method public static androidx.core.app.Person fromBundle(android.os.Bundle);
+    method @RequiresApi(22) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.Person fromPersistableBundle(android.os.PersistableBundle);
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public String? getKey();
+    method public CharSequence? getName();
+    method public String? getUri();
+    method public boolean isBot();
+    method public boolean isImportant();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public String resolveToLegacyUri();
+    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.app.Person toAndroidPerson();
+    method public androidx.core.app.Person.Builder toBuilder();
+    method public android.os.Bundle toBundle();
+    method @RequiresApi(22) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.os.PersistableBundle toPersistableBundle();
+  }
+
+  public static class Person.Builder {
+    ctor public Person.Builder();
+    method public androidx.core.app.Person build();
+    method public androidx.core.app.Person.Builder setBot(boolean);
+    method public androidx.core.app.Person.Builder setIcon(androidx.core.graphics.drawable.IconCompat?);
+    method public androidx.core.app.Person.Builder setImportant(boolean);
+    method public androidx.core.app.Person.Builder setKey(String?);
+    method public androidx.core.app.Person.Builder setName(CharSequence?);
+    method public androidx.core.app.Person.Builder setUri(String?);
+  }
+
+  public final class PictureInPictureModeChangedInfo {
+    ctor public PictureInPictureModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public PictureInPictureModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInPictureInPictureMode();
+  }
+
+  @androidx.versionedparcelable.VersionedParcelize(jetifyAs="android.support.v4.app.RemoteActionCompat") public final class RemoteActionCompat implements androidx.versionedparcelable.VersionedParcelable {
+    ctor public RemoteActionCompat(androidx.core.graphics.drawable.IconCompat, CharSequence, CharSequence, android.app.PendingIntent);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public RemoteActionCompat();
+    ctor public RemoteActionCompat(androidx.core.app.RemoteActionCompat);
+    method @RequiresApi(26) public static androidx.core.app.RemoteActionCompat createFromRemoteAction(android.app.RemoteAction);
+    method public android.app.PendingIntent getActionIntent();
+    method public CharSequence getContentDescription();
+    method public androidx.core.graphics.drawable.IconCompat getIcon();
+    method public CharSequence getTitle();
+    method public boolean isEnabled();
+    method public void setEnabled(boolean);
+    method public void setShouldShowIcon(boolean);
+    method public boolean shouldShowIcon();
+    method @RequiresApi(26) public android.app.RemoteAction toRemoteAction();
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(4) public android.app.PendingIntent mActionIntent;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(3) public CharSequence mContentDescription;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(5) public boolean mEnabled;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(1) public androidx.core.graphics.drawable.IconCompat mIcon;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(6) public boolean mShouldShowIcon;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(2) public CharSequence mTitle;
+  }
+
+  public final class RemoteInput {
+    method public static void addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String!,android.net.Uri!>);
+    method public static void addResultsToIntent(androidx.core.app.RemoteInput![], android.content.Intent, android.os.Bundle);
+    method public boolean getAllowFreeFormInput();
+    method public java.util.Set<java.lang.String!>? getAllowedDataTypes();
+    method public CharSequence![]? getChoices();
+    method public static java.util.Map<java.lang.String!,android.net.Uri!>? getDataResultsFromIntent(android.content.Intent, String);
+    method @androidx.core.app.RemoteInput.EditChoicesBeforeSending public int getEditChoicesBeforeSending();
+    method public android.os.Bundle getExtras();
+    method public CharSequence? getLabel();
+    method public String getResultKey();
+    method public static android.os.Bundle? getResultsFromIntent(android.content.Intent);
+    method @androidx.core.app.RemoteInput.Source public static int getResultsSource(android.content.Intent);
+    method public boolean isDataOnly();
+    method public static void setResultsSource(android.content.Intent, @androidx.core.app.RemoteInput.Source int);
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
+    field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+    field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+    field public static final int SOURCE_CHOICE = 1; // 0x1
+    field public static final int SOURCE_FREE_FORM_INPUT = 0; // 0x0
+  }
+
+  public static final class RemoteInput.Builder {
+    ctor public RemoteInput.Builder(String);
+    method public androidx.core.app.RemoteInput.Builder addExtras(android.os.Bundle);
+    method public androidx.core.app.RemoteInput build();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
+    method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+    method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence![]?);
+    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(@androidx.core.app.RemoteInput.EditChoicesBeforeSending int);
+    method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
+  }
+
+  @IntDef({androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_DISABLED, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_ENABLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.EditChoicesBeforeSending {
+  }
+
+  @IntDef({androidx.core.app.RemoteInput.SOURCE_FREE_FORM_INPUT, androidx.core.app.RemoteInput.SOURCE_CHOICE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.Source {
+  }
+
+  public final class ServiceCompat {
+    method public static void stopForeground(android.app.Service, @androidx.core.app.ServiceCompat.StopForegroundFlags int);
+    field public static final int START_STICKY = 1; // 0x1
+    field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+    field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
+  }
+
+  @IntDef(flag=true, value={androidx.core.app.ServiceCompat.STOP_FOREGROUND_REMOVE, androidx.core.app.ServiceCompat.STOP_FOREGROUND_DETACH}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ServiceCompat.StopForegroundFlags {
+  }
+
+  public final class ShareCompat {
+    method @Deprecated public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
+    method @Deprecated public static void configureMenuItem(android.view.Menu, @IdRes int, androidx.core.app.ShareCompat.IntentBuilder);
+    method public static android.content.ComponentName? getCallingActivity(android.app.Activity);
+    method public static String? getCallingPackage(android.app.Activity);
+    field public static final String EXTRA_CALLING_ACTIVITY = "androidx.core.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_ACTIVITY_INTEROP = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_PACKAGE = "androidx.core.app.EXTRA_CALLING_PACKAGE";
+    field public static final String EXTRA_CALLING_PACKAGE_INTEROP = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
+  }
+
+  public static class ShareCompat.IntentBuilder {
+    ctor public ShareCompat.IntentBuilder(android.content.Context);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
+    method public android.content.Intent createChooserIntent();
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentBuilder from(android.app.Activity);
+    method public android.content.Intent getIntent();
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(@StringRes int);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailBcc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailCc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailTo(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setHtmlText(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setStream(android.net.Uri?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setSubject(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setText(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setType(String?);
+    method public void startChooser();
+  }
+
+  public static class ShareCompat.IntentReader {
+    ctor public ShareCompat.IntentReader(android.app.Activity);
+    ctor public ShareCompat.IntentReader(android.content.Context, android.content.Intent);
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentReader from(android.app.Activity);
+    method public android.content.ComponentName? getCallingActivity();
+    method public android.graphics.drawable.Drawable? getCallingActivityIcon();
+    method public android.graphics.drawable.Drawable? getCallingApplicationIcon();
+    method public CharSequence? getCallingApplicationLabel();
+    method public String? getCallingPackage();
+    method public String![]? getEmailBcc();
+    method public String![]? getEmailCc();
+    method public String![]? getEmailTo();
+    method public String? getHtmlText();
+    method public android.net.Uri? getStream();
+    method public android.net.Uri? getStream(int);
+    method public int getStreamCount();
+    method public String? getSubject();
+    method public CharSequence? getText();
+    method public String? getType();
+    method public boolean isMultipleShare();
+    method public boolean isShareIntent();
+    method public boolean isSingleShare();
+  }
+
+  public abstract class SharedElementCallback {
+    ctor public SharedElementCallback();
+    method public android.os.Parcelable! onCaptureSharedElementSnapshot(android.view.View!, android.graphics.Matrix!, android.graphics.RectF!);
+    method public android.view.View! onCreateSnapshotView(android.content.Context!, android.os.Parcelable!);
+    method public void onMapSharedElements(java.util.List<java.lang.String!>!, java.util.Map<java.lang.String!,android.view.View!>!);
+    method public void onRejectSharedElements(java.util.List<android.view.View!>!);
+    method public void onSharedElementEnd(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementStart(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementsArrived(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener!);
+  }
+
+  public static interface SharedElementCallback.OnSharedElementsReadyListener {
+    method public void onSharedElementsReady();
+  }
+
+  public final class TaskStackBuilder implements java.lang.Iterable<android.content.Intent> {
+    method public androidx.core.app.TaskStackBuilder addNextIntent(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.app.Activity);
+    method public androidx.core.app.TaskStackBuilder addParentStack(Class<?>);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.content.ComponentName);
+    method public static androidx.core.app.TaskStackBuilder create(android.content.Context);
+    method public android.content.Intent? editIntentAt(int);
+    method @Deprecated public static androidx.core.app.TaskStackBuilder! from(android.content.Context!);
+    method @Deprecated public android.content.Intent! getIntent(int);
+    method public int getIntentCount();
+    method public android.content.Intent![] getIntents();
+    method public android.app.PendingIntent? getPendingIntent(int, int);
+    method public android.app.PendingIntent? getPendingIntent(int, int, android.os.Bundle?);
+    method @Deprecated public java.util.Iterator<android.content.Intent!> iterator();
+    method public void startActivities();
+    method public void startActivities(android.os.Bundle?);
+  }
+
+  public static interface TaskStackBuilder.SupportParentable {
+    method public android.content.Intent? getSupportParentActivityIntent();
+  }
+
+}
+
+package androidx.core.content {
+
+  public final class ContentProviderCompat {
+    method public static android.content.Context requireContext(android.content.ContentProvider);
+  }
+
+  public final class ContentResolverCompat {
+    method public static android.database.Cursor? query(android.content.ContentResolver, android.net.Uri, String![]?, String?, String![]?, String?, androidx.core.os.CancellationSignal?);
+  }
+
+  public class ContextCompat {
+    ctor protected ContextCompat();
+    method public static int checkSelfPermission(android.content.Context, String);
+    method public static android.content.Context? createDeviceProtectedStorageContext(android.content.Context);
+    method public static String? getAttributionTag(android.content.Context);
+    method public static java.io.File getCodeCacheDir(android.content.Context);
+    method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
+    method public static java.io.File? getDataDir(android.content.Context);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
+    method public static java.io.File![] getExternalCacheDirs(android.content.Context);
+    method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
+    method public static java.util.concurrent.Executor getMainExecutor(android.content.Context);
+    method public static java.io.File? getNoBackupFilesDir(android.content.Context);
+    method public static java.io.File![] getObbDirs(android.content.Context);
+    method public static <T> T? getSystemService(android.content.Context, Class<T!>);
+    method public static String? getSystemServiceName(android.content.Context, Class<?>);
+    method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, int);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, String?, android.os.Handler?, int);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![]);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
+    method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
+    method public static void startForegroundService(android.content.Context, android.content.Intent);
+    field public static final int RECEIVER_EXPORTED = 2; // 0x2
+    field public static final int RECEIVER_NOT_EXPORTED = 4; // 0x4
+    field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
+  }
+
+  public class FileProvider extends android.content.ContentProvider {
+    ctor public FileProvider();
+    ctor protected FileProvider(@XmlRes int);
+    method public int delete(android.net.Uri, String?, String![]?);
+    method public String? getType(android.net.Uri);
+    method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
+    method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
+    method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
+    method public boolean onCreate();
+    method public android.database.Cursor query(android.net.Uri, String![]?, String?, String![]?, String?);
+    method public int update(android.net.Uri, android.content.ContentValues, String?, String![]?);
+  }
+
+  public final class IntentCompat {
+    method public static android.content.Intent createManageUnusedAppRestrictionsIntent(android.content.Context, String);
+    method public static android.os.Parcelable![]? getParcelableArrayExtra(android.content.Intent, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayListExtra(android.content.Intent, String?, Class<? extends T>);
+    method public static <T> T? getParcelableExtra(android.content.Intent, String?, Class<T!>);
+    method public static android.content.Intent makeMainSelectorActivity(String, String);
+    field public static final String ACTION_CREATE_REMINDER = "android.intent.action.CREATE_REMINDER";
+    field public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+    field public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
+    field public static final String EXTRA_TIME = "android.intent.extra.TIME";
+  }
+
+  public class IntentSanitizer {
+    method public android.content.Intent sanitize(android.content.Intent, androidx.core.util.Consumer<java.lang.String!>);
+    method public android.content.Intent sanitizeByFiltering(android.content.Intent);
+    method public android.content.Intent sanitizeByThrowing(android.content.Intent);
+  }
+
+  public static final class IntentSanitizer.Builder {
+    ctor public IntentSanitizer.Builder();
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowAnyComponent();
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipData(androidx.core.util.Predicate<android.content.ClipData!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataText();
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUri(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(android.content.ComponentName);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(androidx.core.util.Predicate<android.content.ComponentName!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponentWithPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowData(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowDataWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<?>);
+    method public <T> androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<T!>, androidx.core.util.Predicate<T!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, androidx.core.util.Predicate<java.lang.Object!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStream(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStreamUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowFlags(int);
+    method public androidx.core.content.IntentSanitizer.Builder allowHistoryStackFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowIdentifier();
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowReceiverFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowSelector();
+    method public androidx.core.content.IntentSanitizer.Builder allowSourceBounds();
+    method public androidx.core.content.IntentSanitizer.Builder allowType(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowType(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer build();
+  }
+
+  public final class LocusIdCompat {
+    ctor public LocusIdCompat(String);
+    method public String getId();
+    method @RequiresApi(29) public android.content.LocusId toLocusId();
+    method @RequiresApi(29) public static androidx.core.content.LocusIdCompat toLocusIdCompat(android.content.LocusId);
+  }
+
+  public final class MimeTypeFilter {
+    method public static boolean matches(String?, String);
+    method public static String? matches(String?, String![]);
+    method public static String? matches(String![]?, String);
+    method public static String![] matchesMany(String![]?, String);
+  }
+
+  public interface OnConfigurationChangedProvider {
+    method public void addOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+    method public void removeOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+  }
+
+  public interface OnTrimMemoryProvider {
+    method public void addOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+    method public void removeOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+  }
+
+  public final class PackageManagerCompat {
+    method public static com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> getUnusedAppRestrictionsStatus(android.content.Context);
+    field public static final String ACTION_PERMISSION_REVOCATION_SETTINGS = "android.intent.action.AUTO_REVOKE_PERMISSIONS";
+  }
+
+  public final class PermissionChecker {
+    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkCallingOrSelfPermission(android.content.Context, String);
+    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkCallingPermission(android.content.Context, String, String?);
+    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkPermission(android.content.Context, String, int, int, String?);
+    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkSelfPermission(android.content.Context, String);
+    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
+    field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
+    field public static final int PERMISSION_GRANTED = 0; // 0x0
+  }
+
+  @IntDef({androidx.core.content.PermissionChecker.PERMISSION_GRANTED, androidx.core.content.PermissionChecker.PERMISSION_DENIED, androidx.core.content.PermissionChecker.PERMISSION_DENIED_APP_OP}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PermissionChecker.PermissionResult {
+  }
+
+  @Deprecated public final class SharedPreferencesCompat {
+  }
+
+  @Deprecated public static final class SharedPreferencesCompat.EditorCompat {
+    method @Deprecated public void apply(android.content.SharedPreferences.Editor);
+    method @Deprecated public static androidx.core.content.SharedPreferencesCompat.EditorCompat! getInstance();
+  }
+
+  public class UnusedAppRestrictionsBackportCallback {
+    method public void onResult(boolean, boolean) throws android.os.RemoteException;
+  }
+
+  public abstract class UnusedAppRestrictionsBackportService extends android.app.Service {
+    ctor public UnusedAppRestrictionsBackportService();
+    method protected abstract void isPermissionRevocationEnabled(androidx.core.content.UnusedAppRestrictionsBackportCallback);
+    method public android.os.IBinder? onBind(android.content.Intent?);
+    field public static final String ACTION_UNUSED_APP_RESTRICTIONS_BACKPORT_CONNECTION = "android.support.unusedapprestrictions.action.CustomUnusedAppRestrictionsBackportService";
+  }
+
+  public final class UnusedAppRestrictionsConstants {
+    field public static final int API_30 = 4; // 0x4
+    field public static final int API_30_BACKPORT = 3; // 0x3
+    field public static final int API_31 = 5; // 0x5
+    field public static final int DISABLED = 2; // 0x2
+    field public static final int ERROR = 0; // 0x0
+    field public static final int FEATURE_NOT_AVAILABLE = 1; // 0x1
+  }
+
+  public class UriMatcherCompat {
+    method public static androidx.core.util.Predicate<android.net.Uri!> asPredicate(android.content.UriMatcher);
+  }
+
+}
+
+package androidx.core.content.pm {
+
+  @Deprecated public final class ActivityInfoCompat {
+    field @Deprecated public static final int CONFIG_UI_MODE = 512; // 0x200
+  }
+
+  public final class PackageInfoCompat {
+    method public static long getLongVersionCode(android.content.pm.PackageInfo);
+    method public static java.util.List<android.content.pm.Signature!> getSignatures(android.content.pm.PackageManager, String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static boolean hasSignatures(android.content.pm.PackageManager, String, @Size(min=1) java.util.Map<byte[]!,java.lang.Integer!>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
+  }
+
+  public final class PermissionInfoCompat {
+    method public static int getProtection(android.content.pm.PermissionInfo);
+    method public static int getProtectionFlags(android.content.pm.PermissionInfo);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ShortcutInfoChangeListener {
+    ctor public ShortcutInfoChangeListener();
+    method @AnyThread public void onAllShortcutsRemoved();
+    method @AnyThread public void onShortcutAdded(java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method @AnyThread public void onShortcutRemoved(java.util.List<java.lang.String!>);
+    method @AnyThread public void onShortcutUpdated(java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method @AnyThread public void onShortcutUsageReported(java.util.List<java.lang.String!>);
+  }
+
+  public class ShortcutInfoCompat {
+    method public android.content.ComponentName? getActivity();
+    method public java.util.Set<java.lang.String!>? getCategories();
+    method public CharSequence? getDisabledMessage();
+    method public int getDisabledReason();
+    method @androidx.core.content.pm.ShortcutInfoCompat.Surface public int getExcludedFromSurfaces();
+    method public android.os.PersistableBundle? getExtras();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.graphics.drawable.IconCompat! getIcon();
+    method public String getId();
+    method public android.content.Intent getIntent();
+    method public android.content.Intent![] getIntents();
+    method public long getLastChangedTimestamp();
+    method public androidx.core.content.LocusIdCompat? getLocusId();
+    method public CharSequence? getLongLabel();
+    method public String getPackage();
+    method public int getRank();
+    method public CharSequence getShortLabel();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.os.Bundle? getTransientExtras();
+    method public android.os.UserHandle? getUserHandle();
+    method public boolean hasKeyFieldsOnly();
+    method public boolean isCached();
+    method public boolean isDeclaredInManifest();
+    method public boolean isDynamic();
+    method public boolean isEnabled();
+    method public boolean isExcludedFromSurfaces(@androidx.core.content.pm.ShortcutInfoCompat.Surface int);
+    method public boolean isImmutable();
+    method public boolean isPinned();
+    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
+    field public static final int SURFACE_LAUNCHER = 1; // 0x1
+  }
+
+  public static class ShortcutInfoCompat.Builder {
+    ctor public ShortcutInfoCompat.Builder(android.content.Context, String);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public ShortcutInfoCompat.Builder(androidx.core.content.pm.ShortcutInfoCompat);
+    ctor @RequiresApi(25) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public ShortcutInfoCompat.Builder(android.content.Context, android.content.pm.ShortcutInfo);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String, String, java.util.List<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat build();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setAlwaysBadged();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setCategories(java.util.Set<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExcludedFromSurfaces(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExtras(android.os.PersistableBundle);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIcon(androidx.core.graphics.drawable.IconCompat!);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIsConversation();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLabel(CharSequence);
+    method @Deprecated public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived(boolean);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPerson(androidx.core.app.Person);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPersons(androidx.core.app.Person![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setRank(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setShortLabel(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setSliceUri(android.net.Uri);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.content.pm.ShortcutInfoCompat.Builder setTransientExtras(android.os.Bundle);
+  }
+
+  @IntDef(flag=true, value={androidx.core.content.pm.ShortcutInfoCompat.SURFACE_LAUNCHER}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ShortcutInfoCompat.Surface {
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ShortcutInfoCompatSaver<T> {
+    ctor public ShortcutInfoCompatSaver();
+    method @AnyThread public abstract T! addShortcuts(java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>!);
+    method @WorkerThread public java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>! getShortcuts() throws java.lang.Exception;
+    method @AnyThread public abstract T! removeAllShortcuts();
+    method @AnyThread public abstract T! removeShortcuts(java.util.List<java.lang.String!>!);
+  }
+
+  public class ShortcutManagerCompat {
+    method public static boolean addDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static android.content.Intent createShortcutResultIntent(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void disableShortcuts(android.content.Context, java.util.List<java.lang.String!>, CharSequence?);
+    method public static void enableShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
+    method public static int getIconMaxHeight(android.content.Context);
+    method public static int getIconMaxWidth(android.content.Context);
+    method public static int getMaxShortcutCountPerActivity(android.content.Context);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getShortcuts(android.content.Context, @androidx.core.content.pm.ShortcutManagerCompat.ShortcutMatchFlags int);
+    method public static boolean isRateLimitingActive(android.content.Context);
+    method public static boolean isRequestPinShortcutSupported(android.content.Context);
+    method public static boolean pushDynamicShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void removeAllDynamicShortcuts(android.content.Context);
+    method public static void removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void removeLongLivedShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void reportShortcutUsed(android.content.Context, String);
+    method public static boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
+    method public static boolean setDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static boolean updateShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    field public static final String EXTRA_SHORTCUT_ID = "android.intent.extra.shortcut.ID";
+    field public static final int FLAG_MATCH_CACHED = 8; // 0x8
+    field public static final int FLAG_MATCH_DYNAMIC = 2; // 0x2
+    field public static final int FLAG_MATCH_MANIFEST = 1; // 0x1
+    field public static final int FLAG_MATCH_PINNED = 4; // 0x4
+  }
+
+  @IntDef(flag=true, value={androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_MANIFEST, androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_DYNAMIC, androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_PINNED, androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_CACHED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ShortcutManagerCompat.ShortcutMatchFlags {
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class ShortcutXmlParser {
+    method @WorkerThread public static java.util.List<java.lang.String!> getShortcutIds(android.content.Context);
+    method @VisibleForTesting public static java.util.List<java.lang.String!> parseShortcutIds(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
+package androidx.core.content.res {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ColorStateListInflaterCompat {
+    method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static android.content.res.ColorStateList createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static android.content.res.ColorStateList? inflate(android.content.res.Resources, @XmlRes int, android.content.res.Resources.Theme?);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ComplexColorCompat {
+    method @ColorInt public int getColor();
+    method public android.graphics.Shader? getShader();
+    method public static androidx.core.content.res.ComplexColorCompat? inflate(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?);
+    method public boolean isGradient();
+    method public boolean isStateful();
+    method public boolean onStateChanged(int[]!);
+    method public void setColor(@ColorInt int);
+    method public boolean willDraw();
+  }
+
+  public final class ConfigurationHelper {
+    method public static int getDensityDpi(android.content.res.Resources);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FontResourcesParserCompat {
+    method public static androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry? parse(org.xmlpull.v1.XmlPullParser, android.content.res.Resources) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static java.util.List<java.util.List<byte[]!>!> readCerts(android.content.res.Resources, @ArrayRes int);
+    field public static final int FETCH_STRATEGY_ASYNC = 1; // 0x1
+    field public static final int FETCH_STRATEGY_BLOCKING = 0; // 0x0
+    field public static final int INFINITE_TIMEOUT_VALUE = -1; // 0xffffffff
+  }
+
+  public static interface FontResourcesParserCompat.FamilyResourceEntry {
+  }
+
+  @IntDef({androidx.core.content.res.FontResourcesParserCompat.FETCH_STRATEGY_BLOCKING, androidx.core.content.res.FontResourcesParserCompat.FETCH_STRATEGY_ASYNC}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface FontResourcesParserCompat.FetchStrategy {
+  }
+
+  public static final class FontResourcesParserCompat.FontFamilyFilesResourceEntry implements androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry {
+    ctor public FontResourcesParserCompat.FontFamilyFilesResourceEntry(androidx.core.content.res.FontResourcesParserCompat.FontFileResourceEntry![]);
+    method public androidx.core.content.res.FontResourcesParserCompat.FontFileResourceEntry![] getEntries();
+  }
+
+  public static final class FontResourcesParserCompat.FontFileResourceEntry {
+    ctor public FontResourcesParserCompat.FontFileResourceEntry(String, int, boolean, String?, int, int);
+    method public String getFileName();
+    method public int getResourceId();
+    method public int getTtcIndex();
+    method public String? getVariationSettings();
+    method public int getWeight();
+    method public boolean isItalic();
+  }
+
+  public static final class FontResourcesParserCompat.ProviderResourceEntry implements androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry {
+    ctor public FontResourcesParserCompat.ProviderResourceEntry(androidx.core.provider.FontRequest, @androidx.core.content.res.FontResourcesParserCompat.FetchStrategy int, int);
+    method @androidx.core.content.res.FontResourcesParserCompat.FetchStrategy public int getFetchStrategy();
+    method public androidx.core.provider.FontRequest getRequest();
+    method public int getTimeout();
+  }
+
+  public final class ResourcesCompat {
+    method public static void clearCachesForTheme(android.content.res.Resources.Theme);
+    method public static android.graphics.Typeface? getCachedFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method @ColorInt public static int getColor(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.Resources, @DrawableRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawableForDensity(android.content.res.Resources, @DrawableRes int, int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static float getFloat(android.content.res.Resources, @DimenRes int);
+    method public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method public static void getFont(android.content.Context, @FontRes int, androidx.core.content.res.ResourcesCompat.FontCallback, android.os.Handler?) throws android.content.res.Resources.NotFoundException;
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int, android.util.TypedValue, int, androidx.core.content.res.ResourcesCompat.FontCallback?) throws android.content.res.Resources.NotFoundException;
+    field @AnyRes public static final int ID_NULL = 0; // 0x0
+  }
+
+  public abstract static class ResourcesCompat.FontCallback {
+    ctor public ResourcesCompat.FontCallback();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final void callbackFailAsync(@androidx.core.provider.FontsContractCompat.FontRequestCallback.FontRequestFailReason int, android.os.Handler?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final void callbackSuccessAsync(android.graphics.Typeface, android.os.Handler?);
+    method public abstract void onFontRetrievalFailed(@androidx.core.provider.FontsContractCompat.FontRequestCallback.FontRequestFailReason int);
+    method public abstract void onFontRetrieved(android.graphics.Typeface);
+  }
+
+  public static final class ResourcesCompat.ThemeCompat {
+    method public static void rebase(android.content.res.Resources.Theme);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypedArrayUtils {
+    method public static int getAttr(android.content.Context, int, int);
+    method public static boolean getBoolean(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int, boolean);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
+    method public static int getInt(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int, int);
+    method public static boolean getNamedBoolean(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, boolean);
+    method @ColorInt public static int getNamedColor(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, @ColorInt int);
+    method public static android.content.res.ColorStateList? getNamedColorStateList(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme?, String, @StyleableRes int);
+    method public static androidx.core.content.res.ComplexColorCompat! getNamedComplexColor(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme?, String, @StyleableRes int, @ColorInt int);
+    method public static float getNamedFloat(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, float);
+    method public static int getNamedInt(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, int);
+    method @AnyRes public static int getNamedResourceId(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, @AnyRes int);
+    method public static String? getNamedString(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int);
+    method @AnyRes public static int getResourceId(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int, @AnyRes int);
+    method public static String? getString(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
+    method public static CharSequence? getText(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
+    method public static CharSequence![]? getTextArray(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
+    method public static boolean hasAttribute(org.xmlpull.v1.XmlPullParser, String);
+    method public static android.content.res.TypedArray obtainAttributes(android.content.res.Resources, android.content.res.Resources.Theme?, android.util.AttributeSet, int[]);
+    method public static android.util.TypedValue? peekNamedValue(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, int);
+  }
+
+}
+
+package androidx.core.database {
+
+  public final class CursorWindowCompat {
+    method public static android.database.CursorWindow create(String?, long);
+  }
+
+  @Deprecated public final class DatabaseUtilsCompat {
+    method @Deprecated public static String![]! appendSelectionArgs(String![]!, String![]!);
+    method @Deprecated public static String! concatenateWhere(String!, String!);
+  }
+
+}
+
+package androidx.core.database.sqlite {
+
+  public final class SQLiteCursorCompat {
+    method public static void setFillWindowForwardOnly(android.database.sqlite.SQLiteCursor, boolean);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapCompat {
+    method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, android.graphics.Rect?, boolean);
+    method public static int getAllocationByteCount(android.graphics.Bitmap);
+    method public static boolean hasMipMap(android.graphics.Bitmap);
+    method public static void setHasMipMap(android.graphics.Bitmap, boolean);
+  }
+
+  public class BlendModeColorFilterCompat {
+    method public static android.graphics.ColorFilter? createBlendModeColorFilterCompat(int, androidx.core.graphics.BlendModeCompat);
+  }
+
+  public enum BlendModeCompat {
+    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HUE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SATURATION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
+  }
+
+  public final class ColorUtils {
+    method @ColorInt public static int HSLToColor(float[]);
+    method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
+    method public static void LABToXYZ(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double, double[]);
+    method public static void RGBToHSL(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, float[]);
+    method public static void RGBToLAB(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method public static void RGBToXYZ(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method @ColorInt public static int XYZToColor(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double);
+    method public static void XYZToLAB(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double, double[]);
+    method @ColorInt public static int blendARGB(@ColorInt int, @ColorInt int, @FloatRange(from=0.0, to=1.0) float);
+    method public static void blendHSL(float[], float[], @FloatRange(from=0.0, to=1.0) float, float[]);
+    method public static void blendLAB(double[], double[], @FloatRange(from=0.0, to=1.0) double, double[]);
+    method public static double calculateContrast(@ColorInt int, @ColorInt int);
+    method @FloatRange(from=0.0, to=1.0) public static double calculateLuminance(@ColorInt int);
+    method public static int calculateMinimumAlpha(@ColorInt int, @ColorInt int, float);
+    method public static void colorToHSL(@ColorInt int, float[]);
+    method public static void colorToLAB(@ColorInt int, double[]);
+    method public static void colorToXYZ(@ColorInt int, double[]);
+    method public static int compositeColors(@ColorInt int, @ColorInt int);
+    method @RequiresApi(26) public static android.graphics.Color compositeColors(android.graphics.Color, android.graphics.Color);
+    method public static double distanceEuclidean(double[], double[]);
+    method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
+  }
+
+  public final class Insets {
+    method public static androidx.core.graphics.Insets add(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets max(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets min(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets of(int, int, int, int);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    method public static androidx.core.graphics.Insets subtract(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method @RequiresApi(api=29) public static androidx.core.graphics.Insets toCompatInsets(android.graphics.Insets);
+    method @RequiresApi(29) public android.graphics.Insets toPlatformInsets();
+    method @Deprecated @RequiresApi(api=29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.Insets wrap(android.graphics.Insets);
+    field public static final androidx.core.graphics.Insets NONE;
+    field public final int bottom;
+    field public final int left;
+    field public final int right;
+    field public final int top;
+  }
+
+  public final class PaintCompat {
+    method public static boolean hasGlyph(android.graphics.Paint, String);
+    method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
+  }
+
+  public final class PathSegment {
+    ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
+    method public android.graphics.PointF getEnd();
+    method public float getEndFraction();
+    method public android.graphics.PointF getStart();
+    method public float getStartFraction();
+  }
+
+  public final class PathUtils {
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path);
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path, @FloatRange(from=0) float);
+  }
+
+  public class TypefaceCompat {
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @VisibleForTesting public static void clearCache();
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, int);
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, @IntRange(from=1, to=1000) int, boolean);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromFontInfo(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![], int);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromResourcesFamilyXml(android.content.Context, androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry, android.content.res.Resources, int, int, androidx.core.content.res.ResourcesCompat.FontCallback?, android.os.Handler?, boolean);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromResourcesFontFile(android.content.Context, android.content.res.Resources, int, String!, int);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? findFromCache(android.content.res.Resources, int, int);
+  }
+
+  @RequiresApi(26) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatApi26Impl {
+    ctor public TypefaceCompatApi26Impl();
+    method protected android.graphics.Typeface? createFromFamiliesWithDefault(Object!);
+    method public android.graphics.Typeface? createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
+    method public android.graphics.Typeface? createFromFontInfo(android.content.Context!, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![], int);
+    method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
+    method protected java.lang.reflect.Method! obtainAbortCreationMethod(Class<?>!) throws java.lang.NoSuchMethodException;
+    method protected java.lang.reflect.Method! obtainAddFontFromAssetManagerMethod(Class<?>!) throws java.lang.NoSuchMethodException;
+    method protected java.lang.reflect.Method! obtainAddFontFromBufferMethod(Class<?>!) throws java.lang.NoSuchMethodException;
+    method protected java.lang.reflect.Method! obtainCreateFromFamiliesWithDefaultMethod(Class<?>!) throws java.lang.NoSuchMethodException;
+    method protected Class<?>! obtainFontFamily() throws java.lang.ClassNotFoundException;
+    method protected java.lang.reflect.Constructor<?>! obtainFontFamilyCtor(Class<?>!) throws java.lang.NoSuchMethodException;
+    method protected java.lang.reflect.Method! obtainFreezeMethod(Class<?>!) throws java.lang.NoSuchMethodException;
+    field protected final java.lang.reflect.Method! mAbortCreation;
+    field protected final java.lang.reflect.Method! mAddFontFromAssetManager;
+    field protected final java.lang.reflect.Method! mAddFontFromBuffer;
+    field protected final java.lang.reflect.Method! mCreateFromFamiliesWithDefault;
+    field protected final Class<?>! mFontFamily;
+    field protected final java.lang.reflect.Constructor<?>! mFontFamilyCtor;
+    field protected final java.lang.reflect.Method! mFreeze;
+  }
+
+  @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatApi28Impl extends androidx.core.graphics.TypefaceCompatApi26Impl {
+    ctor public TypefaceCompatApi28Impl();
+  }
+
+  @RequiresApi(29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class TypefaceCompatApi29Impl {
+    ctor public TypefaceCompatApi29Impl();
+    method public android.graphics.Typeface? createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
+    method public android.graphics.Typeface? createFromFontInfo(android.content.Context!, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![], int);
+    method protected android.graphics.Typeface! createFromInputStream(android.content.Context!, java.io.InputStream!);
+    method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
+    method protected androidx.core.provider.FontsContractCompat.FontInfo! findBestInfo(androidx.core.provider.FontsContractCompat.FontInfo![]!, int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatUtil {
+    method public static void closeQuietly(java.io.Closeable?);
+    method @RequiresApi(19) public static java.nio.ByteBuffer? copyToDirectBuffer(android.content.Context, android.content.res.Resources, int);
+    method public static boolean copyToFile(java.io.File, java.io.InputStream);
+    method public static boolean copyToFile(java.io.File, android.content.res.Resources, int);
+    method public static java.io.File? getTempFile(android.content.Context);
+    method @RequiresApi(19) public static java.nio.ByteBuffer? mmap(android.content.Context, android.os.CancellationSignal?, android.net.Uri);
+  }
+
+}
+
+package androidx.core.graphics.drawable {
+
+  public final class DrawableCompat {
+    method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
+    method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
+    method public static void clearColorFilter(android.graphics.drawable.Drawable);
+    method public static int getAlpha(android.graphics.drawable.Drawable);
+    method public static android.graphics.ColorFilter? getColorFilter(android.graphics.drawable.Drawable);
+    method public static int getLayoutDirection(android.graphics.drawable.Drawable);
+    method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
+    method @Deprecated public static void jumpToCurrentState(android.graphics.drawable.Drawable);
+    method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
+    method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
+    method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
+    method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
+    method public static void setTint(android.graphics.drawable.Drawable, @ColorInt int);
+    method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList?);
+    method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode?);
+    method public static <T extends android.graphics.drawable.Drawable> T! unwrap(android.graphics.drawable.Drawable);
+    method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
+  }
+
+  @androidx.versionedparcelable.VersionedParcelize(allowSerialization=true, ignoreParcelables=true, isCustom=true, jetifyAs="android.support.v4.graphics.drawable.IconCompat") public class IconCompat extends androidx.versionedparcelable.CustomVersionedParcelable {
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addToShortcutIntent(android.content.Intent, android.graphics.drawable.Drawable?, android.content.Context);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void checkResource(android.content.Context);
+    method public static androidx.core.graphics.drawable.IconCompat? createFromBundle(android.os.Bundle);
+    method @RequiresApi(23) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.content.Context, android.graphics.drawable.Icon);
+    method @RequiresApi(23) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.graphics.drawable.Icon);
+    method @RequiresApi(23) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.drawable.IconCompat? createFromIconOrNullIfZeroResId(android.graphics.drawable.Icon);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithData(byte[], int, int);
+    method public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.Context, @DrawableRes int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.res.Resources?, String, @DrawableRes int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.Bitmap? getBitmap();
+    method @DrawableRes public int getResId();
+    method public String getResPackage();
+    method public int getType();
+    method public android.net.Uri getUri();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public java.io.InputStream? getUriInputStream(android.content.Context);
+    method public android.graphics.drawable.Drawable? loadDrawable(android.content.Context);
+    method public androidx.core.graphics.drawable.IconCompat setTint(@ColorInt int);
+    method public androidx.core.graphics.drawable.IconCompat setTintList(android.content.res.ColorStateList?);
+    method public androidx.core.graphics.drawable.IconCompat setTintMode(android.graphics.PorterDuff.Mode?);
+    method public android.os.Bundle toBundle();
+    method @Deprecated @RequiresApi(23) public android.graphics.drawable.Icon toIcon();
+    method @RequiresApi(23) public android.graphics.drawable.Icon toIcon(android.content.Context?);
+    field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
+    field public static final int TYPE_BITMAP = 1; // 0x1
+    field public static final int TYPE_DATA = 3; // 0x3
+    field public static final int TYPE_RESOURCE = 2; // 0x2
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int TYPE_URI = 4; // 0x4
+    field public static final int TYPE_URI_ADAPTIVE_BITMAP = 6; // 0x6
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @androidx.versionedparcelable.ParcelField(value=1, defaultValue="androidx.core.graphics.drawable.IconCompat.TYPE_UNKNOWN") public int mType;
+  }
+
+  public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.Bitmap? getBitmap();
+    method public float getCornerRadius();
+    method public int getGravity();
+    method public int getOpacity();
+    method public final android.graphics.Paint getPaint();
+    method public boolean hasAntiAlias();
+    method public boolean hasMipMap();
+    method public boolean isCircular();
+    method public void setAlpha(int);
+    method public void setAntiAlias(boolean);
+    method public void setCircular(boolean);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setCornerRadius(float);
+    method public void setDither(boolean);
+    method public void setGravity(int);
+    method public void setMipMap(boolean);
+    method public void setTargetDensity(android.graphics.Canvas);
+    method public void setTargetDensity(android.util.DisplayMetrics);
+    method public void setTargetDensity(int);
+  }
+
+  public final class RoundedBitmapDrawableFactory {
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap?);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, String);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface TintAwareDrawable {
+    method public void setTint(@ColorInt int);
+    method public void setTintList(android.content.res.ColorStateList!);
+    method public void setTintMode(android.graphics.PorterDuff.Mode!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface WrappedDrawable {
+    method public android.graphics.drawable.Drawable! getWrappedDrawable();
+    method public void setWrappedDrawable(android.graphics.drawable.Drawable!);
+  }
+
+}
+
+package androidx.core.hardware.display {
+
+  public final class DisplayManagerCompat {
+    method public android.view.Display? getDisplay(int);
+    method public android.view.Display![] getDisplays();
+    method public android.view.Display![] getDisplays(String?);
+    method public static androidx.core.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
+    field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+  }
+
+}
+
+package androidx.core.hardware.fingerprint {
+
+  @Deprecated public class FingerprintManagerCompat {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public void authenticate(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject?, int, androidx.core.os.CancellationSignal?, androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler?);
+    method @Deprecated public static androidx.core.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean hasEnrolledFingerprints();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean isHardwareDetected();
+  }
+
+  @Deprecated public abstract static class FingerprintManagerCompat.AuthenticationCallback {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationCallback();
+    method @Deprecated public void onAuthenticationError(int, CharSequence!);
+    method @Deprecated public void onAuthenticationFailed();
+    method @Deprecated public void onAuthenticationHelp(int, CharSequence!);
+    method @Deprecated public void onAuthenticationSucceeded(androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult!);
+  }
+
+  @Deprecated public static final class FingerprintManagerCompat.AuthenticationResult {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationResult(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject!);
+    method @Deprecated public androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject! getCryptoObject();
+  }
+
+  @Deprecated public static class FingerprintManagerCompat.CryptoObject {
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
+    method @Deprecated public javax.crypto.Cipher? getCipher();
+    method @Deprecated public javax.crypto.Mac? getMac();
+    method @Deprecated public java.security.Signature? getSignature();
+  }
+
+}
+
+package androidx.core.internal.view {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SupportMenu extends android.view.Menu {
+    method public void setGroupDividerEnabled(boolean);
+    field public static final int CATEGORY_MASK = -65536; // 0xffff0000
+    field public static final int CATEGORY_SHIFT = 16; // 0x10
+    field public static final int FLAG_KEEP_OPEN_ON_SUBMENU_OPENED = 4; // 0x4
+    field public static final int SUPPORTED_MODIFIERS_MASK = 69647; // 0x1100f
+    field public static final int USER_MASK = 65535; // 0xffff
+    field public static final int USER_SHIFT = 0; // 0x0
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SupportMenuItem extends android.view.MenuItem {
+    method public int getAlphabeticModifiers();
+    method public CharSequence? getContentDescription();
+    method public android.content.res.ColorStateList? getIconTintList();
+    method public android.graphics.PorterDuff.Mode? getIconTintMode();
+    method public int getNumericModifiers();
+    method public androidx.core.view.ActionProvider? getSupportActionProvider();
+    method public CharSequence? getTooltipText();
+    method public boolean requiresActionButton();
+    method public boolean requiresOverflow();
+    method public android.view.MenuItem setAlphabeticShortcut(char, int);
+    method public androidx.core.internal.view.SupportMenuItem setContentDescription(CharSequence?);
+    method public android.view.MenuItem setIconTintList(android.content.res.ColorStateList?);
+    method public android.view.MenuItem setIconTintMode(android.graphics.PorterDuff.Mode?);
+    method public android.view.MenuItem setNumericShortcut(char, int);
+    method public android.view.MenuItem setShortcut(char, char, int, int);
+    method public androidx.core.internal.view.SupportMenuItem setSupportActionProvider(androidx.core.view.ActionProvider?);
+    method public androidx.core.internal.view.SupportMenuItem setTooltipText(CharSequence?);
+    field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+    field public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+    field public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+    field public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+    field public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SupportSubMenu extends androidx.core.internal.view.SupportMenu android.view.SubMenu {
+  }
+
+}
+
+package androidx.core.location {
+
+  public abstract class GnssStatusCompat {
+    method @FloatRange(from=0, to=360) public abstract float getAzimuthDegrees(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getBasebandCn0DbHz(@IntRange(from=0) int);
+    method @FloatRange(from=0) public abstract float getCarrierFrequencyHz(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getCn0DbHz(@IntRange(from=0) int);
+    method public abstract int getConstellationType(@IntRange(from=0) int);
+    method @FloatRange(from=0xffffffa6, to=90) public abstract float getElevationDegrees(@IntRange(from=0) int);
+    method @IntRange(from=0) public abstract int getSatelliteCount();
+    method @IntRange(from=1, to=200) public abstract int getSvid(@IntRange(from=0) int);
+    method public abstract boolean hasAlmanacData(@IntRange(from=0) int);
+    method public abstract boolean hasBasebandCn0DbHz(@IntRange(from=0) int);
+    method public abstract boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
+    method public abstract boolean hasEphemerisData(@IntRange(from=0) int);
+    method public abstract boolean usedInFix(@IntRange(from=0) int);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static androidx.core.location.GnssStatusCompat wrap(android.location.GnssStatus);
+    method public static androidx.core.location.GnssStatusCompat wrap(android.location.GpsStatus);
+    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
+    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
+    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
+    field public static final int CONSTELLATION_GPS = 1; // 0x1
+    field public static final int CONSTELLATION_IRNSS = 7; // 0x7
+    field public static final int CONSTELLATION_QZSS = 4; // 0x4
+    field public static final int CONSTELLATION_SBAS = 2; // 0x2
+    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
+  }
+
+  public abstract static class GnssStatusCompat.Callback {
+    ctor public GnssStatusCompat.Callback();
+    method public void onFirstFix(@IntRange(from=0) int);
+    method public void onSatelliteStatusChanged(androidx.core.location.GnssStatusCompat);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public final class LocationCompat {
+    method public static float getBearingAccuracyDegrees(android.location.Location);
+    method public static long getElapsedRealtimeMillis(android.location.Location);
+    method public static long getElapsedRealtimeNanos(android.location.Location);
+    method @FloatRange(from=0.0) public static float getMslAltitudeAccuracyMeters(android.location.Location);
+    method public static double getMslAltitudeMeters(android.location.Location);
+    method public static float getSpeedAccuracyMetersPerSecond(android.location.Location);
+    method public static float getVerticalAccuracyMeters(android.location.Location);
+    method public static boolean hasBearingAccuracy(android.location.Location);
+    method public static boolean hasMslAltitude(android.location.Location);
+    method public static boolean hasMslAltitudeAccuracy(android.location.Location);
+    method public static boolean hasSpeedAccuracy(android.location.Location);
+    method public static boolean hasVerticalAccuracy(android.location.Location);
+    method public static boolean isMock(android.location.Location);
+    method public static void removeMslAltitude(android.location.Location);
+    method public static void removeMslAltitudeAccuracy(android.location.Location);
+    method public static void setBearingAccuracyDegrees(android.location.Location, float);
+    method public static void setMock(android.location.Location, boolean);
+    method public static void setMslAltitudeAccuracyMeters(android.location.Location, @FloatRange(from=0.0) float);
+    method public static void setMslAltitudeMeters(android.location.Location, double);
+    method public static void setSpeedAccuracyMetersPerSecond(android.location.Location, float);
+    method public static void setVerticalAccuracyMeters(android.location.Location, float);
+    field public static final String EXTRA_BEARING_ACCURACY = "bearingAccuracy";
+    field public static final String EXTRA_IS_MOCK = "mockLocation";
+    field public static final String EXTRA_MSL_ALTITUDE = "androidx.core.location.extra.MSL_ALTITUDE";
+    field public static final String EXTRA_MSL_ALTITUDE_ACCURACY = "androidx.core.location.extra.MSL_ALTITUDE_ACCURACY";
+    field public static final String EXTRA_SPEED_ACCURACY = "speedAccuracy";
+    field public static final String EXTRA_VERTICAL_ACCURACY = "verticalAccuracy";
+  }
+
+  public interface LocationListenerCompat extends android.location.LocationListener {
+    method public default void onStatusChanged(String, int, android.os.Bundle?);
+  }
+
+  public final class LocationManagerCompat {
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void getCurrentLocation(android.location.LocationManager, String, androidx.core.os.CancellationSignal?, java.util.concurrent.Executor, androidx.core.util.Consumer<android.location.Location!>);
+    method public static String? getGnssHardwareModelName(android.location.LocationManager);
+    method public static int getGnssYearOfHardware(android.location.LocationManager);
+    method public static boolean hasProvider(android.location.LocationManager, String);
+    method public static boolean isLocationEnabled(android.location.LocationManager);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
+    method @RequiresApi(android.os.Build.VERSION_CODES.R) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, java.util.concurrent.Executor, android.location.GnssMeasurementsEvent.Callback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback, android.os.Handler);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, java.util.concurrent.Executor, androidx.core.location.GnssStatusCompat.Callback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void removeUpdates(android.location.LocationManager, androidx.core.location.LocationListenerCompat);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, java.util.concurrent.Executor, androidx.core.location.LocationListenerCompat);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, androidx.core.location.LocationListenerCompat, android.os.Looper);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static void unregisterGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback);
+    method public static void unregisterGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback);
+  }
+
+  public final class LocationRequestCompat {
+    method @IntRange(from=1) public long getDurationMillis();
+    method @IntRange(from=0) public long getIntervalMillis();
+    method @IntRange(from=0) public long getMaxUpdateDelayMillis();
+    method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates();
+    method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters();
+    method @IntRange(from=0) public long getMinUpdateIntervalMillis();
+    method public int getQuality();
+    method @RequiresApi(31) public android.location.LocationRequest toLocationRequest();
+    method @RequiresApi(19) public android.location.LocationRequest? toLocationRequest(String);
+    field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL
+    field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66
+    field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64
+    field public static final int QUALITY_LOW_POWER = 104; // 0x68
+  }
+
+  public static final class LocationRequestCompat.Builder {
+    ctor public LocationRequestCompat.Builder(long);
+    ctor public LocationRequestCompat.Builder(androidx.core.location.LocationRequestCompat);
+    method public androidx.core.location.LocationRequestCompat build();
+    method public androidx.core.location.LocationRequestCompat.Builder clearMinUpdateIntervalMillis();
+    method public androidx.core.location.LocationRequestCompat.Builder setDurationMillis(@IntRange(from=1) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdateDelayMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setQuality(int);
+  }
+
+}
+
+package androidx.core.math {
+
+  public class MathUtils {
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
+    method public static float clamp(float, float, float);
+    method public static double clamp(double, double, double);
+    method public static int clamp(int, int, int);
+    method public static long clamp(long, long, long);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
+    method public static int toIntExact(long);
+  }
+
+}
+
+package androidx.core.net {
+
+  public final class ConnectivityManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static android.net.NetworkInfo? getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
+    method @androidx.core.net.ConnectivityManagerCompat.RestrictBackgroundStatus public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
+    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+  }
+
+  @IntDef({androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_DISABLED, androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_WHITELISTED, androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_ENABLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ConnectivityManagerCompat.RestrictBackgroundStatus {
+  }
+
+  public final class MailTo {
+    method public String? getBcc();
+    method public String? getBody();
+    method public String? getCc();
+    method public java.util.Map<java.lang.String!,java.lang.String!>? getHeaders();
+    method public String? getSubject();
+    method public String? getTo();
+    method public static boolean isMailTo(String?);
+    method public static boolean isMailTo(android.net.Uri?);
+    method public static androidx.core.net.MailTo parse(String) throws androidx.core.net.ParseException;
+    method public static androidx.core.net.MailTo parse(android.net.Uri) throws androidx.core.net.ParseException;
+    field public static final String MAILTO_SCHEME = "mailto:";
+  }
+
+  public class ParseException extends java.lang.RuntimeException {
+    field public final String response;
+  }
+
+  public final class TrafficStatsCompat {
+    method @Deprecated public static void clearThreadStatsTag();
+    method @Deprecated public static int getThreadStatsTag();
+    method @Deprecated public static void incrementOperationCount(int);
+    method @Deprecated public static void incrementOperationCount(int, int);
+    method @Deprecated public static void setThreadStatsTag(int);
+    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void tagSocket(java.net.Socket!) throws java.net.SocketException;
+    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void untagSocket(java.net.Socket!) throws java.net.SocketException;
+  }
+
+  public final class UriCompat {
+    method public static String toSafeString(android.net.Uri);
+  }
+
+}
+
+package androidx.core.os {
+
+  public class BuildCompat {
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N) public static boolean isAtLeastN();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N_MR1) public static boolean isAtLeastNMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O) public static boolean isAtLeastO();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O_MR1) public static boolean isAtLeastOMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.P) public static boolean isAtLeastP();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
+    method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
+    field @ChecksSdkIntAtLeast(extension=android.os.ext.SdkExtensions.AD_SERVICES) public static final int AD_SERVICES_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.R) public static final int R_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.S) public static final int S_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.TIRAMISU) public static final int T_EXTENSION_INT;
+  }
+
+  public final class BundleCompat {
+    method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
+    method public static android.os.Parcelable![]? getParcelableArray(android.os.Bundle, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayList(android.os.Bundle, String?, Class<? extends T>);
+    method public static <T> android.util.SparseArray<T!>? getSparseParcelableArray(android.os.Bundle, String?, Class<? extends T>);
+  }
+
+  public final class CancellationSignal {
+    ctor public CancellationSignal();
+    method public void cancel();
+    method public Object? getCancellationSignalObject();
+    method public boolean isCanceled();
+    method public void setOnCancelListener(androidx.core.os.CancellationSignal.OnCancelListener?);
+    method public void throwIfCanceled();
+  }
+
+  public static interface CancellationSignal.OnCancelListener {
+    method public void onCancel();
+  }
+
+  public final class ConfigurationCompat {
+    method public static androidx.core.os.LocaleListCompat getLocales(android.content.res.Configuration);
+  }
+
+  public final class EnvironmentCompat {
+    method public static String getStorageState(java.io.File);
+    field public static final String MEDIA_UNKNOWN = "unknown";
+  }
+
+  public final class ExecutorCompat {
+    method public static java.util.concurrent.Executor create(android.os.Handler);
+  }
+
+  public final class HandlerCompat {
+    method public static android.os.Handler createAsync(android.os.Looper);
+    method public static android.os.Handler createAsync(android.os.Looper, android.os.Handler.Callback);
+    method @RequiresApi(16) public static boolean hasCallbacks(android.os.Handler, Runnable);
+    method public static boolean postDelayed(android.os.Handler, Runnable, Object?, long);
+  }
+
+  public final class LocaleListCompat {
+    method public static androidx.core.os.LocaleListCompat create(java.util.Locale!...);
+    method public static androidx.core.os.LocaleListCompat forLanguageTags(String?);
+    method public java.util.Locale? get(int);
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getAdjustedDefault();
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getDefault();
+    method public static androidx.core.os.LocaleListCompat getEmptyLocaleList();
+    method public java.util.Locale? getFirstMatch(String![]);
+    method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
+    method public boolean isEmpty();
+    method @RequiresApi(21) public static boolean matchesLanguageAndScript(java.util.Locale, java.util.Locale);
+    method @IntRange(from=0) public int size();
+    method public String toLanguageTags();
+    method public Object? unwrap();
+    method @Deprecated @RequiresApi(24) public static androidx.core.os.LocaleListCompat! wrap(Object!);
+    method @RequiresApi(24) public static androidx.core.os.LocaleListCompat wrap(android.os.LocaleList);
+  }
+
+  public final class MessageCompat {
+    method public static boolean isAsynchronous(android.os.Message);
+    method public static void setAsynchronous(android.os.Message, boolean);
+  }
+
+  public class OperationCanceledException extends java.lang.RuntimeException {
+    ctor public OperationCanceledException();
+    ctor public OperationCanceledException(String?);
+  }
+
+  public final class ParcelCompat {
+    method public static <T> Object![]? readArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> java.util.ArrayList<T!>? readArrayList(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static boolean readBoolean(android.os.Parcel);
+    method public static <K, V> java.util.HashMap<K!,V!>? readHashMap(android.os.Parcel, ClassLoader?, Class<? extends K>, Class<? extends V>);
+    method public static <T> void readList(android.os.Parcel, java.util.List<? super T>, ClassLoader?, Class<T!>);
+    method public static <K, V> void readMap(android.os.Parcel, java.util.Map<? super K,? super V>, ClassLoader?, Class<K!>, Class<V!>);
+    method public static <T extends android.os.Parcelable> T? readParcelable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @Deprecated public static <T> T![]? readParcelableArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.os.Parcelable![]? readParcelableArrayTyped(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(30) public static <T> android.os.Parcelable.Creator<T!>? readParcelableCreator(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.Q) public static <T> java.util.List<T!> readParcelableList(android.os.Parcel, java.util.List<T!>, ClassLoader?, Class<T!>);
+    method public static <T extends java.io.Serializable> T? readSerializable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.util.SparseArray<T!>? readSparseArray(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static void writeBoolean(android.os.Parcel, boolean);
+  }
+
+  @Deprecated public final class ParcelableCompat {
+    method @Deprecated public static <T> android.os.Parcelable.Creator<T!>! newCreator(androidx.core.os.ParcelableCompatCreatorCallbacks<T!>!);
+  }
+
+  @Deprecated public interface ParcelableCompatCreatorCallbacks<T> {
+    method @Deprecated public T! createFromParcel(android.os.Parcel!, ClassLoader!);
+    method @Deprecated public T![]! newArray(int);
+  }
+
+  public final class ProcessCompat {
+    method public static boolean isApplicationUid(int);
+  }
+
+  @Deprecated public final class TraceCompat {
+    method @Deprecated public static void beginAsyncSection(String, int);
+    method @Deprecated public static void beginSection(String);
+    method @Deprecated public static void endAsyncSection(String, int);
+    method @Deprecated public static void endSection();
+    method @Deprecated public static boolean isEnabled();
+    method @Deprecated public static void setCounter(String, int);
+  }
+
+  @RequiresApi(17) public class UserHandleCompat {
+    method public static android.os.UserHandle getUserHandleForUid(int);
+  }
+
+  public class UserManagerCompat {
+    method public static boolean isUserUnlocked(android.content.Context);
+  }
+
+}
+
+package androidx.core.provider {
+
+  public final class DocumentsContractCompat {
+    method public static android.net.Uri? buildChildDocumentsUri(String, String?);
+    method public static android.net.Uri? buildChildDocumentsUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildDocumentUri(String, String);
+    method public static android.net.Uri? buildDocumentUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildTreeDocumentUri(String, String);
+    method public static android.net.Uri? createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException;
+    method public static String? getDocumentId(android.net.Uri);
+    method public static String? getTreeDocumentId(android.net.Uri);
+    method public static boolean isDocumentUri(android.content.Context, android.net.Uri?);
+    method public static boolean isTreeUri(android.net.Uri);
+    method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.net.Uri? renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException;
+  }
+
+  public static final class DocumentsContractCompat.DocumentCompat {
+    field public static final int FLAG_VIRTUAL_DOCUMENT = 512; // 0x200
+  }
+
+  public final class FontRequest {
+    ctor public FontRequest(String, String, String, java.util.List<java.util.List<byte[]!>!>);
+    ctor public FontRequest(String, String, String, @ArrayRes int);
+    method public java.util.List<java.util.List<byte[]!>!>? getCertificates();
+    method @ArrayRes public int getCertificatesArrayResId();
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public String! getIdentifier();
+    method public String getProviderAuthority();
+    method public String getProviderPackage();
+    method public String getQuery();
+  }
+
+  public class FontsContractCompat {
+    method public static android.graphics.Typeface? buildTypeface(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![]);
+    method public static androidx.core.provider.FontsContractCompat.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface! getFontSync(android.content.Context!, androidx.core.provider.FontRequest!, androidx.core.content.res.ResourcesCompat.FontCallback?, android.os.Handler?, boolean, int, int);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @VisibleForTesting public static android.content.pm.ProviderInfo? getProvider(android.content.pm.PackageManager, androidx.core.provider.FontRequest, android.content.res.Resources?) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Deprecated @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static java.util.Map<android.net.Uri!,java.nio.ByteBuffer!>! prepareFontData(android.content.Context!, androidx.core.provider.FontsContractCompat.FontInfo![]!, android.os.CancellationSignal!);
+    method public static void requestFont(android.content.Context, androidx.core.provider.FontRequest, androidx.core.provider.FontsContractCompat.FontRequestCallback, android.os.Handler);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void resetCache();
+    field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final String PARCEL_FONT_RESULTS = "font_results";
+  }
+
+  public static final class FontsContractCompat.Columns implements android.provider.BaseColumns {
+    ctor public FontsContractCompat.Columns();
+    field public static final String FILE_ID = "file_id";
+    field public static final String ITALIC = "font_italic";
+    field public static final String RESULT_CODE = "result_code";
+    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
+    field public static final int RESULT_CODE_OK = 0; // 0x0
+    field public static final String TTC_INDEX = "font_ttc_index";
+    field public static final String VARIATION_SETTINGS = "font_variation_settings";
+    field public static final String WEIGHT = "font_weight";
+  }
+
+  public static class FontsContractCompat.FontFamilyResult {
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public FontsContractCompat.FontFamilyResult(int, androidx.core.provider.FontsContractCompat.FontInfo![]?);
+    method public androidx.core.provider.FontsContractCompat.FontInfo![]! getFonts();
+    method public int getStatusCode();
+    field public static final int STATUS_OK = 0; // 0x0
+    field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
+    field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
+  }
+
+  public static class FontsContractCompat.FontInfo {
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public FontsContractCompat.FontInfo(android.net.Uri, @IntRange(from=0) int, @IntRange(from=1, to=1000) int, boolean, int);
+    method public int getResultCode();
+    method @IntRange(from=0) public int getTtcIndex();
+    method public android.net.Uri getUri();
+    method @IntRange(from=1, to=1000) public int getWeight();
+    method public boolean isItalic();
+  }
+
+  public static class FontsContractCompat.FontRequestCallback {
+    ctor public FontsContractCompat.FontRequestCallback();
+    method public void onTypefaceRequestFailed(@androidx.core.provider.FontsContractCompat.FontRequestCallback.FontRequestFailReason int);
+    method public void onTypefaceRetrieved(android.graphics.Typeface!);
+    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+    field public static final int FAIL_REASON_SECURITY_VIOLATION = -4; // 0xfffffffc
+    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
+    field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int RESULT_OK = 0; // 0x0
+  }
+
+  @IntDef({androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_FONT_UNAVAILABLE, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_MALFORMED_QUERY, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_SECURITY_VIOLATION, androidx.core.provider.FontsContractCompat.FontRequestCallback.RESULT_OK}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface FontsContractCompat.FontRequestCallback.FontRequestFailReason {
+  }
+
+  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SelfDestructiveThread {
+    ctor @Deprecated public SelfDestructiveThread(String!, int, int);
+    method @Deprecated @VisibleForTesting public int getGeneration();
+    method @Deprecated @VisibleForTesting public boolean isRunning();
+    method @Deprecated public <T> void postAndReply(java.util.concurrent.Callable<T!>!, androidx.core.provider.SelfDestructiveThread.ReplyCallback<T!>!);
+    method @Deprecated public <T> T! postAndWait(java.util.concurrent.Callable<T!>!, int) throws java.lang.InterruptedException;
+  }
+
+  @Deprecated public static interface SelfDestructiveThread.ReplyCallback<T> {
+    method @Deprecated public void onReply(T!);
+  }
+
+}
+
+package androidx.core.telephony {
+
+  @RequiresApi(22) public class SubscriptionManagerCompat {
+    method public static int getSlotIndex(int);
+  }
+
+  public class TelephonyManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static String? getImei(android.telephony.TelephonyManager);
+    method public static int getSubscriptionId(android.telephony.TelephonyManager);
+  }
+
+}
+
+package androidx.core.telephony.mbms {
+
+  public final class MbmsHelper {
+    method public static CharSequence? getBestNameForService(android.content.Context, android.telephony.mbms.ServiceInfo);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class BidiFormatter {
+    method public static androidx.core.text.BidiFormatter! getInstance();
+    method public static androidx.core.text.BidiFormatter! getInstance(boolean);
+    method public static androidx.core.text.BidiFormatter! getInstance(java.util.Locale!);
+    method public boolean getStereoReset();
+    method public boolean isRtl(String!);
+    method public boolean isRtl(CharSequence!);
+    method public boolean isRtlContext();
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public String! unicodeWrap(String!, boolean);
+    method public CharSequence! unicodeWrap(CharSequence!, boolean);
+    method public String! unicodeWrap(String!);
+    method public CharSequence! unicodeWrap(CharSequence!);
+  }
+
+  public static final class BidiFormatter.Builder {
+    ctor public BidiFormatter.Builder();
+    ctor public BidiFormatter.Builder(boolean);
+    ctor public BidiFormatter.Builder(java.util.Locale!);
+    method public androidx.core.text.BidiFormatter! build();
+    method public androidx.core.text.BidiFormatter.Builder! setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat!);
+    method public androidx.core.text.BidiFormatter.Builder! stereoReset(boolean);
+  }
+
+  public final class HtmlCompat {
+    method public static android.text.Spanned fromHtml(String, int);
+    method public static android.text.Spanned fromHtml(String, int, android.text.Html.ImageGetter?, android.text.Html.TagHandler?);
+    method public static String toHtml(android.text.Spanned, int);
+    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
+    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
+    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
+    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
+    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
+  }
+
+  public final class ICUCompat {
+    method public static String? maximizeAndGetScript(java.util.Locale);
+  }
+
+  public class PrecomputedTextCompat implements android.text.Spannable {
+    method public char charAt(int);
+    method public static androidx.core.text.PrecomputedTextCompat! create(CharSequence, androidx.core.text.PrecomputedTextCompat.Params);
+    method @IntRange(from=0) public int getParagraphCount();
+    method @IntRange(from=0) public int getParagraphEnd(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getParagraphStart(@IntRange(from=0) int);
+    method public androidx.core.text.PrecomputedTextCompat.Params getParams();
+    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.text.PrecomputedText? getPrecomputedText();
+    method public int getSpanEnd(Object!);
+    method public int getSpanFlags(Object!);
+    method public int getSpanStart(Object!);
+    method public <T> T![]! getSpans(int, int, Class<T!>!);
+    method @UiThread public static java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>! getTextFuture(CharSequence, androidx.core.text.PrecomputedTextCompat.Params, java.util.concurrent.Executor?);
+    method public int length();
+    method public int nextSpanTransition(int, int, Class!);
+    method public void removeSpan(Object!);
+    method public void setSpan(Object!, int, int, int);
+    method public CharSequence! subSequence(int, int);
+  }
+
+  public static final class PrecomputedTextCompat.Params {
+    ctor @RequiresApi(28) public PrecomputedTextCompat.Params(android.text.PrecomputedText.Params);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean equalsWithoutTextDirection(androidx.core.text.PrecomputedTextCompat.Params);
+    method @RequiresApi(23) public int getBreakStrategy();
+    method @RequiresApi(23) public int getHyphenationFrequency();
+    method @RequiresApi(18) public android.text.TextDirectionHeuristic? getTextDirection();
+    method public android.text.TextPaint getTextPaint();
+  }
+
+  public static class PrecomputedTextCompat.Params.Builder {
+    ctor public PrecomputedTextCompat.Params.Builder(android.text.TextPaint);
+    method public androidx.core.text.PrecomputedTextCompat.Params build();
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setBreakStrategy(int);
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setHyphenationFrequency(int);
+    method @RequiresApi(18) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setTextDirection(android.text.TextDirectionHeuristic);
+  }
+
+  public interface TextDirectionHeuristicCompat {
+    method public boolean isRtl(char[]!, int, int);
+    method public boolean isRtl(CharSequence!, int, int);
+  }
+
+  public final class TextDirectionHeuristicsCompat {
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! ANYRTL_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_RTL;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LOCALE;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! RTL;
+  }
+
+  public final class TextUtilsCompat {
+    method public static int getLayoutDirectionFromLocale(java.util.Locale?);
+    method public static String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.text.util {
+
+  public final class LinkifyCompat {
+    method public static boolean addLinks(android.text.Spannable, @androidx.core.text.util.LinkifyCompat.LinkifyMask int);
+    method public static boolean addLinks(android.widget.TextView, @androidx.core.text.util.LinkifyCompat.LinkifyMask int);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+  }
+
+  @IntDef(flag=true, value={android.text.util.Linkify.WEB_URLS, android.text.util.Linkify.EMAIL_ADDRESSES, android.text.util.Linkify.PHONE_NUMBERS, android.text.util.Linkify.MAP_ADDRESSES, android.text.util.Linkify.ALL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface LinkifyCompat.LinkifyMask {
+  }
+
+}
+
+package androidx.core.util {
+
+  public class AtomicFile {
+    ctor public AtomicFile(java.io.File);
+    method public void delete();
+    method public void failWrite(java.io.FileOutputStream?);
+    method public void finishWrite(java.io.FileOutputStream?);
+    method public java.io.File getBaseFile();
+    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
+    method public byte[] readFully() throws java.io.IOException;
+    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+  }
+
+  public interface Consumer<T> {
+    method public void accept(T!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DebugUtils {
+    method public static void buildShortClassTag(Object!, StringBuilder!);
+  }
+
+  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class LogWriter extends java.io.Writer {
+    ctor @Deprecated public LogWriter(String!);
+    method @Deprecated public void close();
+    method @Deprecated public void flush();
+    method @Deprecated public void write(char[]!, int, int);
+  }
+
+  public class ObjectsCompat {
+    method public static boolean equals(Object?, Object?);
+    method public static int hash(java.lang.Object!...);
+    method public static int hashCode(Object?);
+    method public static <T> T requireNonNull(T?);
+    method public static <T> T requireNonNull(T?, String);
+    method public static String? toString(Object?, String?);
+  }
+
+  public class Pair<F, S> {
+    ctor public Pair(F!, S!);
+    method public static <A, B> androidx.core.util.Pair<A!,B!> create(A!, B!);
+    field public final F! first;
+    field public final S! second;
+  }
+
+  public final class PatternsCompat {
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final java.util.regex.Pattern AUTOLINK_EMAIL_ADDRESS;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final java.util.regex.Pattern AUTOLINK_WEB_URL;
+    field public static final java.util.regex.Pattern DOMAIN_NAME;
+    field public static final java.util.regex.Pattern EMAIL_ADDRESS;
+    field public static final java.util.regex.Pattern IP_ADDRESS;
+    field public static final java.util.regex.Pattern WEB_URL;
+  }
+
+  public final class Pools {
+  }
+
+  public static interface Pools.Pool<T> {
+    method public T? acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SimplePool<T> implements androidx.core.util.Pools.Pool<T> {
+    ctor public Pools.SimplePool(int);
+    method public T! acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SynchronizedPool<T> extends androidx.core.util.Pools.SimplePool<T> {
+    ctor public Pools.SynchronizedPool(int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class Preconditions {
+    method public static void checkArgument(boolean);
+    method public static void checkArgument(boolean, Object);
+    method public static void checkArgument(boolean, String, java.lang.Object!...);
+    method public static float checkArgumentFinite(float, String);
+    method public static int checkArgumentInRange(int, int, int, String);
+    method public static long checkArgumentInRange(long, long, long, String);
+    method public static float checkArgumentInRange(float, float, float, String);
+    method public static double checkArgumentInRange(double, double, double, String);
+    method @IntRange(from=0) public static int checkArgumentNonnegative(int, String?);
+    method @IntRange(from=0) public static int checkArgumentNonnegative(int);
+    method public static int checkFlagsArgument(int, int);
+    method public static <T> T checkNotNull(T?);
+    method public static <T> T checkNotNull(T?, Object);
+    method public static void checkState(boolean, String?);
+    method public static void checkState(boolean);
+    method public static <T extends java.lang.CharSequence> T checkStringNotEmpty(T?);
+    method public static <T extends java.lang.CharSequence> T checkStringNotEmpty(T?, Object);
+    method public static <T extends java.lang.CharSequence> T checkStringNotEmpty(T?, String, java.lang.Object!...);
+  }
+
+  public interface Predicate<T> {
+    method public default androidx.core.util.Predicate<T!>! and(androidx.core.util.Predicate<? super T>!);
+    method public static <T> androidx.core.util.Predicate<T!>! isEqual(Object!);
+    method public default androidx.core.util.Predicate<T!>! negate();
+    method public static <T> androidx.core.util.Predicate<T!>! not(androidx.core.util.Predicate<? super T>!);
+    method public default androidx.core.util.Predicate<T!>! or(androidx.core.util.Predicate<? super T>!);
+    method public boolean test(T!);
+  }
+
+  public final class SizeFCompat {
+    ctor public SizeFCompat(float, float);
+    method public float getHeight();
+    method public float getWidth();
+    method @RequiresApi(21) public android.util.SizeF toSizeF();
+    method @RequiresApi(21) public static androidx.core.util.SizeFCompat toSizeFCompat(android.util.SizeF);
+  }
+
+  public interface Supplier<T> {
+    method public T! get();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class TimeUtils {
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, StringBuilder!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, java.io.PrintWriter!, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, java.io.PrintWriter!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, long, java.io.PrintWriter!);
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int HUNDRED_DAY_FIELD_LEN = 19; // 0x13
+  }
+
+}
+
+package androidx.core.view {
+
+  public class AccessibilityDelegateCompat {
+    ctor public AccessibilityDelegateCompat();
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public AccessibilityDelegateCompat(android.view.View.AccessibilityDelegate);
+    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public void sendAccessibilityEvent(android.view.View, int);
+    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+  }
+
+  public abstract class ActionProvider {
+    ctor public ActionProvider(android.content.Context);
+    method public android.content.Context getContext();
+    method public boolean hasSubMenu();
+    method public boolean isVisible();
+    method public abstract android.view.View onCreateActionView();
+    method public android.view.View onCreateActionView(android.view.MenuItem);
+    method public boolean onPerformDefaultAction();
+    method public void onPrepareSubMenu(android.view.SubMenu);
+    method public boolean overridesItemVisibility();
+    method public void refreshVisibility();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void reset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSubUiVisibilityListener(androidx.core.view.ActionProvider.SubUiVisibilityListener?);
+    method public void setVisibilityListener(androidx.core.view.ActionProvider.VisibilityListener?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void subUiVisibilityChanged(boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface ActionProvider.SubUiVisibilityListener {
+    method public void onSubUiVisibilityChanged(boolean);
+  }
+
+  public static interface ActionProvider.VisibilityListener {
+    method public void onActionProviderVisibilityChanged(boolean);
+  }
+
+  public final class ContentInfoCompat {
+    method public android.content.ClipData getClip();
+    method public android.os.Bundle? getExtras();
+    method @androidx.core.view.ContentInfoCompat.Flags public int getFlags();
+    method public android.net.Uri? getLinkUri();
+    method @androidx.core.view.ContentInfoCompat.Source public int getSource();
+    method public android.util.Pair<androidx.core.view.ContentInfoCompat!,androidx.core.view.ContentInfoCompat!> partition(androidx.core.util.Predicate<android.content.ClipData.Item!>);
+    method @RequiresApi(31) public static android.util.Pair<android.view.ContentInfo!,android.view.ContentInfo!> partition(android.view.ContentInfo, java.util.function.Predicate<android.content.ClipData.Item!>);
+    method @RequiresApi(31) public android.view.ContentInfo toContentInfo();
+    method @RequiresApi(31) public static androidx.core.view.ContentInfoCompat toContentInfoCompat(android.view.ContentInfo);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_APP = 0; // 0x0
+    field public static final int SOURCE_AUTOFILL = 4; // 0x4
+    field public static final int SOURCE_CLIPBOARD = 1; // 0x1
+    field public static final int SOURCE_DRAG_AND_DROP = 3; // 0x3
+    field public static final int SOURCE_INPUT_METHOD = 2; // 0x2
+    field public static final int SOURCE_PROCESS_TEXT = 5; // 0x5
+  }
+
+  public static final class ContentInfoCompat.Builder {
+    ctor public ContentInfoCompat.Builder(androidx.core.view.ContentInfoCompat);
+    ctor public ContentInfoCompat.Builder(android.content.ClipData, @androidx.core.view.ContentInfoCompat.Source int);
+    method public androidx.core.view.ContentInfoCompat build();
+    method public androidx.core.view.ContentInfoCompat.Builder setClip(android.content.ClipData);
+    method public androidx.core.view.ContentInfoCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.view.ContentInfoCompat.Builder setFlags(@androidx.core.view.ContentInfoCompat.Flags int);
+    method public androidx.core.view.ContentInfoCompat.Builder setLinkUri(android.net.Uri?);
+    method public androidx.core.view.ContentInfoCompat.Builder setSource(@androidx.core.view.ContentInfoCompat.Source int);
+  }
+
+  @IntDef(flag=true, value={androidx.core.view.ContentInfoCompat.FLAG_CONVERT_TO_PLAIN_TEXT}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ContentInfoCompat.Flags {
+  }
+
+  @IntDef({androidx.core.view.ContentInfoCompat.SOURCE_APP, androidx.core.view.ContentInfoCompat.SOURCE_CLIPBOARD, androidx.core.view.ContentInfoCompat.SOURCE_INPUT_METHOD, androidx.core.view.ContentInfoCompat.SOURCE_DRAG_AND_DROP, androidx.core.view.ContentInfoCompat.SOURCE_AUTOFILL, androidx.core.view.ContentInfoCompat.SOURCE_PROCESS_TEXT}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ContentInfoCompat.Source {
+  }
+
+  public final class DisplayCompat {
+    method public static androidx.core.view.DisplayCompat.ModeCompat getMode(android.content.Context, android.view.Display);
+    method public static androidx.core.view.DisplayCompat.ModeCompat![] getSupportedModes(android.content.Context, android.view.Display);
+  }
+
+  public static final class DisplayCompat.ModeCompat {
+    method public int getPhysicalHeight();
+    method public int getPhysicalWidth();
+    method @Deprecated public boolean isNative();
+    method @RequiresApi(android.os.Build.VERSION_CODES.M) public android.view.Display.Mode? toMode();
+  }
+
+  public final class DisplayCutoutCompat {
+    ctor public DisplayCutoutCompat(android.graphics.Rect?, java.util.List<android.graphics.Rect!>?);
+    ctor public DisplayCutoutCompat(androidx.core.graphics.Insets, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, androidx.core.graphics.Insets);
+    method public java.util.List<android.graphics.Rect!> getBoundingRects();
+    method public int getSafeInsetBottom();
+    method public int getSafeInsetLeft();
+    method public int getSafeInsetRight();
+    method public int getSafeInsetTop();
+    method public androidx.core.graphics.Insets getWaterfallInsets();
+  }
+
+  public final class DragAndDropPermissionsCompat {
+    method public void release();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.view.DragAndDropPermissionsCompat? request(android.app.Activity, android.view.DragEvent);
+  }
+
+  public class DragStartHelper {
+    ctor public DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener);
+    method public void attach();
+    method public void detach();
+    method public void getTouchPosition(android.graphics.Point);
+    method public boolean onLongClick(android.view.View);
+    method public boolean onTouch(android.view.View, android.view.MotionEvent);
+  }
+
+  public static interface DragStartHelper.OnDragStartListener {
+    method public boolean onDragStart(android.view.View, androidx.core.view.DragStartHelper);
+  }
+
+  public final class GestureDetectorCompat {
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler?);
+    method public boolean isLongpressEnabled();
+    method public boolean onTouchEvent(android.view.MotionEvent);
+    method public void setIsLongpressEnabled(boolean);
+    method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener?);
+  }
+
+  public final class GravityCompat {
+    method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
+    method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static int getAbsoluteGravity(int, int);
+    field public static final int END = 8388613; // 0x800005
+    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
+    field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
+    field public static final int START = 8388611; // 0x800003
+  }
+
+  public final class InputDeviceCompat {
+    field public static final int SOURCE_ANY = -256; // 0xffffff00
+    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
+    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
+    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
+    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
+    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
+    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
+    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
+    field public static final int SOURCE_DPAD = 513; // 0x201
+    field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
+    field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
+    field public static final int SOURCE_KEYBOARD = 257; // 0x101
+    field public static final int SOURCE_MOUSE = 8194; // 0x2002
+    field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
+    field public static final int SOURCE_STYLUS = 16386; // 0x4002
+    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
+    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
+    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
+    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
+    field public static final int SOURCE_UNKNOWN = 0; // 0x0
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class KeyEventDispatcher {
+    method public static boolean dispatchBeforeHierarchy(android.view.View, android.view.KeyEvent);
+    method public static boolean dispatchKeyEvent(androidx.core.view.KeyEventDispatcher.Component, android.view.View?, android.view.Window.Callback?, android.view.KeyEvent);
+  }
+
+  public static interface KeyEventDispatcher.Component {
+    method public boolean superDispatchKeyEvent(android.view.KeyEvent);
+  }
+
+  public final class LayoutInflaterCompat {
+    method @Deprecated public static androidx.core.view.LayoutInflaterFactory! getFactory(android.view.LayoutInflater!);
+    method @Deprecated public static void setFactory(android.view.LayoutInflater, androidx.core.view.LayoutInflaterFactory);
+    method public static void setFactory2(android.view.LayoutInflater, android.view.LayoutInflater.Factory2);
+  }
+
+  @Deprecated public interface LayoutInflaterFactory {
+    method @Deprecated public android.view.View! onCreateView(android.view.View!, String!, android.content.Context!, android.util.AttributeSet!);
+  }
+
+  public final class MarginLayoutParamsCompat {
+    method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
+    method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
+    method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
+  }
+
+  public final class MenuCompat {
+    method public static void setGroupDividerEnabled(android.view.Menu, boolean);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+  }
+
+  public interface MenuHost {
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void invalidateMenu();
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public class MenuHostHelper {
+    ctor public MenuHostHelper(Runnable);
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public void onPrepareMenu(android.view.Menu);
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public final class MenuItemCompat {
+    method @Deprecated public static boolean collapseActionView(android.view.MenuItem!);
+    method @Deprecated public static boolean expandActionView(android.view.MenuItem!);
+    method public static androidx.core.view.ActionProvider? getActionProvider(android.view.MenuItem);
+    method @Deprecated public static android.view.View! getActionView(android.view.MenuItem!);
+    method public static int getAlphabeticModifiers(android.view.MenuItem);
+    method public static CharSequence? getContentDescription(android.view.MenuItem);
+    method public static android.content.res.ColorStateList? getIconTintList(android.view.MenuItem);
+    method public static android.graphics.PorterDuff.Mode? getIconTintMode(android.view.MenuItem);
+    method public static int getNumericModifiers(android.view.MenuItem);
+    method public static CharSequence? getTooltipText(android.view.MenuItem);
+    method @Deprecated public static boolean isActionViewExpanded(android.view.MenuItem!);
+    method public static android.view.MenuItem? setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider?);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, android.view.View!);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, int);
+    method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
+    method public static void setContentDescription(android.view.MenuItem, CharSequence?);
+    method public static void setIconTintList(android.view.MenuItem, android.content.res.ColorStateList?);
+    method public static void setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode?);
+    method public static void setNumericShortcut(android.view.MenuItem, char, int);
+    method @Deprecated public static android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem!, androidx.core.view.MenuItemCompat.OnActionExpandListener!);
+    method public static void setShortcut(android.view.MenuItem, char, char, int, int);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+    method public static void setTooltipText(android.view.MenuItem, CharSequence?);
+    field @Deprecated public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+    field @Deprecated public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+    field @Deprecated public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+    field @Deprecated public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+    field @Deprecated public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+  }
+
+  @Deprecated public static interface MenuItemCompat.OnActionExpandListener {
+    method @Deprecated public boolean onMenuItemActionCollapse(android.view.MenuItem!);
+    method @Deprecated public boolean onMenuItemActionExpand(android.view.MenuItem!);
+  }
+
+  public interface MenuProvider {
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public default void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public default void onPrepareMenu(android.view.Menu);
+  }
+
+  public final class MotionEventCompat {
+    method @Deprecated public static int findPointerIndex(android.view.MotionEvent!, int);
+    method @Deprecated public static int getActionIndex(android.view.MotionEvent!);
+    method @Deprecated public static int getActionMasked(android.view.MotionEvent!);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int, int);
+    method @Deprecated public static int getButtonState(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerCount(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerId(android.view.MotionEvent!, int);
+    method @Deprecated public static int getSource(android.view.MotionEvent!);
+    method @Deprecated public static float getX(android.view.MotionEvent!, int);
+    method @Deprecated public static float getY(android.view.MotionEvent!, int);
+    method public static boolean isFromSource(android.view.MotionEvent, int);
+    field @Deprecated public static final int ACTION_HOVER_ENTER = 9; // 0x9
+    field @Deprecated public static final int ACTION_HOVER_EXIT = 10; // 0xa
+    field @Deprecated public static final int ACTION_HOVER_MOVE = 7; // 0x7
+    field @Deprecated public static final int ACTION_MASK = 255; // 0xff
+    field @Deprecated public static final int ACTION_POINTER_DOWN = 5; // 0x5
+    field @Deprecated public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
+    field @Deprecated public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+    field @Deprecated public static final int ACTION_POINTER_UP = 6; // 0x6
+    field @Deprecated public static final int ACTION_SCROLL = 8; // 0x8
+    field @Deprecated public static final int AXIS_BRAKE = 23; // 0x17
+    field @Deprecated public static final int AXIS_DISTANCE = 24; // 0x18
+    field @Deprecated public static final int AXIS_GAS = 22; // 0x16
+    field @Deprecated public static final int AXIS_GENERIC_1 = 32; // 0x20
+    field @Deprecated public static final int AXIS_GENERIC_10 = 41; // 0x29
+    field @Deprecated public static final int AXIS_GENERIC_11 = 42; // 0x2a
+    field @Deprecated public static final int AXIS_GENERIC_12 = 43; // 0x2b
+    field @Deprecated public static final int AXIS_GENERIC_13 = 44; // 0x2c
+    field @Deprecated public static final int AXIS_GENERIC_14 = 45; // 0x2d
+    field @Deprecated public static final int AXIS_GENERIC_15 = 46; // 0x2e
+    field @Deprecated public static final int AXIS_GENERIC_16 = 47; // 0x2f
+    field @Deprecated public static final int AXIS_GENERIC_2 = 33; // 0x21
+    field @Deprecated public static final int AXIS_GENERIC_3 = 34; // 0x22
+    field @Deprecated public static final int AXIS_GENERIC_4 = 35; // 0x23
+    field @Deprecated public static final int AXIS_GENERIC_5 = 36; // 0x24
+    field @Deprecated public static final int AXIS_GENERIC_6 = 37; // 0x25
+    field @Deprecated public static final int AXIS_GENERIC_7 = 38; // 0x26
+    field @Deprecated public static final int AXIS_GENERIC_8 = 39; // 0x27
+    field @Deprecated public static final int AXIS_GENERIC_9 = 40; // 0x28
+    field @Deprecated public static final int AXIS_HAT_X = 15; // 0xf
+    field @Deprecated public static final int AXIS_HAT_Y = 16; // 0x10
+    field @Deprecated public static final int AXIS_HSCROLL = 10; // 0xa
+    field @Deprecated public static final int AXIS_LTRIGGER = 17; // 0x11
+    field @Deprecated public static final int AXIS_ORIENTATION = 8; // 0x8
+    field @Deprecated public static final int AXIS_PRESSURE = 2; // 0x2
+    field public static final int AXIS_RELATIVE_X = 27; // 0x1b
+    field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
+    field @Deprecated public static final int AXIS_RTRIGGER = 18; // 0x12
+    field @Deprecated public static final int AXIS_RUDDER = 20; // 0x14
+    field @Deprecated public static final int AXIS_RX = 12; // 0xc
+    field @Deprecated public static final int AXIS_RY = 13; // 0xd
+    field @Deprecated public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SCROLL = 26; // 0x1a
+    field @Deprecated public static final int AXIS_SIZE = 3; // 0x3
+    field @Deprecated public static final int AXIS_THROTTLE = 19; // 0x13
+    field @Deprecated public static final int AXIS_TILT = 25; // 0x19
+    field @Deprecated public static final int AXIS_TOOL_MAJOR = 6; // 0x6
+    field @Deprecated public static final int AXIS_TOOL_MINOR = 7; // 0x7
+    field @Deprecated public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
+    field @Deprecated public static final int AXIS_TOUCH_MINOR = 5; // 0x5
+    field @Deprecated public static final int AXIS_VSCROLL = 9; // 0x9
+    field @Deprecated public static final int AXIS_WHEEL = 21; // 0x15
+    field @Deprecated public static final int AXIS_X = 0; // 0x0
+    field @Deprecated public static final int AXIS_Y = 1; // 0x1
+    field @Deprecated public static final int AXIS_Z = 11; // 0xb
+    field @Deprecated public static final int BUTTON_PRIMARY = 1; // 0x1
+  }
+
+  public interface NestedScrollingChild {
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean isNestedScrollingEnabled();
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int);
+    method public void stopNestedScroll();
+  }
+
+  public interface NestedScrollingChild2 extends androidx.core.view.NestedScrollingChild {
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public boolean hasNestedScrollingParent(@androidx.core.view.ViewCompat.NestedScrollType int);
+    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public void stopNestedScroll(@androidx.core.view.ViewCompat.NestedScrollType int);
+  }
+
+  public interface NestedScrollingChild3 extends androidx.core.view.NestedScrollingChild2 {
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int, int[]);
+  }
+
+  public class NestedScrollingChildHelper {
+    ctor public NestedScrollingChildHelper(android.view.View);
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean hasNestedScrollingParent(@androidx.core.view.ViewCompat.NestedScrollType int);
+    method public boolean isNestedScrollingEnabled();
+    method public void onDetachedFromWindow();
+    method public void onStopNestedScroll(android.view.View);
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int);
+    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public void stopNestedScroll();
+    method public void stopNestedScroll(@androidx.core.view.ViewCompat.NestedScrollType int);
+  }
+
+  public interface NestedScrollingParent {
+    method @androidx.core.view.ViewCompat.ScrollAxis public int getNestedScrollAxes();
+    method public boolean onNestedFling(android.view.View, float, float, boolean);
+    method public boolean onNestedPreFling(android.view.View, float, float);
+    method public void onNestedPreScroll(android.view.View, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
+    method public void onStopNestedScroll(android.view.View);
+  }
+
+  public interface NestedScrollingParent2 extends androidx.core.view.NestedScrollingParent {
+    method public void onNestedPreScroll(android.view.View, int, int, int[], @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public void onStopNestedScroll(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
+  }
+
+  public interface NestedScrollingParent3 extends androidx.core.view.NestedScrollingParent2 {
+    method public void onNestedScroll(android.view.View, int, int, int, int, @androidx.core.view.ViewCompat.NestedScrollType int, int[]);
+  }
+
+  public class NestedScrollingParentHelper {
+    ctor public NestedScrollingParentHelper(android.view.ViewGroup);
+    method @androidx.core.view.ViewCompat.ScrollAxis public int getNestedScrollAxes();
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public void onStopNestedScroll(android.view.View);
+    method public void onStopNestedScroll(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
+  }
+
+  public interface OnApplyWindowInsetsListener {
+    method public androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+  }
+
+  public interface OnReceiveContentListener {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+  }
+
+  public interface OnReceiveContentViewBehavior {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
+  }
+
+  public final class OneShotPreDrawListener implements android.view.View.OnAttachStateChangeListener android.view.ViewTreeObserver.OnPreDrawListener {
+    method public static androidx.core.view.OneShotPreDrawListener add(android.view.View, Runnable);
+    method public boolean onPreDraw();
+    method public void onViewAttachedToWindow(android.view.View);
+    method public void onViewDetachedFromWindow(android.view.View);
+    method public void removeListener();
+  }
+
+  public final class PointerIconCompat {
+    method public static androidx.core.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public Object? getPointerIcon();
+    method public static androidx.core.view.PointerIconCompat getSystemIcon(android.content.Context, int);
+    method public static androidx.core.view.PointerIconCompat load(android.content.res.Resources, int);
+    field public static final int TYPE_ALIAS = 1010; // 0x3f2
+    field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
+    field public static final int TYPE_ARROW = 1000; // 0x3e8
+    field public static final int TYPE_CELL = 1006; // 0x3ee
+    field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
+    field public static final int TYPE_COPY = 1011; // 0x3f3
+    field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
+    field public static final int TYPE_DEFAULT = 1000; // 0x3e8
+    field public static final int TYPE_GRAB = 1020; // 0x3fc
+    field public static final int TYPE_GRABBING = 1021; // 0x3fd
+    field public static final int TYPE_HAND = 1002; // 0x3ea
+    field public static final int TYPE_HELP = 1003; // 0x3eb
+    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
+    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
+    field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_TEXT = 1008; // 0x3f0
+    field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
+    field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
+    field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
+    field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
+    field public static final int TYPE_WAIT = 1004; // 0x3ec
+    field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
+    field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
+  }
+
+  public final class ScaleGestureDetectorCompat {
+    method @Deprecated public static boolean isQuickScaleEnabled(Object!);
+    method public static boolean isQuickScaleEnabled(android.view.ScaleGestureDetector);
+    method @Deprecated public static void setQuickScaleEnabled(Object!, boolean);
+    method public static void setQuickScaleEnabled(android.view.ScaleGestureDetector, boolean);
+  }
+
+  public interface ScrollingView {
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+  }
+
+  public interface TintableBackgroundView {
+    method public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  @Deprecated public final class VelocityTrackerCompat {
+    method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
+    method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
+  }
+
+  public class ViewCompat {
+    ctor @Deprecated protected ViewCompat();
+    method public static int addAccessibilityAction(android.view.View, CharSequence, androidx.core.view.accessibility.AccessibilityViewCommand);
+    method public static void addKeyboardNavigationClusters(android.view.View, java.util.Collection<android.view.View!>, int);
+    method public static void addOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static androidx.core.view.ViewPropertyAnimatorCompat animate(android.view.View);
+    method @Deprecated public static boolean canScrollHorizontally(android.view.View!, int);
+    method @Deprecated public static boolean canScrollVertically(android.view.View!, int);
+    method public static void cancelDragAndDrop(android.view.View);
+    method @Deprecated public static int combineMeasuredStates(int, int);
+    method public static androidx.core.view.WindowInsetsCompat computeSystemWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat, android.graphics.Rect);
+    method public static androidx.core.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method public static void dispatchFinishTemporaryDetach(android.view.View);
+    method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
+    method public static boolean dispatchNestedPreFling(android.view.View, float, float);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?);
+    method public static void dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int, int[]);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public static void dispatchStartTemporaryDetach(android.view.View);
+    method public static void enableAccessibleClickableSpanSupport(android.view.View);
+    method public static int generateViewId();
+    method public static androidx.core.view.AccessibilityDelegateCompat? getAccessibilityDelegate(android.view.View);
+    method public static int getAccessibilityLiveRegion(android.view.View);
+    method public static androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method @UiThread public static CharSequence? getAccessibilityPaneTitle(android.view.View);
+    method @Deprecated public static float getAlpha(android.view.View!);
+    method public static android.content.res.ColorStateList? getBackgroundTintList(android.view.View);
+    method public static android.graphics.PorterDuff.Mode? getBackgroundTintMode(android.view.View);
+    method public static android.graphics.Rect? getClipBounds(android.view.View);
+    method public static android.view.Display? getDisplay(android.view.View);
+    method public static float getElevation(android.view.View);
+    method public static boolean getFitsSystemWindows(android.view.View);
+    method public static int getImportantForAccessibility(android.view.View);
+    method public static int getImportantForAutofill(android.view.View);
+    method public static int getLabelFor(android.view.View);
+    method @Deprecated public static int getLayerType(android.view.View!);
+    method public static int getLayoutDirection(android.view.View);
+    method @Deprecated public static android.graphics.Matrix? getMatrix(android.view.View!);
+    method @Deprecated public static int getMeasuredHeightAndState(android.view.View!);
+    method @Deprecated public static int getMeasuredState(android.view.View!);
+    method @Deprecated public static int getMeasuredWidthAndState(android.view.View!);
+    method public static int getMinimumHeight(android.view.View);
+    method public static int getMinimumWidth(android.view.View);
+    method public static int getNextClusterForwardId(android.view.View);
+    method public static String![]? getOnReceiveContentMimeTypes(android.view.View);
+    method @Deprecated public static int getOverScrollMode(android.view.View!);
+    method @Px public static int getPaddingEnd(android.view.View);
+    method @Px public static int getPaddingStart(android.view.View);
+    method public static android.view.ViewParent? getParentForAccessibility(android.view.View);
+    method @Deprecated public static float getPivotX(android.view.View!);
+    method @Deprecated public static float getPivotY(android.view.View!);
+    method public static androidx.core.view.WindowInsetsCompat? getRootWindowInsets(android.view.View);
+    method @Deprecated public static float getRotation(android.view.View!);
+    method @Deprecated public static float getRotationX(android.view.View!);
+    method @Deprecated public static float getRotationY(android.view.View!);
+    method @Deprecated public static float getScaleX(android.view.View!);
+    method @Deprecated public static float getScaleY(android.view.View!);
+    method public static int getScrollIndicators(android.view.View);
+    method @UiThread public static CharSequence? getStateDescription(android.view.View);
+    method public static java.util.List<android.graphics.Rect!> getSystemGestureExclusionRects(android.view.View);
+    method public static String? getTransitionName(android.view.View);
+    method @Deprecated public static float getTranslationX(android.view.View!);
+    method @Deprecated public static float getTranslationY(android.view.View!);
+    method public static float getTranslationZ(android.view.View);
+    method @Deprecated public static androidx.core.view.WindowInsetsControllerCompat? getWindowInsetsController(android.view.View);
+    method @Deprecated public static int getWindowSystemUiVisibility(android.view.View);
+    method @Deprecated public static float getX(android.view.View!);
+    method @Deprecated public static float getY(android.view.View!);
+    method public static float getZ(android.view.View);
+    method public static boolean hasAccessibilityDelegate(android.view.View);
+    method public static boolean hasExplicitFocusable(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public static boolean hasOnClickListeners(android.view.View);
+    method public static boolean hasOverlappingRendering(android.view.View);
+    method public static boolean hasTransientState(android.view.View);
+    method @UiThread public static boolean isAccessibilityHeading(android.view.View);
+    method public static boolean isAttachedToWindow(android.view.View);
+    method public static boolean isFocusedByDefault(android.view.View);
+    method public static boolean isImportantForAccessibility(android.view.View);
+    method public static boolean isImportantForAutofill(android.view.View);
+    method public static boolean isInLayout(android.view.View);
+    method public static boolean isKeyboardNavigationCluster(android.view.View);
+    method public static boolean isLaidOut(android.view.View);
+    method public static boolean isLayoutDirectionResolved(android.view.View);
+    method public static boolean isNestedScrollingEnabled(android.view.View);
+    method @Deprecated public static boolean isOpaque(android.view.View!);
+    method public static boolean isPaddingRelative(android.view.View);
+    method @UiThread public static boolean isScreenReaderFocusable(android.view.View);
+    method @Deprecated public static void jumpDrawablesToCurrentState(android.view.View!);
+    method public static android.view.View? keyboardNavigationClusterSearch(android.view.View, android.view.View?, @androidx.core.view.ViewCompat.FocusDirection int);
+    method public static void offsetLeftAndRight(android.view.View, int);
+    method public static void offsetTopAndBottom(android.view.View, int);
+    method public static androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method @Deprecated public static void onInitializeAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+    method public static void postInvalidateOnAnimation(android.view.View);
+    method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
+    method public static void postOnAnimation(android.view.View, Runnable);
+    method public static void postOnAnimationDelayed(android.view.View, Runnable, long);
+    method public static void removeAccessibilityAction(android.view.View, int);
+    method public static void removeOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static void replaceAccessibilityAction(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat, CharSequence?, androidx.core.view.accessibility.AccessibilityViewCommand?);
+    method public static void requestApplyInsets(android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.View, @IdRes int);
+    method @Deprecated public static int resolveSizeAndState(int, int, int);
+    method public static boolean restoreDefaultFocus(android.view.View);
+    method public static void saveAttributeDataForStyleable(android.view.View, android.content.Context, int[], android.util.AttributeSet?, android.content.res.TypedArray, int, int);
+    method public static void setAccessibilityDelegate(android.view.View, androidx.core.view.AccessibilityDelegateCompat?);
+    method @UiThread public static void setAccessibilityHeading(android.view.View, boolean);
+    method public static void setAccessibilityLiveRegion(android.view.View, int);
+    method @UiThread public static void setAccessibilityPaneTitle(android.view.View, CharSequence?);
+    method @Deprecated public static void setActivated(android.view.View!, boolean);
+    method @Deprecated public static void setAlpha(android.view.View!, @FloatRange(from=0.0, to=1.0) float);
+    method public static void setAutofillHints(android.view.View, java.lang.String!...);
+    method public static void setBackground(android.view.View, android.graphics.drawable.Drawable?);
+    method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList?);
+    method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode?);
+    method @Deprecated public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup!, boolean);
+    method public static void setClipBounds(android.view.View, android.graphics.Rect?);
+    method public static void setElevation(android.view.View, float);
+    method @Deprecated public static void setFitsSystemWindows(android.view.View!, boolean);
+    method public static void setFocusedByDefault(android.view.View, boolean);
+    method public static void setHasTransientState(android.view.View, boolean);
+    method @UiThread public static void setImportantForAccessibility(android.view.View, int);
+    method public static void setImportantForAutofill(android.view.View, int);
+    method public static void setKeyboardNavigationCluster(android.view.View, boolean);
+    method public static void setLabelFor(android.view.View, @IdRes int);
+    method public static void setLayerPaint(android.view.View, android.graphics.Paint?);
+    method @Deprecated public static void setLayerType(android.view.View!, int, android.graphics.Paint!);
+    method public static void setLayoutDirection(android.view.View, int);
+    method public static void setNestedScrollingEnabled(android.view.View, boolean);
+    method public static void setNextClusterForwardId(android.view.View, int);
+    method public static void setOnApplyWindowInsetsListener(android.view.View, androidx.core.view.OnApplyWindowInsetsListener?);
+    method public static void setOnReceiveContentListener(android.view.View, String![]?, androidx.core.view.OnReceiveContentListener?);
+    method @Deprecated public static void setOverScrollMode(android.view.View!, int);
+    method public static void setPaddingRelative(android.view.View, @Px int, @Px int, @Px int, @Px int);
+    method @Deprecated public static void setPivotX(android.view.View!, float);
+    method @Deprecated public static void setPivotY(android.view.View!, float);
+    method public static void setPointerIcon(android.view.View, androidx.core.view.PointerIconCompat?);
+    method @Deprecated public static void setRotation(android.view.View!, float);
+    method @Deprecated public static void setRotationX(android.view.View!, float);
+    method @Deprecated public static void setRotationY(android.view.View!, float);
+    method @Deprecated public static void setSaveFromParentEnabled(android.view.View!, boolean);
+    method @Deprecated public static void setScaleX(android.view.View!, float);
+    method @Deprecated public static void setScaleY(android.view.View!, float);
+    method @UiThread public static void setScreenReaderFocusable(android.view.View, boolean);
+    method public static void setScrollIndicators(android.view.View, @androidx.core.view.ViewCompat.ScrollIndicators int);
+    method public static void setScrollIndicators(android.view.View, @androidx.core.view.ViewCompat.ScrollIndicators int, @androidx.core.view.ViewCompat.ScrollIndicators int);
+    method @UiThread public static void setStateDescription(android.view.View, CharSequence?);
+    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect!>);
+    method public static void setTooltipText(android.view.View, CharSequence?);
+    method public static void setTransitionName(android.view.View, String?);
+    method @Deprecated public static void setTranslationX(android.view.View!, float);
+    method @Deprecated public static void setTranslationY(android.view.View!, float);
+    method public static void setTranslationZ(android.view.View, float);
+    method public static void setWindowInsetsAnimationCallback(android.view.View, androidx.core.view.WindowInsetsAnimationCompat.Callback?);
+    method @Deprecated public static void setX(android.view.View!, float);
+    method @Deprecated public static void setY(android.view.View!, float);
+    method public static void setZ(android.view.View, float);
+    method public static boolean startDragAndDrop(android.view.View, android.content.ClipData?, android.view.View.DragShadowBuilder, Object?, int);
+    method public static boolean startNestedScroll(android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
+    method public static boolean startNestedScroll(android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public static void stopNestedScroll(android.view.View);
+    method public static void stopNestedScroll(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
+    method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
+    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
+    field @Deprecated public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
+    field @Deprecated public static final int LAYER_TYPE_NONE = 0; // 0x0
+    field @Deprecated public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
+    field @Deprecated public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+    field @Deprecated public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+    field @Deprecated public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
+    field @Deprecated public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+    field @Deprecated public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
+    field @Deprecated public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
+    field @Deprecated public static final int OVER_SCROLL_NEVER = 2; // 0x2
+    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+    field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+    field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+    field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
+    field public static final int TYPE_NON_TOUCH = 1; // 0x1
+    field public static final int TYPE_TOUCH = 0; // 0x0
+  }
+
+  @IntDef({android.view.View.FOCUS_LEFT, android.view.View.FOCUS_UP, android.view.View.FOCUS_RIGHT, android.view.View.FOCUS_DOWN, android.view.View.FOCUS_FORWARD, android.view.View.FOCUS_BACKWARD}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.FocusDirection {
+  }
+
+  @IntDef({android.view.View.FOCUS_LEFT, android.view.View.FOCUS_UP, android.view.View.FOCUS_RIGHT, android.view.View.FOCUS_DOWN}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.FocusRealDirection {
+  }
+
+  @IntDef({android.view.View.FOCUS_FORWARD, android.view.View.FOCUS_BACKWARD}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.FocusRelativeDirection {
+  }
+
+  @IntDef({androidx.core.view.ViewCompat.TYPE_TOUCH, androidx.core.view.ViewCompat.TYPE_NON_TOUCH}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.NestedScrollType {
+  }
+
+  public static interface ViewCompat.OnUnhandledKeyEventListenerCompat {
+    method public boolean onUnhandledKeyEvent(android.view.View, android.view.KeyEvent);
+  }
+
+  @IntDef(value={androidx.core.view.ViewCompat.SCROLL_AXIS_NONE, androidx.core.view.ViewCompat.SCROLL_AXIS_HORIZONTAL, androidx.core.view.ViewCompat.SCROLL_AXIS_VERTICAL}, flag=true) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.ScrollAxis {
+  }
+
+  @IntDef(flag=true, value={androidx.core.view.ViewCompat.SCROLL_INDICATOR_TOP, androidx.core.view.ViewCompat.SCROLL_INDICATOR_BOTTOM, androidx.core.view.ViewCompat.SCROLL_INDICATOR_LEFT, androidx.core.view.ViewCompat.SCROLL_INDICATOR_RIGHT, androidx.core.view.ViewCompat.SCROLL_INDICATOR_START, androidx.core.view.ViewCompat.SCROLL_INDICATOR_END}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.ScrollIndicators {
+  }
+
+  public final class ViewConfigurationCompat {
+    method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method public static int getScaledHoverSlop(android.view.ViewConfiguration);
+    method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
+    method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
+    method public static boolean shouldShowMenuShortcutsWhenKeyboardPresent(android.view.ViewConfiguration, android.content.Context);
+  }
+
+  public final class ViewGroupCompat {
+    method public static int getLayoutMode(android.view.ViewGroup);
+    method @androidx.core.view.ViewCompat.ScrollAxis public static int getNestedScrollAxes(android.view.ViewGroup);
+    method public static boolean isTransitionGroup(android.view.ViewGroup);
+    method @Deprecated public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void setLayoutMode(android.view.ViewGroup, int);
+    method @Deprecated public static void setMotionEventSplittingEnabled(android.view.ViewGroup!, boolean);
+    method public static void setTransitionGroup(android.view.ViewGroup, boolean);
+    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
+  }
+
+  public final class ViewParentCompat {
+    method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
+    method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View, int);
+    method @Deprecated public static boolean requestSendAccessibilityEvent(android.view.ViewParent!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+  }
+
+  public final class ViewPropertyAnimatorCompat {
+    method public androidx.core.view.ViewPropertyAnimatorCompat alpha(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat alphaBy(float);
+    method public void cancel();
+    method public long getDuration();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public long getStartDelay();
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotation(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setDuration(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setListener(androidx.core.view.ViewPropertyAnimatorListener?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setStartDelay(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener?);
+    method public void start();
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZ(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withEndAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withLayer();
+    method public androidx.core.view.ViewPropertyAnimatorCompat withStartAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat x(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat xBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat y(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat yBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat z(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat zBy(float);
+  }
+
+  public interface ViewPropertyAnimatorListener {
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public class ViewPropertyAnimatorListenerAdapter implements androidx.core.view.ViewPropertyAnimatorListener {
+    ctor public ViewPropertyAnimatorListenerAdapter();
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public interface ViewPropertyAnimatorUpdateListener {
+    method public void onAnimationUpdate(android.view.View);
+  }
+
+  public final class WindowCompat {
+    method public static androidx.core.view.WindowInsetsControllerCompat getInsetsController(android.view.Window, android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
+    method public static void setDecorFitsSystemWindows(android.view.Window, boolean);
+    field public static final int FEATURE_ACTION_BAR = 8; // 0x8
+    field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+  }
+
+  public final class WindowInsetsAnimationCompat {
+    ctor public WindowInsetsAnimationCompat(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, android.view.animation.Interpolator?, long);
+    method @FloatRange(from=0.0f, to=1.0f) public float getAlpha();
+    method public long getDurationMillis();
+    method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
+    method public float getInterpolatedFraction();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public int getTypeMask();
+    method public void setAlpha(@FloatRange(from=0.0f, to=1.0f) float);
+    method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public static final class WindowInsetsAnimationCompat.BoundsCompat {
+    ctor public WindowInsetsAnimationCompat.BoundsCompat(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public androidx.core.graphics.Insets getLowerBound();
+    method public androidx.core.graphics.Insets getUpperBound();
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat inset(androidx.core.graphics.Insets);
+    method @RequiresApi(30) public android.view.WindowInsetsAnimation.Bounds toBounds();
+    method @RequiresApi(30) public static androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat toBoundsCompat(android.view.WindowInsetsAnimation.Bounds);
+  }
+
+  public abstract static class WindowInsetsAnimationCompat.Callback {
+    ctor public WindowInsetsAnimationCompat.Callback(@androidx.core.view.WindowInsetsAnimationCompat.Callback.DispatchMode int);
+    method @androidx.core.view.WindowInsetsAnimationCompat.Callback.DispatchMode public final int getDispatchMode();
+    method public void onEnd(androidx.core.view.WindowInsetsAnimationCompat);
+    method public void onPrepare(androidx.core.view.WindowInsetsAnimationCompat);
+    method public abstract androidx.core.view.WindowInsetsCompat onProgress(androidx.core.view.WindowInsetsCompat, java.util.List<androidx.core.view.WindowInsetsAnimationCompat!>);
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat onStart(androidx.core.view.WindowInsetsAnimationCompat, androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat);
+    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
+    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
+  }
+
+  @IntDef({androidx.core.view.WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP, androidx.core.view.WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface WindowInsetsAnimationCompat.Callback.DispatchMode {
+  }
+
+  public interface WindowInsetsAnimationControlListenerCompat {
+    method public void onCancelled(androidx.core.view.WindowInsetsAnimationControllerCompat?);
+    method public void onFinished(androidx.core.view.WindowInsetsAnimationControllerCompat);
+    method public void onReady(androidx.core.view.WindowInsetsAnimationControllerCompat, @androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
+  }
+
+  public final class WindowInsetsAnimationControllerCompat {
+    method public void finish(boolean);
+    method public float getCurrentAlpha();
+    method @FloatRange(from=0.0f, to=1.0f) public float getCurrentFraction();
+    method public androidx.core.graphics.Insets getCurrentInsets();
+    method public androidx.core.graphics.Insets getHiddenStateInsets();
+    method public androidx.core.graphics.Insets getShownStateInsets();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public int getTypes();
+    method public boolean isCancelled();
+    method public boolean isFinished();
+    method public boolean isReady();
+    method public void setInsetsAndAlpha(androidx.core.graphics.Insets?, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public class WindowInsetsCompat {
+    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat?);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeDisplayCutout();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeStableInsets();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeSystemWindowInsets();
+    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getInsets(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
+    method public androidx.core.graphics.Insets getInsetsIgnoringVisibility(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
+    method @Deprecated public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
+    method @Deprecated public int getStableInsetBottom();
+    method @Deprecated public int getStableInsetLeft();
+    method @Deprecated public int getStableInsetRight();
+    method @Deprecated public int getStableInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getStableInsets();
+    method @Deprecated public androidx.core.graphics.Insets getSystemGestureInsets();
+    method @Deprecated public int getSystemWindowInsetBottom();
+    method @Deprecated public int getSystemWindowInsetLeft();
+    method @Deprecated public int getSystemWindowInsetRight();
+    method @Deprecated public int getSystemWindowInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getSystemWindowInsets();
+    method @Deprecated public androidx.core.graphics.Insets getTappableElementInsets();
+    method public boolean hasInsets();
+    method @Deprecated public boolean hasStableInsets();
+    method @Deprecated public boolean hasSystemWindowInsets();
+    method public androidx.core.view.WindowInsetsCompat inset(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat inset(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+    method public boolean isConsumed();
+    method public boolean isRound();
+    method public boolean isVisible(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
+    method @RequiresApi(20) public android.view.WindowInsets? toWindowInsets();
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets);
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets, android.view.View?);
+    field public static final androidx.core.view.WindowInsetsCompat CONSUMED;
+  }
+
+  public static final class WindowInsetsCompat.Builder {
+    ctor public WindowInsetsCompat.Builder();
+    ctor public WindowInsetsCompat.Builder(androidx.core.view.WindowInsetsCompat);
+    method public androidx.core.view.WindowInsetsCompat build();
+    method public androidx.core.view.WindowInsetsCompat.Builder setDisplayCutout(androidx.core.view.DisplayCutoutCompat?);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsets(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsetsIgnoringVisibility(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setMandatorySystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setStableInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemWindowInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setTappableElementInsets(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setVisible(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, boolean);
+  }
+
+  public static final class WindowInsetsCompat.Type {
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int captionBar();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int displayCutout();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int ime();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int mandatorySystemGestures();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int navigationBars();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int statusBars();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int systemBars();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int systemGestures();
+    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int tappableElement();
+  }
+
+  @IntDef(flag=true, value={0x1, 0x2, 0x4, 0x8, 0x100, 0x10, 0x20, 0x40, 0x80}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface WindowInsetsCompat.Type.InsetsType {
+  }
+
+  public final class WindowInsetsControllerCompat {
+    ctor public WindowInsetsControllerCompat(android.view.Window, android.view.View);
+    method public void addOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void controlWindowInsetsAnimation(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, long, android.view.animation.Interpolator?, android.os.CancellationSignal?, androidx.core.view.WindowInsetsAnimationControlListenerCompat);
+    method public int getSystemBarsBehavior();
+    method public void hide(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
+    method public boolean isAppearanceLightNavigationBars();
+    method public boolean isAppearanceLightStatusBars();
+    method public void removeOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void setAppearanceLightNavigationBars(boolean);
+    method public void setAppearanceLightStatusBars(boolean);
+    method public void setSystemBarsBehavior(int);
+    method public void show(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
+    method @Deprecated @RequiresApi(30) public static androidx.core.view.WindowInsetsControllerCompat toWindowInsetsControllerCompat(android.view.WindowInsetsController);
+    field public static final int BEHAVIOR_DEFAULT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_SWIPE = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0; // 0x0
+    field public static final int BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2; // 0x2
+  }
+
+  public static interface WindowInsetsControllerCompat.OnControllableInsetsChangedListener {
+    method public void onControllableInsetsChanged(androidx.core.view.WindowInsetsControllerCompat, @androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
+  }
+
+}
+
+package androidx.core.view.accessibility {
+
+  public final class AccessibilityClickableSpanCompat extends android.text.style.ClickableSpan {
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public AccessibilityClickableSpanCompat(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, int);
+    method public void onClick(android.view.View);
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final String SPAN_ID = "ACCESSIBILITY_CLICKABLE_SPAN_ID";
+  }
+
+  public final class AccessibilityEventCompat {
+    method @Deprecated public static void appendRecord(android.view.accessibility.AccessibilityEvent!, androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! asRecord(android.view.accessibility.AccessibilityEvent!);
+    method public static int getAction(android.view.accessibility.AccessibilityEvent);
+    method @androidx.core.view.accessibility.AccessibilityEventCompat.ContentChangeType public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
+    method public static int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! getRecord(android.view.accessibility.AccessibilityEvent!, int);
+    method @Deprecated public static int getRecordCount(android.view.accessibility.AccessibilityEvent!);
+    method public static void setAction(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, @androidx.core.view.accessibility.AccessibilityEventCompat.ContentChangeType int);
+    method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
+    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 512; // 0x200
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 256; // 0x100
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 128; // 0x80
+    field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
+    field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
+    field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
+    field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
+    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
+    field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+    field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
+    field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
+    field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
+    field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
+    field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
+    field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
+    field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
+    field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
+    field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+    field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
+    field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
+    field @Deprecated public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
+  }
+
+  @IntDef(flag=true, value={androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_STATE_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_SUBTREE, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_TEXT, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_DRAG_STARTED, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_DRAG_DROPPED, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_DRAG_CANCELLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface AccessibilityEventCompat.ContentChangeType {
+  }
+
+  public final class AccessibilityManagerCompat {
+    method @Deprecated public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!, int);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+  }
+
+  @Deprecated public static interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    method @Deprecated public void onAccessibilityStateChanged(boolean);
+  }
+
+  @Deprecated public abstract static class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    ctor @Deprecated public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
+  }
+
+  public static interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
+    method public void onTouchExplorationStateChanged(boolean);
+  }
+
+  public class AccessibilityNodeInfoCompat {
+    ctor @Deprecated public AccessibilityNodeInfoCompat(Object!);
+    method public void addAction(int);
+    method public void addAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public void addChild(android.view.View!);
+    method public void addChild(android.view.View!, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addSpansToExtras(CharSequence!, android.view.View!);
+    method public boolean canOpenPopup();
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByText(String!);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByViewId(String!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! findFocus(int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!>! getActionList();
+    method @Deprecated public int getActions();
+    method public java.util.List<java.lang.String!> getAvailableExtraData();
+    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
+    method public void getBoundsInScreen(android.graphics.Rect!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
+    method public int getChildCount();
+    method public CharSequence! getClassName();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.text.style.ClickableSpan![]! getClickableSpans(CharSequence!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! getCollectionInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! getCollectionItemInfo();
+    method public CharSequence! getContentDescription();
+    method public int getDrawingOrder();
+    method public CharSequence! getError();
+    method public android.view.accessibility.AccessibilityNodeInfo.ExtraRenderingInfo? getExtraRenderingInfo();
+    method public android.os.Bundle! getExtras();
+    method public CharSequence? getHintText();
+    method @Deprecated public Object! getInfo();
+    method public int getInputType();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabelFor();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
+    method public int getLiveRegion();
+    method public int getMaxTextLength();
+    method public long getMinDurationBetweenContentChangesMillis();
+    method public int getMovementGranularities();
+    method public CharSequence! getPackageName();
+    method public CharSequence? getPaneTitle();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getParent();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! getRangeInfo();
+    method public CharSequence? getRoleDescription();
+    method public CharSequence? getStateDescription();
+    method public CharSequence! getText();
+    method public int getTextSelectionEnd();
+    method public int getTextSelectionStart();
+    method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
+    method public String? getUniqueId();
+    method public String! getViewIdResourceName();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
+    method public int getWindowId();
+    method public boolean hasRequestInitialAccessibilityFocus();
+    method public boolean isAccessibilityFocused();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isClickable();
+    method public boolean isContentInvalid();
+    method public boolean isContextClickable();
+    method public boolean isDismissable();
+    method public boolean isEditable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public boolean isFocused();
+    method public boolean isHeading();
+    method public boolean isImportantForAccessibility();
+    method public boolean isLongClickable();
+    method public boolean isMultiLine();
+    method public boolean isPassword();
+    method public boolean isScreenReaderFocusable();
+    method public boolean isScrollable();
+    method public boolean isSelected();
+    method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
+    method public boolean isTextSelectable();
+    method public boolean isVisibleToUser();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat!);
+    method public boolean performAction(int);
+    method public boolean performAction(int, android.os.Bundle!);
+    method @Deprecated public void recycle();
+    method public boolean refresh();
+    method public boolean removeAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public boolean removeChild(android.view.View!);
+    method public boolean removeChild(android.view.View!, int);
+    method public void setAccessibilityFocused(boolean);
+    method public void setAvailableExtraData(java.util.List<java.lang.String!>);
+    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
+    method public void setBoundsInScreen(android.graphics.Rect!);
+    method public void setCanOpenPopup(boolean);
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setClassName(CharSequence!);
+    method public void setClickable(boolean);
+    method public void setCollectionInfo(Object!);
+    method public void setCollectionItemInfo(Object!);
+    method public void setContentDescription(CharSequence!);
+    method public void setContentInvalid(boolean);
+    method public void setContextClickable(boolean);
+    method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
+    method public void setEditable(boolean);
+    method public void setEnabled(boolean);
+    method public void setError(CharSequence!);
+    method public void setFocusable(boolean);
+    method public void setFocused(boolean);
+    method public void setHeading(boolean);
+    method public void setHintText(CharSequence?);
+    method public void setImportantForAccessibility(boolean);
+    method public void setInputType(int);
+    method public void setLabelFor(android.view.View!);
+    method public void setLabelFor(android.view.View!, int);
+    method public void setLabeledBy(android.view.View!);
+    method public void setLabeledBy(android.view.View!, int);
+    method public void setLiveRegion(int);
+    method public void setLongClickable(boolean);
+    method public void setMaxTextLength(int);
+    method public void setMinDurationBetweenContentChangesMillis(long);
+    method public void setMovementGranularities(int);
+    method public void setMultiLine(boolean);
+    method public void setPackageName(CharSequence!);
+    method public void setPaneTitle(CharSequence?);
+    method public void setParent(android.view.View!);
+    method public void setParent(android.view.View!, int);
+    method public void setPassword(boolean);
+    method public void setRangeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat!);
+    method public void setRequestInitialAccessibilityFocus(boolean);
+    method public void setRoleDescription(CharSequence?);
+    method public void setScreenReaderFocusable(boolean);
+    method public void setScrollable(boolean);
+    method public void setSelected(boolean);
+    method public void setShowingHintText(boolean);
+    method public void setSource(android.view.View!);
+    method public void setSource(android.view.View!, int);
+    method public void setStateDescription(CharSequence?);
+    method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
+    method public void setTextSelectable(boolean);
+    method public void setTextSelection(int, int);
+    method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
+    method public void setTraversalAfter(android.view.View!);
+    method public void setTraversalAfter(android.view.View!, int);
+    method public void setTraversalBefore(android.view.View!);
+    method public void setTraversalBefore(android.view.View!, int);
+    method public void setUniqueId(String?);
+    method public void setViewIdResourceName(String!);
+    method public void setVisibleToUser(boolean);
+    method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
+    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+    field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+    field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+    field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+    field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_X = "ACTION_ARGUMENT_MOVE_WINDOW_X";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y = "ACTION_ARGUMENT_MOVE_WINDOW_Y";
+    field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
+    field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
+    field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+    field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
+    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
+    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
+    field public static final int ACTION_CLICK = 16; // 0x10
+    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
+    field public static final int ACTION_COPY = 16384; // 0x4000
+    field public static final int ACTION_CUT = 65536; // 0x10000
+    field public static final int ACTION_DISMISS = 1048576; // 0x100000
+    field public static final int ACTION_EXPAND = 262144; // 0x40000
+    field public static final int ACTION_FOCUS = 1; // 0x1
+    field public static final int ACTION_LONG_CLICK = 32; // 0x20
+    field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
+    field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+    field public static final int ACTION_PASTE = 32768; // 0x8000
+    field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
+    field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
+    field public static final int ACTION_SELECT = 4; // 0x4
+    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH";
+    field public static final int EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_MAX_LENGTH = 20000; // 0x4e20
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX";
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY";
+    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+    field public static final int FOCUS_INPUT = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
+    field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
+    field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
+    field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int mParentVirtualDescendantId;
+  }
+
+  public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
+    ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!, androidx.core.view.accessibility.AccessibilityViewCommand!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! createReplacementAction(CharSequence!, androidx.core.view.accessibility.AccessibilityViewCommand!);
+    method public int getId();
+    method public CharSequence! getLabel();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean perform(android.view.View!, android.os.Bundle!);
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COLLAPSE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CONTEXT_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_CANCEL;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_DROP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_START;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_IME_ENTER;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_LONG_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PRESS_AND_HOLD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SELECT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_PROGRESS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_TEXT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_ON_SCREEN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SHOW_TEXT_SUGGESTIONS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_TOOLTIP;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected final androidx.core.view.accessibility.AccessibilityViewCommand! mCommand;
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public int getSelectionMode();
+    method public boolean isHierarchical();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean, int);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
+    method public int getColumnIndex();
+    method public int getColumnSpan();
+    method public int getRowIndex();
+    method public int getRowSpan();
+    method @Deprecated public boolean isHeading();
+    method public boolean isSelected();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean, boolean);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean);
+  }
+
+  public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
+    method public float getCurrent();
+    method public float getMax();
+    method public float getMin();
+    method public int getType();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! obtain(int, float, float, float);
+    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+    field public static final int RANGE_TYPE_INT = 0; // 0x0
+    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+  }
+
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region!,android.view.View!>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
+  public class AccessibilityNodeProviderCompat {
+    ctor public AccessibilityNodeProviderCompat();
+    ctor public AccessibilityNodeProviderCompat(Object?);
+    method public void addExtraDataToAccessibilityNodeInfo(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, String, android.os.Bundle?);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? createAccessibilityNodeInfo(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>? findAccessibilityNodeInfosByText(String, int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? findFocus(int);
+    method public Object? getProvider();
+    method public boolean performAction(int, int, android.os.Bundle?);
+    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
+  }
+
+  public class AccessibilityRecordCompat {
+    ctor @Deprecated public AccessibilityRecordCompat(Object!);
+    method @Deprecated public boolean equals(Object?);
+    method @Deprecated public int getAddedCount();
+    method @Deprecated public CharSequence! getBeforeText();
+    method @Deprecated public CharSequence! getClassName();
+    method @Deprecated public CharSequence! getContentDescription();
+    method @Deprecated public int getCurrentItemIndex();
+    method @Deprecated public int getFromIndex();
+    method @Deprecated public Object! getImpl();
+    method @Deprecated public int getItemCount();
+    method @Deprecated public int getMaxScrollX();
+    method public static int getMaxScrollX(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public int getMaxScrollY();
+    method public static int getMaxScrollY(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public android.os.Parcelable! getParcelableData();
+    method @Deprecated public int getRemovedCount();
+    method @Deprecated public int getScrollX();
+    method @Deprecated public int getScrollY();
+    method @Deprecated public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getSource();
+    method @Deprecated public java.util.List<java.lang.CharSequence!>! getText();
+    method @Deprecated public int getToIndex();
+    method @Deprecated public int getWindowId();
+    method @Deprecated public int hashCode();
+    method @Deprecated public boolean isChecked();
+    method @Deprecated public boolean isEnabled();
+    method @Deprecated public boolean isFullScreen();
+    method @Deprecated public boolean isPassword();
+    method @Deprecated public boolean isScrollable();
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain(androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain();
+    method @Deprecated public void recycle();
+    method @Deprecated public void setAddedCount(int);
+    method @Deprecated public void setBeforeText(CharSequence!);
+    method @Deprecated public void setChecked(boolean);
+    method @Deprecated public void setClassName(CharSequence!);
+    method @Deprecated public void setContentDescription(CharSequence!);
+    method @Deprecated public void setCurrentItemIndex(int);
+    method @Deprecated public void setEnabled(boolean);
+    method @Deprecated public void setFromIndex(int);
+    method @Deprecated public void setFullScreen(boolean);
+    method @Deprecated public void setItemCount(int);
+    method @Deprecated public void setMaxScrollX(int);
+    method public static void setMaxScrollX(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setMaxScrollY(int);
+    method public static void setMaxScrollY(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setParcelableData(android.os.Parcelable!);
+    method @Deprecated public void setPassword(boolean);
+    method @Deprecated public void setRemovedCount(int);
+    method @Deprecated public void setScrollX(int);
+    method @Deprecated public void setScrollY(int);
+    method @Deprecated public void setScrollable(boolean);
+    method @Deprecated public void setSource(android.view.View!);
+    method @Deprecated public void setSource(android.view.View!, int);
+    method public static void setSource(android.view.accessibility.AccessibilityRecord, android.view.View?, int);
+    method @Deprecated public void setToIndex(int);
+  }
+
+  public interface AccessibilityViewCommand {
+    method public boolean perform(android.view.View, androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments?);
+  }
+
+  public abstract static class AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.CommandArguments();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setBundle(android.os.Bundle?);
+  }
+
+  public static final class AccessibilityViewCommand.MoveAtGranularityArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveAtGranularityArguments();
+    method public boolean getExtendSelection();
+    method public int getGranularity();
+  }
+
+  public static final class AccessibilityViewCommand.MoveHtmlArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveHtmlArguments();
+    method public String? getHTMLElement();
+  }
+
+  public static final class AccessibilityViewCommand.MoveWindowArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveWindowArguments();
+    method public int getX();
+    method public int getY();
+  }
+
+  public static final class AccessibilityViewCommand.ScrollToPositionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.ScrollToPositionArguments();
+    method public int getColumn();
+    method public int getRow();
+  }
+
+  public static final class AccessibilityViewCommand.SetProgressArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetProgressArguments();
+    method public float getProgress();
+  }
+
+  public static final class AccessibilityViewCommand.SetSelectionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetSelectionArguments();
+    method public int getEnd();
+    method public int getStart();
+  }
+
+  public static final class AccessibilityViewCommand.SetTextArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetTextArguments();
+    method public CharSequence? getText();
+  }
+
+  public class AccessibilityWindowInfoCompat {
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
+    method public int getChildCount();
+    method public int getDisplayId();
+    method public int getId();
+    method public int getLayer();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getParent();
+    method public void getRegionInScreen(android.graphics.Region);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getRoot();
+    method public CharSequence? getTitle();
+    method public int getType();
+    method public boolean isAccessibilityFocused();
+    method public boolean isActive();
+    method public boolean isFocused();
+    method public boolean isInPictureInPictureMode();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat?);
+    method @Deprecated public void recycle();
+    method public android.view.accessibility.AccessibilityWindowInfo? unwrap();
+    field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
+    field public static final int TYPE_APPLICATION = 1; // 0x1
+    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+    field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
+    field public static final int TYPE_SYSTEM = 3; // 0x3
+  }
+
+}
+
+package androidx.core.view.animation {
+
+  public final class PathInterpolatorCompat {
+    method public static android.view.animation.Interpolator create(android.graphics.Path);
+    method public static android.view.animation.Interpolator create(float, float);
+    method public static android.view.animation.Interpolator create(float, float, float, float);
+  }
+
+}
+
+package androidx.core.view.inputmethod {
+
+  public final class EditorInfoCompat {
+    ctor @Deprecated public EditorInfoCompat();
+    method public static String![] getContentMimeTypes(android.view.inputmethod.EditorInfo);
+    method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
+    method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
+    method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
+    method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
+    field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
+    field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
+  }
+
+  public final class InputConnectionCompat {
+    ctor @Deprecated public InputConnectionCompat();
+    method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+    method @Deprecated public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+    method public static android.view.inputmethod.InputConnection createWrapper(android.view.View, android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo);
+    field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
+  }
+
+  public static interface InputConnectionCompat.OnCommitContentListener {
+    method public boolean onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+  }
+
+  public final class InputContentInfoCompat {
+    ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri?);
+    method public android.net.Uri getContentUri();
+    method public android.content.ClipDescription getDescription();
+    method public android.net.Uri? getLinkUri();
+    method public void releasePermission();
+    method public void requestPermission();
+    method public Object? unwrap();
+    method public static androidx.core.view.inputmethod.InputContentInfoCompat? wrap(Object?);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
+    ctor public AutoScrollHelper(android.view.View);
+    method public abstract boolean canTargetScrollHorizontally(int);
+    method public abstract boolean canTargetScrollVertically(int);
+    method public boolean isEnabled();
+    method public boolean isExclusive();
+    method public boolean onTouch(android.view.View!, android.view.MotionEvent!);
+    method public abstract void scrollTargetBy(int, int);
+    method public androidx.core.widget.AutoScrollHelper setActivationDelay(int);
+    method public androidx.core.widget.AutoScrollHelper setEdgeType(int);
+    method public androidx.core.widget.AutoScrollHelper! setEnabled(boolean);
+    method public androidx.core.widget.AutoScrollHelper! setExclusive(boolean);
+    method public androidx.core.widget.AutoScrollHelper setMaximumEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMaximumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMinimumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRampDownDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRampUpDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRelativeEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRelativeVelocity(float, float);
+    field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
+    field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
+    field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
+    field public static final float NO_MAX = 3.4028235E38f;
+    field public static final float NO_MIN = 0.0f;
+    field public static final float RELATIVE_UNSPECIFIED = 0.0f;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface AutoSizeableTextView {
+    method public int getAutoSizeMaxTextSize();
+    method public int getAutoSizeMinTextSize();
+    method public int getAutoSizeStepGranularity();
+    method public int[]! getAutoSizeTextAvailableSizes();
+    method @androidx.core.widget.TextViewCompat.AutoSizeTextType public int getAutoSizeTextType();
+    method public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
+    method public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
+    method public void setAutoSizeTextTypeWithDefaults(@androidx.core.widget.TextViewCompat.AutoSizeTextType int);
+    field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final boolean PLATFORM_SUPPORTS_AUTOSIZE;
+  }
+
+  public final class CheckedTextViewCompat {
+    method public static android.graphics.drawable.Drawable? getCheckMarkDrawable(android.widget.CheckedTextView);
+    method public static android.content.res.ColorStateList? getCheckMarkTintList(android.widget.CheckedTextView);
+    method public static android.graphics.PorterDuff.Mode? getCheckMarkTintMode(android.widget.CheckedTextView);
+    method public static void setCheckMarkTintList(android.widget.CheckedTextView, android.content.res.ColorStateList?);
+    method public static void setCheckMarkTintMode(android.widget.CheckedTextView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class CompoundButtonCompat {
+    method public static android.graphics.drawable.Drawable? getButtonDrawable(android.widget.CompoundButton);
+    method public static android.content.res.ColorStateList? getButtonTintList(android.widget.CompoundButton);
+    method public static android.graphics.PorterDuff.Mode? getButtonTintMode(android.widget.CompoundButton);
+    method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList?);
+    method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode?);
+  }
+
+  public class ContentLoadingProgressBar extends android.widget.ProgressBar {
+    ctor public ContentLoadingProgressBar(android.content.Context);
+    ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet?);
+    method public void hide();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void show();
+  }
+
+  public final class EdgeEffectCompat {
+    ctor @Deprecated public EdgeEffectCompat(android.content.Context!);
+    method public static android.widget.EdgeEffect create(android.content.Context, android.util.AttributeSet?);
+    method @Deprecated public boolean draw(android.graphics.Canvas!);
+    method @Deprecated public void finish();
+    method public static float getDistance(android.widget.EdgeEffect);
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean onAbsorb(int);
+    method @Deprecated public boolean onPull(float);
+    method @Deprecated public boolean onPull(float, float);
+    method public static void onPull(android.widget.EdgeEffect, float, float);
+    method public static float onPullDistance(android.widget.EdgeEffect, float, float);
+    method @Deprecated public boolean onRelease();
+    method @Deprecated public void setSize(int, int);
+  }
+
+  public class ImageViewCompat {
+    method public static android.content.res.ColorStateList? getImageTintList(android.widget.ImageView);
+    method public static android.graphics.PorterDuff.Mode? getImageTintMode(android.widget.ImageView);
+    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList?);
+    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class ListPopupWindowCompat {
+    method @Deprecated public static android.view.View.OnTouchListener! createDragToOpenListener(Object!, android.view.View!);
+    method public static android.view.View.OnTouchListener? createDragToOpenListener(android.widget.ListPopupWindow, android.view.View);
+  }
+
+  public class ListViewAutoScrollHelper extends androidx.core.widget.AutoScrollHelper {
+    ctor public ListViewAutoScrollHelper(android.widget.ListView);
+    method public boolean canTargetScrollHorizontally(int);
+    method public boolean canTargetScrollVertically(int);
+    method public void scrollTargetBy(int, int);
+  }
+
+  public final class ListViewCompat {
+    method public static boolean canScrollList(android.widget.ListView, int);
+    method public static void scrollListBy(android.widget.ListView, int);
+  }
+
+  public class NestedScrollView extends android.widget.FrameLayout implements androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent3 androidx.core.view.ScrollingView {
+    ctor public NestedScrollView(android.content.Context);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean arrowScroll(int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollRange();
+    method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public boolean executeKeyEvent(android.view.KeyEvent);
+    method public void fling(int);
+    method public boolean fullScroll(int);
+    method public int getMaxScrollAmount();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean isFillViewport();
+    method public boolean isSmoothScrollingEnabled();
+    method public void onAttachedToWindow();
+    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View, int);
+    method public boolean pageScroll(int);
+    method public void setFillViewport(boolean);
+    method public void setOnScrollChangeListener(androidx.core.widget.NestedScrollView.OnScrollChangeListener?);
+    method public void setSmoothScrollingEnabled(boolean);
+    method public final void smoothScrollBy(int, int);
+    method public final void smoothScrollBy(int, int, int);
+    method public final void smoothScrollTo(int, int);
+    method public final void smoothScrollTo(int, int, int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+  }
+
+  public static interface NestedScrollView.OnScrollChangeListener {
+    method public void onScrollChange(androidx.core.widget.NestedScrollView, int, int, int, int);
+  }
+
+  public final class PopupMenuCompat {
+    method public static android.view.View.OnTouchListener? getDragToOpenListener(Object);
+  }
+
+  public final class PopupWindowCompat {
+    method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+    method public static int getWindowLayoutType(android.widget.PopupWindow);
+    method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
+    method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
+  }
+
+  @Deprecated public final class ScrollerCompat {
+    method @Deprecated public void abortAnimation();
+    method @Deprecated public boolean computeScrollOffset();
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!);
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!, android.view.animation.Interpolator!);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int, int, int);
+    method @Deprecated public float getCurrVelocity();
+    method @Deprecated public int getCurrX();
+    method @Deprecated public int getCurrY();
+    method @Deprecated public int getFinalX();
+    method @Deprecated public int getFinalY();
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean isOverScrolled();
+    method @Deprecated public void notifyHorizontalEdgeReached(int, int, int);
+    method @Deprecated public void notifyVerticalEdgeReached(int, int, int);
+    method @Deprecated public boolean springBack(int, int, int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int, int);
+  }
+
+  public final class TextViewCompat {
+    method public static int getAutoSizeMaxTextSize(android.widget.TextView);
+    method public static int getAutoSizeMinTextSize(android.widget.TextView);
+    method public static int getAutoSizeStepGranularity(android.widget.TextView);
+    method public static int[] getAutoSizeTextAvailableSizes(android.widget.TextView);
+    method public static int getAutoSizeTextType(android.widget.TextView);
+    method public static android.content.res.ColorStateList? getCompoundDrawableTintList(android.widget.TextView);
+    method public static android.graphics.PorterDuff.Mode? getCompoundDrawableTintMode(android.widget.TextView);
+    method public static android.graphics.drawable.Drawable![] getCompoundDrawablesRelative(android.widget.TextView);
+    method public static int getFirstBaselineToTopHeight(android.widget.TextView);
+    method public static int getLastBaselineToBottomHeight(android.widget.TextView);
+    method public static int getMaxLines(android.widget.TextView);
+    method public static int getMinLines(android.widget.TextView);
+    method public static androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParams(android.widget.TextView);
+    method public static void setAutoSizeTextTypeUniformWithConfiguration(android.widget.TextView, int, int, int, int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeUniformWithPresetSizes(android.widget.TextView, int[], int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeWithDefaults(android.widget.TextView, int);
+    method public static void setCompoundDrawableTintList(android.widget.TextView, android.content.res.ColorStateList?);
+    method public static void setCompoundDrawableTintMode(android.widget.TextView, android.graphics.PorterDuff.Mode?);
+    method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, @DrawableRes int, @DrawableRes int, @DrawableRes int, @DrawableRes int);
+    method public static void setCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback);
+    method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
+    method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
+    method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.view.ActionMode.Callback? unwrapCustomSelectionActionModeCallback(android.view.ActionMode.Callback?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.view.ActionMode.Callback? wrapCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback?);
+    field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0
+    field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
+  }
+
+  @IntDef({androidx.core.widget.TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE, androidx.core.widget.TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface TextViewCompat.AutoSizeTextType {
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class TextViewOnReceiveContentListener implements androidx.core.view.OnReceiveContentListener {
+    ctor public TextViewOnReceiveContentListener();
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface TintableCheckedTextView {
+    method public android.content.res.ColorStateList? getSupportCheckMarkTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportCheckMarkTintMode();
+    method public void setSupportCheckMarkTintList(android.content.res.ColorStateList?);
+    method public void setSupportCheckMarkTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface TintableCompoundButton {
+    method public android.content.res.ColorStateList? getSupportButtonTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface TintableCompoundDrawablesView {
+    method public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface TintableImageSourceView {
+    method public android.content.res.ColorStateList? getSupportImageTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportImageTintMode();
+    method public void setSupportImageTintList(android.content.res.ColorStateList?);
+    method public void setSupportImageTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+}
+
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index 9556806..07bd416 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -3720,7 +3720,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
     method public int getLiveRegion();
     method public int getMaxTextLength();
-    method public int getMinMillisBetweenContentChanges();
+    method public long getMinDurationBetweenContentChangesMillis();
     method public int getMovementGranularities();
     method public CharSequence! getPackageName();
     method public CharSequence? getPaneTitle();
@@ -3806,7 +3806,7 @@
     method public void setLiveRegion(int);
     method public void setLongClickable(boolean);
     method public void setMaxTextLength(int);
-    method public void setMinMillisBetweenContentChanges(int);
+    method public void setMinDurationBetweenContentChangesMillis(long);
     method public void setMovementGranularities(int);
     method public void setMultiLine(boolean);
     method public void setPackageName(CharSequence!);
diff --git a/core/core/build.gradle b/core/core/build.gradle
index 3f464c5..2f93e91 100644
--- a/core/core/build.gradle
+++ b/core/core/build.gradle
@@ -12,7 +12,7 @@
         implementation(project(":core:core-ktx"))
     }
 
-    api(projectOrArtifact(":annotation:annotation"))
+    api("androidx.annotation:annotation:1.6.0")
     api("androidx.annotation:annotation-experimental:1.3.0")
     api("androidx.lifecycle:lifecycle-runtime:2.3.1")
     api("androidx.versionedparcelable:versionedparcelable:1.1.1")
@@ -20,9 +20,6 @@
     implementation("androidx.concurrent:concurrent-futures:1.0.0")
     implementation("androidx.interpolator:interpolator:1.0.0")
 
-    // Required for -Werror due to annotation-experimental use of Kotlin
-    compileOnly(libs.kotlinStdlib)
-
     // We don't ship this as a public artifact, so it must remain a project-type dependency.
     annotationProcessor(projectOrArtifact(":versionedparcelable:versionedparcelable-compiler"))
 
diff --git a/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
index 520a252..5ffca2f 100644
--- a/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
@@ -304,6 +304,11 @@
         // notification is built successfully (without throwing an exception).
         NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
 
+        Notification nDefault = builder.build();
+        if (Build.VERSION.SDK_INT >= 19) {
+            assertThat(NotificationCompat.getShowWhen(nDefault)).isTrue();
+        }
+
         // test true
         Notification nTrue = builder.setShowWhen(true).build();
         if (Build.VERSION.SDK_INT >= 19) {
diff --git a/core/core/src/androidTest/java/androidx/core/content/FileProviderTest.java b/core/core/src/androidTest/java/androidx/core/content/FileProviderTest.java
index 36ef9c7..9de302e 100644
--- a/core/core/src/androidTest/java/androidx/core/content/FileProviderTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/FileProviderTest.java
@@ -45,7 +45,6 @@
 import org.junit.runner.RunWith;
 
 import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -486,7 +485,7 @@
     /**
      * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
      */
-    private static void closeQuietly(Closeable closeable) {
+    private static void closeQuietly(AutoCloseable closeable) {
         if (closeable != null) {
             try {
                 closeable.close();
diff --git a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
index 9df7bc0..805a399 100644
--- a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
@@ -103,10 +103,10 @@
 
     @SdkSuppress(minSdkVersion = 19)
     @Test
-    public void testGetSetMinMillisBetweenContentChanges() {
+    public void testGetSetMinDurationBetweenContentChanges() {
         AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
-        nodeCompat.setMinMillisBetweenContentChanges(200);
-        assertThat(nodeCompat.getMinMillisBetweenContentChanges(), equalTo(200));
+        nodeCompat.setMinDurationBetweenContentChangesMillis(200L);
+        assertThat(nodeCompat.getMinDurationBetweenContentChangesMillis(), equalTo(200L));
     }
 
     @SdkSuppress(minSdkVersion = 19)
diff --git a/core/core/src/main/java/androidx/core/app/NotificationCompat.java b/core/core/src/main/java/androidx/core/app/NotificationCompat.java
index 679e8e0..d965579 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationCompat.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationCompat.java
@@ -1278,9 +1278,6 @@
         /**
          * Set the time that the event occurred.  Notifications in the panel are
          * sorted by this time.
-         *
-         * <p>For apps targeting {@link android.os.Build.VERSION_CODES#N} and above, this time is
-         * not shown anymore by default and must be opted into using {@link #setShowWhen(boolean)}
          */
         public @NonNull Builder setWhen(long when) {
             mNotification.when = when;
@@ -1289,10 +1286,7 @@
 
         /**
          * Control whether the timestamp set with {@link #setWhen(long) setWhen} is shown
-         * in the content view.
-         *
-         * <p>For apps targeting {@link android.os.Build.VERSION_CODES#N} and above, this
-         * defaults to {@code false}. For earlier apps, the default is {@code true}.
+         * in the content view. The default is {@code true}.
          */
         public @NonNull Builder setShowWhen(boolean show) {
             mShowWhen = show;
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 3f54712a..7272616 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -1314,9 +1314,9 @@
     private static final String UNIQUE_ID_KEY =
             "androidx.view.accessibility.AccessibilityNodeInfoCompat.UNIQUE_ID_KEY";
 
-    private static final String MIN_MILLIS_BETWEEN_CONTENT_CHANGES_KEY =
+    private static final String MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY =
             "androidx.view.accessibility.AccessibilityNodeInfoCompat."
-                    + "MIN_MILLIS_BETWEEN_CONTENT_CHANGES_KEY";
+                    + "MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY";
 
     // These don't line up with the internal framework constants, since they are independent
     // and we might as well get all 32 bits of utility here.
@@ -2743,9 +2743,9 @@
     /**
      * Gets the minimum time duration between two content change events.
      */
-    public int getMinMillisBetweenContentChanges() {
+    public long getMinDurationBetweenContentChangesMillis() {
         if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getInt(MIN_MILLIS_BETWEEN_CONTENT_CHANGES_KEY);
+            return Api19Impl.getExtras(mInfo).getLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY);
         }
         return 0;
     }
@@ -2755,7 +2755,7 @@
      * content change events in accessibility services.
      *
      * <p>
-     * Example: An app can set MinMillisBetweenContentChanges as 1 min for a view which sends
+     * Example: An app can set MinDurationBetweenContentChanges as 1 min for a view which sends
      * content change events to accessibility services one event per second.
      * Accessibility service will throttle those content change events and only handle one event
      * per minute for that view.
@@ -2764,9 +2764,9 @@
      * @see AccessibilityEventCompat#getContentChangeTypes for all content change types.
      * @param duration the minimum duration between content change events.
      */
-    public void setMinMillisBetweenContentChanges(int duration) {
+    public void setMinDurationBetweenContentChangesMillis(long duration) {
         if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putInt(MIN_MILLIS_BETWEEN_CONTENT_CHANGES_KEY, duration);
+            Api19Impl.getExtras(mInfo).putLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY, duration);
         }
     }
 
diff --git a/credentials/credentials-play-services-auth/build.gradle b/credentials/credentials-play-services-auth/build.gradle
index 4cbcb8c..f2ecf59 100644
--- a/credentials/credentials-play-services-auth/build.gradle
+++ b/credentials/credentials-play-services-auth/build.gradle
@@ -26,6 +26,10 @@
     api(libs.kotlinStdlib)
     api project(":credentials:credentials")
 
+    implementation("com.google.android.libraries.identity.googleid:googleid:0.0.2"){
+        exclude group: "androidx.credentials"
+    }
+
     // Closed source dependencies
     implementation(libs.playServicesAuth) {
         exclude group: "androidx.loader"
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
index 5db9701..27c9b68 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
@@ -29,6 +29,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.google.android.gms.auth.api.identity.BeginSignInRequest;
+import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -40,8 +41,7 @@
 @SuppressWarnings("deprecation")
 public class CredentialProviderBeginSignInControllerJavaTest {
     @Test
-    public void
-            convertRequestToPlayServices_setPasswordOptionRequestAndFalseAutoSelect_success() {
+    public void convertRequestToPlayServices_setPasswordOptionRequestAndFalseAutoSelect_success() {
         ActivityScenario<TestCredentialsActivity> activityScenario =
                 ActivityScenario.launch(TestCredentialsActivity.class);
         activityScenario.onActivity(activity -> {
@@ -66,10 +66,10 @@
 
             BeginSignInRequest actualResponse =
                     CredentialProviderBeginSignInController
-                        .getInstance(activity)
-                        .convertRequestToPlayServices(new GetCredentialRequest(List.of(
-                                new GetPasswordOption()
-                        ), true));
+                            .getInstance(activity)
+                            .convertRequestToPlayServices(new GetCredentialRequest(List.of(
+                                    new GetPasswordOption()
+                            ), true));
 
             assertThat(actualResponse.getPasswordRequestOptions().isSupported()).isTrue();
             assertThat(actualResponse.isAutoSelectEnabled()).isTrue();
@@ -107,4 +107,44 @@
             );
         });
     }
+
+    @Test
+    public void convertRequestToPlayServices_setGoogleIdOptionRequestAndTrueAutoSelect_success() {
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+
+        GetGoogleIdOption option = new GetGoogleIdOption.Builder()
+                .setServerClientId("server_client_id")
+                .setNonce("nonce")
+                .setFilterByAuthorizedAccounts(true)
+                .setRequestVerifiedPhoneNumber(false)
+                .associatedLinkedAccounts("link_service_id", List.of("a", "b", "c"))
+                .build();
+
+        activityScenario.onActivity(activity -> {
+
+            BeginSignInRequest actualRequest =
+                    CredentialProviderBeginSignInController
+                            .getInstance(activity)
+                            .convertRequestToPlayServices(new GetCredentialRequest(List.of(
+                                    option
+                            ), true));
+
+            assertThat(actualRequest.getGoogleIdTokenRequestOptions().isSupported()).isTrue();
+            assertThat(actualRequest.isAutoSelectEnabled()).isTrue();
+
+            BeginSignInRequest.GoogleIdTokenRequestOptions actualOption =
+                    actualRequest.getGoogleIdTokenRequestOptions();
+            assertThat(actualOption.getServerClientId()).isEqualTo(option.getServerClientId());
+            assertThat(actualOption.getNonce()).isEqualTo(option.getNonce());
+            assertThat(actualOption.filterByAuthorizedAccounts()).isEqualTo(
+                    option.getFilterByAuthorizedAccounts());
+            assertThat(actualOption.requestVerifiedPhoneNumber()).isEqualTo(
+                    option.getRequestVerifiedPhoneNumber());
+            assertThat(actualOption.getLinkedServiceId()).isEqualTo(option.getLinkedServiceId());
+            assertThat(actualOption.getIdTokenDepositionScopes()).isEqualTo(
+                    option.getIdTokenDepositionScopes());
+
+        });
+    }
 }
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
index c648f28..461e8a3 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
@@ -25,6 +25,7 @@
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.google.android.libraries.identity.googleid.GetGoogleIdOption
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -75,4 +76,44 @@
             assertThat(actualResponse.isAutoSelectEnabled).isTrue()
         }
     }
+
+    @Test
+    fun convertRequestToPlayServices_setGoogleIdOptionRequest_success() {
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+
+        val option = GetGoogleIdOption.Builder()
+            .setServerClientId("server_client_id")
+            .setNonce("nonce")
+            .setFilterByAuthorizedAccounts(true)
+            .setRequestVerifiedPhoneNumber(false)
+            .associatedLinkedAccounts("link_service_id", listOf("a", "b", "c"))
+            .build()
+
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
+            val actualRequest = getInstance(activity!!)
+                .convertRequestToPlayServices(
+                    GetCredentialRequest(
+                        listOf(
+                            option
+                        ), true
+                    )
+                )
+            assertThat(
+                actualRequest.googleIdTokenRequestOptions.isSupported
+            ).isTrue()
+            assertThat(actualRequest.isAutoSelectEnabled).isTrue()
+            val actualOption = actualRequest.googleIdTokenRequestOptions
+            assertThat(actualOption.serverClientId).isEqualTo(option.serverClientId)
+            assertThat(actualOption.nonce).isEqualTo(option.nonce)
+            assertThat(actualOption.filterByAuthorizedAccounts())
+                .isEqualTo(option.filterByAuthorizedAccounts)
+            assertThat(actualOption.requestVerifiedPhoneNumber())
+                .isEqualTo(option.requestVerifiedPhoneNumber)
+            assertThat(actualOption.linkedServiceId).isEqualTo(option.linkedServiceId)
+            assertThat(actualOption.idTokenDepositionScopes)
+                .isEqualTo(option.idTokenDepositionScopes)
+        }
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt
index 3f915a5..c842429 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt
@@ -37,6 +37,8 @@
 import androidx.credentials.GetPublicKeyCredentialOption
 import androidx.credentials.playservices.controllers.CreatePublicKeyCredential.PublicKeyCredentialControllerUtility.Companion.convertToPlayAuthPasskeyRequest
 import com.google.android.gms.auth.api.identity.BeginSignInRequest
+import com.google.android.gms.auth.api.identity.BeginSignInRequest.GoogleIdTokenRequestOptions
+import com.google.android.libraries.identity.googleid.GetGoogleIdOption
 
 /**
  * A utility class to handle logic for the begin sign in controller.
@@ -65,12 +67,32 @@
                     )
                     isPublicKeyCredReqFound = true
                     // TODO("Confirm logic for single vs multiple options of the same type")
+                } else if (option is GetGoogleIdOption) {
+                    requestBuilder.setGoogleIdTokenRequestOptions(
+                        convertToGoogleIdTokenOption(option))
                 }
-            // TODO("Add GoogleIDToken version")
             }
             return requestBuilder
                 .setAutoSelectEnabled(request.isAutoSelectAllowed)
                 .build()
         }
+
+        private fun convertToGoogleIdTokenOption(option: GetGoogleIdOption):
+          GoogleIdTokenRequestOptions {
+            var idTokenOption =
+                GoogleIdTokenRequestOptions.builder()
+                    .setFilterByAuthorizedAccounts(option.filterByAuthorizedAccounts)
+                    .setNonce(option.nonce)
+                    .setRequestVerifiedPhoneNumber(option.requestVerifiedPhoneNumber)
+                    .setServerClientId(option.serverClientId)
+                    .setSupported(true)
+            if (option.linkedServiceId != null) {
+                idTokenOption.associateLinkedAccounts(
+                    option.linkedServiceId!!,
+                    option.idTokenDepositionScopes
+                )
+            }
+            return idTokenOption.build()
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
index 4dbc5d5..e1ca866 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
@@ -46,6 +46,7 @@
 import com.google.android.gms.auth.api.identity.SignInCredential
 import com.google.android.gms.common.api.ApiException
 import com.google.android.gms.common.api.CommonStatusCodes
+import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
 import java.util.concurrent.Executor
 
 /**
@@ -56,11 +57,11 @@
 @Suppress("deprecation")
 class CredentialProviderBeginSignInController(private val activity: Activity) :
     CredentialProviderController<
-    GetCredentialRequest,
-    BeginSignInRequest,
-    SignInCredential,
-    GetCredentialResponse,
-    GetCredentialException>(activity) {
+        GetCredentialRequest,
+        BeginSignInRequest,
+        SignInCredential,
+        GetCredentialResponse,
+        GetCredentialException>(activity) {
 
     /**
      * The callback object state, used in the protected handleResponse method.
@@ -68,6 +69,7 @@
     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
     lateinit var callback: CredentialManagerCallback<GetCredentialResponse,
         GetCredentialException>
+
     /**
      * The callback requires an executor to invoke it.
      */
@@ -88,12 +90,17 @@
             resultCode: Int,
             resultData: Bundle
         ) {
-            if (maybeReportErrorFromResultReceiver(resultData,
+            if (maybeReportErrorFromResultReceiver(
+                    resultData,
                     CredentialProviderBaseController
                         .Companion::getCredentialExceptionTypeToException,
-                    executor = executor, callback = callback, cancellationSignal)) return
-            handleResponse(resultData.getInt(ACTIVITY_REQUEST_CODE_TAG), resultCode,
-                resultData.getParcelable(RESULT_DATA_TAG))
+                    executor = executor, callback = callback, cancellationSignal
+                )
+            ) return
+            handleResponse(
+                resultData.getInt(ACTIVITY_REQUEST_CODE_TAG), resultCode,
+                resultData.getParcelable(RESULT_DATA_TAG)
+            )
         }
     }
 
@@ -107,7 +114,9 @@
         this.callback = callback
         this.executor = executor
 
-        if (CredentialProviderPlayServicesImpl.cancellationReviewer(cancellationSignal)) { return }
+        if (CredentialProviderPlayServicesImpl.cancellationReviewer(cancellationSignal)) {
+            return
+        }
 
         val convertedRequest: BeginSignInRequest = this.convertRequestToPlayServices(request)
         val hiddenIntent = Intent(activity, HiddenActivity::class.java)
@@ -118,19 +127,30 @@
 
     internal fun handleResponse(uniqueRequestCode: Int, resultCode: Int, data: Intent?) {
         if (uniqueRequestCode != CONTROLLER_REQUEST_CODE) {
-            Log.w(TAG, "Returned request code " +
-                "$CONTROLLER_REQUEST_CODE which does not match what was given $uniqueRequestCode")
+            Log.w(
+                TAG,
+                "Returned request code $CONTROLLER_REQUEST_CODE which " +
+                    " does not match what was given $uniqueRequestCode"
+            )
             return
         }
         if (maybeReportErrorResultCodeGet(resultCode, TAG,
-                { s, f -> cancelOrCallbackExceptionOrResult(s, f) }, { e -> this.executor.execute {
-                    this.callback.onError(e) } }, cancellationSignal)) return
+                { s, f -> cancelOrCallbackExceptionOrResult(s, f) }, { e ->
+                    this.executor.execute {
+                        this.callback.onError(e)
+                    }
+                }, cancellationSignal
+            )
+        ) return
         try {
             val signInCredential = Identity.getSignInClient(activity)
                 .getSignInCredentialFromIntent(data)
             val response = convertResponseToCredentialManager(signInCredential)
-            cancelOrCallbackExceptionOrResult(cancellationSignal) { this.executor.execute {
-                    this.callback.onResult(response) } }
+            cancelOrCallbackExceptionOrResult(cancellationSignal) {
+                this.executor.execute {
+                    this.callback.onResult(response)
+                }
+            }
         } catch (e: ApiException) {
             var exception: GetCredentialException = GetCredentialUnknownException(e.message)
             if (e.statusCode == CommonStatusCodes.CANCELED) {
@@ -138,12 +158,18 @@
             } else if (e.statusCode in retryables) {
                 exception = GetCredentialInterruptedException(e.message)
             }
-            cancelOrCallbackExceptionOrResult(cancellationSignal) { executor.execute {
-                callback.onError(exception) } }
+            cancelOrCallbackExceptionOrResult(cancellationSignal) {
+                executor.execute {
+                    callback.onError(exception)
+                }
+            }
             return
         } catch (e: GetCredentialException) {
-            cancelOrCallbackExceptionOrResult(cancellationSignal) { executor.execute {
-                callback.onError(e) } }
+            cancelOrCallbackExceptionOrResult(cancellationSignal) {
+                executor.execute {
+                    callback.onError(e)
+                }
+            }
         }
     }
 
@@ -160,7 +186,7 @@
         if (response.password != null) {
             cred = PasswordCredential(response.id, response.password!!)
         } else if (response.googleIdToken != null) {
-            TODO(" Implement GoogleIdTokenVersion")
+            cred = createGoogleIdCredential(response)
         } else if (response.publicKeyCredential != null) {
             try {
                 cred = PublicKeyCredential(
@@ -173,16 +199,44 @@
             Log.w(TAG, "Credential returned but no google Id or password or passkey found")
         }
         if (cred == null) {
-            throw GetCredentialUnknownException("When attempting to convert get response, " +
-                "null credential found")
+            throw GetCredentialUnknownException(
+                "When attempting to convert get response, " +
+                    "null credential found"
+            )
         }
         return GetCredentialResponse(cred)
     }
 
+    private fun createGoogleIdCredential(response: SignInCredential): GoogleIdTokenCredential {
+        var cred = GoogleIdTokenCredential.Builder().setId(response.id)
+            .setIdToken(response.googleIdToken!!)
+
+        if (response.displayName != null) {
+            cred.setDisplayName(response.displayName)
+        }
+
+        if (response.givenName != null) {
+            cred.setGivenName(response.givenName)
+        }
+
+        if (response.familyName != null) {
+            cred.setFamilyName(response.familyName)
+        }
+
+        if (response.phoneNumber != null) {
+            cred.setPhoneNumber(response.phoneNumber)
+        }
+
+        if (response.profilePictureUri != null) {
+            cred.setProfilePictureUri(response.profilePictureUri.toString())
+        }
+
+        return cred.build()
+    }
+
     companion object {
         private val TAG = CredentialProviderBeginSignInController::class.java.name
         private var controller: CredentialProviderBeginSignInController? = null
-        // TODO("Ensure this is tested for multiple calls")
 
         /**
          * This finds a past version of the [CredentialProviderBeginSignInController] if it exists,
@@ -200,4 +254,4 @@
             return controller!!
         }
     }
-}
\ No newline at end of file
+}
diff --git a/development/auto-version-updater/update_versions_for_release.py b/development/auto-version-updater/update_versions_for_release.py
index 0cd1cd8..008f4846b 100755
--- a/development/auto-version-updater/update_versions_for_release.py
+++ b/development/auto-version-updater/update_versions_for_release.py
@@ -315,7 +315,10 @@
 
     # Open file for writing and write toml back
     with open(LIBRARY_VERSIONS_FP, 'w') as f:
-        toml.dump(library_versions, f, encoder=toml.TomlPreserveInlineDictEncoder())
+        versions_toml_file_string = toml.dumps(library_versions, encoder=toml.TomlPreserveInlineDictEncoder())
+        versions_toml_file_string_new = re.sub(",]", " ]", versions_toml_file_string)
+        f.write(versions_toml_file_string_new)
+
     return updated_version
 
 
@@ -471,7 +474,7 @@
         msg = "Update versions for release id %s\n\nThis commit was generated from the command:\n%s\n\n%s" % (
             release_date, " ".join(sys.argv), "Test: ./gradlew checkApi")
         subprocess.check_call(["git", "commit", "-m", msg], cwd=dir, stderr=subprocess.STDOUT)
-        subprocess.check_call(["repo", "upload", ".", "--cbr", "-t", "-y", "--label", "Presubmit-Ready+1"], cwd=dir,
+        subprocess.check_call(["repo", "upload", ".", "--cbr", "-t", "-y", "-o", "banned-words~skip", "--label", "Presubmit-Ready+1"], cwd=dir,
                               stderr=subprocess.STDOUT)
 
 def main(args):
diff --git a/development/project-creator/create_project.py b/development/project-creator/create_project.py
index bc1db8e..8a121f8 100755
--- a/development/project-creator/create_project.py
+++ b/development/project-creator/create_project.py
@@ -25,6 +25,7 @@
 from shutil import copyfile
 from distutils.dir_util import copy_tree
 from distutils.dir_util import DistutilsFileError
+import re
 
 try:
     # non-default python3 module, be helpful if it is missing
@@ -590,7 +591,9 @@
 
     # Open file for writing and update toml
     with open(LIBRARY_VERSIONS_FP, 'w') as f:
-        toml.dump(library_versions, f, encoder=toml.TomlPreserveInlineDictEncoder())
+        versions_toml_file_string = toml.dumps(library_versions, encoder=toml.TomlPreserveInlineDictEncoder())
+        versions_toml_file_string_new = re.sub(",]", " ]", versions_toml_file_string)
+        f.write(versions_toml_file_string_new)
 
 
 def is_group_id_atomic(group_id):
diff --git a/development/update_studio.sh b/development/update_studio.sh
index d394214..187a9d4 100755
--- a/development/update_studio.sh
+++ b/development/update_studio.sh
@@ -1,24 +1,9 @@
 #!/bin/bash
-
-function echoAndDo() {
-  echo "$@"
-  eval "$@"
-}
-
 # Get versions
-echo Getting Studio version and link
-AGP_VERSION=${1:-8.1.0-alpha03}
-STUDIO_VERSION_STRING=${2:-"Android Studio Giraffe | 2022.3.1 Canary 3"}
-STUDIO_IFRAME_LINK=`curl "https://developer.android.com/studio/archive.html" | grep "<iframe " | sed "s/.* src=\"\([^\"]*\)\".*/\1/g"`
-echo iframe link $STUDIO_IFRAME_LINK
-STUDIO_IFRAME_REDIRECT=`curl -s $STUDIO_IFRAME_LINK | grep href | sed 's/.*href="\([^"]*\)".*/\1/g'`
-echo iframe redirect $STUDIO_IFRAME_REDIRECT
-STUDIO_LINK=`curl -s $STUDIO_IFRAME_REDIRECT | grep -C30 "$STUDIO_VERSION_STRING" | grep Linux | tail -n 1 | sed 's/.*a href="\(.*\).*"/\1/g' | sed 's/>.*//'`
-echo STUDIO_LINK: $STUDIO_LINK
-if [ "$STUDIO_LINK" == "" ]; then
-  echo "Error: STUDIO_LINK must not be empty. Open this script and look for parsing errors. Does studio version '$STUDIO_VERSION_STRING' exist?"
-  exit 1
-fi
+AGP_VERSION=${1:-8.0.0-alpha07}
+STUDIO_VERSION_STRING=${2:-"Android Studio Flamingo (2022.2.1) Canary 7"}
+STUDIO_IFRAME_LINK=`curl "https://developer.android.com/studio/archive.html" | grep iframe | sed "s/.*src=\"\([a-zA-Z0-9\/\._]*\)\".*/https:\/\/android-dot-devsite-v2-prod.appspot.com\1/g"`
+STUDIO_LINK=`curl -s $STUDIO_IFRAME_LINK | grep -C30 "$STUDIO_VERSION_STRING" | grep Linux | tail -n 1 | sed 's/.*a href="\(.*\).*"/\1/g'`
 STUDIO_VERSION=`echo $STUDIO_LINK | sed "s/.*ide-zips\/\(.*\)\/android-studio-.*/\1/g"`
 
 # Update AGP
@@ -37,8 +22,7 @@
 ARTIFACTS_TO_DOWNLOAD+="com.android.tools.lint:lint-gradle:$LINT_VERSION,"
 ARTIFACTS_TO_DOWNLOAD+="com.android.tools:ninepatch:$LINT_VERSION,"
 
-# Update libs.versions.toml
-echo Updating dependency versions
+# Update studio_versions.properties
 sed -i "s/androidGradlePlugin = .*/androidGradlePlugin = \"$AGP_VERSION\"/g" gradle/libs.versions.toml
 sed -i "s/androidLint = \".*/androidLint = \"$LINT_VERSION\"/g" gradle/libs.versions.toml
 sed -i "s/androidStudio = .*/androidStudio = \"$STUDIO_VERSION\"/g" gradle/libs.versions.toml
@@ -60,4 +44,4 @@
 ARTIFACTS_TO_DOWNLOAD+="com.google.testing.platform:core:$ATP_VERSION"
 
 # Download all the artifacts
-echoAndDo ./development/importMaven/importMaven.sh "$ARTIFACTS_TO_DOWNLOAD"
+./development/importMaven/importMaven.sh "$ARTIFACTS_TO_DOWNLOAD"
\ No newline at end of file
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index b040ec5..36bbd84 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -8,16 +8,16 @@
 }
 
 dependencies {
-    docs("androidx.activity:activity:1.7.0-beta01")
-    docs("androidx.activity:activity-compose:1.7.0-beta01")
-    samples("androidx.activity:activity-compose-samples:1.7.0-beta01")
-    docs("androidx.activity:activity-ktx:1.7.0-beta01")
+    docs("androidx.activity:activity:1.8.0-alpha01")
+    docs("androidx.activity:activity-compose:1.8.0-alpha01")
+    samples("androidx.activity:activity-compose-samples:1.8.0-alpha01")
+    docs("androidx.activity:activity-ktx:1.8.0-alpha01")
     docs("androidx.ads:ads-identifier:1.0.0-alpha04")
     docs("androidx.ads:ads-identifier-provider:1.0.0-alpha04")
-    docs("androidx.annotation:annotation:1.6.0-alpha02")
+    docs("androidx.annotation:annotation:1.6.0-rc01")
     docs("androidx.annotation:annotation-experimental:1.3.0")
-    docs("androidx.appcompat:appcompat:1.7.0-alpha01")
-    docs("androidx.appcompat:appcompat-resources:1.7.0-alpha01")
+    docs("androidx.appcompat:appcompat:1.7.0-alpha02")
+    docs("androidx.appcompat:appcompat-resources:1.7.0-alpha02")
     docs("androidx.appsearch:appsearch:1.1.0-alpha02")
     docs("androidx.appsearch:appsearch-builtin-types:1.1.0-alpha02")
     docs("androidx.appsearch:appsearch-ktx:1.1.0-alpha02")
@@ -36,7 +36,7 @@
     docs("androidx.biometric:biometric:1.2.0-alpha05")
     docs("androidx.biometric:biometric-ktx:1.2.0-alpha05")
     samples("androidx.biometric:biometric-ktx-samples:1.2.0-alpha05")
-    docs("androidx.browser:browser:1.5.0-rc01")
+    docs("androidx.browser:browser:1.5.0")
     docs("androidx.camera:camera-camera2:1.3.0-alpha03")
     docs("androidx.camera:camera-core:1.3.0-alpha03")
     docs("androidx.camera:camera-extensions:1.3.0-alpha03")
@@ -54,60 +54,60 @@
     docs("androidx.cardview:cardview:1.0.0")
     docs("androidx.collection:collection:1.3.0-alpha02")
     docs("androidx.collection:collection-ktx:1.3.0-alpha02")
-    docs("androidx.compose.animation:animation:1.4.0-alpha05")
-    docs("androidx.compose.animation:animation-core:1.4.0-alpha05")
-    docs("androidx.compose.animation:animation-graphics:1.4.0-alpha05")
-    samples("androidx.compose.animation:animation-samples:1.4.0-alpha05")
-    samples("androidx.compose.animation:animation-core-samples:1.4.0-alpha05")
-    samples("androidx.compose.animation:animation-graphics-samples:1.4.0-alpha05")
-    docs("androidx.compose.foundation:foundation:1.4.0-alpha05")
-    docs("androidx.compose.foundation:foundation-layout:1.4.0-alpha05")
-    samples("androidx.compose.foundation:foundation-layout-samples:1.4.0-alpha05")
-    samples("androidx.compose.foundation:foundation-samples:1.4.0-alpha05")
-    docs("androidx.compose.material3:material3:1.1.0-alpha05")
-    samples("androidx.compose.material3:material3-samples:1.1.0-alpha05")
-    docs("androidx.compose.material3:material3-window-size-class:1.1.0-alpha05")
-    samples("androidx.compose.material3:material3-window-size-class-samples:1.1.0-alpha05")
-    docs("androidx.compose.material:material:1.4.0-alpha05")
-    docs("androidx.compose.material:material-icons-core:1.4.0-alpha05")
-    samples("androidx.compose.material:material-icons-core-samples:1.4.0-alpha05")
-    docs("androidx.compose.material:material-ripple:1.4.0-alpha05")
-    samples("androidx.compose.material:material-samples:1.4.0-alpha05")
-    docs("androidx.compose.runtime:runtime:1.4.0-alpha05")
-    docs("androidx.compose.runtime:runtime-livedata:1.4.0-alpha05")
-    samples("androidx.compose.runtime:runtime-livedata-samples:1.4.0-alpha05")
-    docs("androidx.compose.runtime:runtime-rxjava2:1.4.0-alpha05")
-    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.4.0-alpha05")
-    docs("androidx.compose.runtime:runtime-rxjava3:1.4.0-alpha05")
-    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.4.0-alpha05")
-    docs("androidx.compose.runtime:runtime-saveable:1.4.0-alpha05")
-    samples("androidx.compose.runtime:runtime-saveable-samples:1.4.0-alpha05")
-    samples("androidx.compose.runtime:runtime-samples:1.4.0-alpha05")
+    docs("androidx.compose.animation:animation:1.4.0-beta01")
+    docs("androidx.compose.animation:animation-core:1.4.0-beta01")
+    docs("androidx.compose.animation:animation-graphics:1.4.0-beta01")
+    samples("androidx.compose.animation:animation-samples:1.4.0-beta01")
+    samples("androidx.compose.animation:animation-core-samples:1.4.0-beta01")
+    samples("androidx.compose.animation:animation-graphics-samples:1.4.0-beta01")
+    docs("androidx.compose.foundation:foundation:1.4.0-beta01")
+    docs("androidx.compose.foundation:foundation-layout:1.4.0-beta01")
+    samples("androidx.compose.foundation:foundation-layout-samples:1.4.0-beta01")
+    samples("androidx.compose.foundation:foundation-samples:1.4.0-beta01")
+    docs("androidx.compose.material3:material3:1.1.0-alpha06")
+    samples("androidx.compose.material3:material3-samples:1.1.0-alpha06")
+    docs("androidx.compose.material3:material3-window-size-class:1.1.0-alpha06")
+    samples("androidx.compose.material3:material3-window-size-class-samples:1.1.0-alpha06")
+    docs("androidx.compose.material:material:1.4.0-beta01")
+    docs("androidx.compose.material:material-icons-core:1.4.0-beta01")
+    samples("androidx.compose.material:material-icons-core-samples:1.4.0-beta01")
+    docs("androidx.compose.material:material-ripple:1.4.0-beta01")
+    samples("androidx.compose.material:material-samples:1.4.0-beta01")
+    docs("androidx.compose.runtime:runtime:1.4.0-beta01")
+    docs("androidx.compose.runtime:runtime-livedata:1.4.0-beta01")
+    samples("androidx.compose.runtime:runtime-livedata-samples:1.4.0-beta01")
+    docs("androidx.compose.runtime:runtime-rxjava2:1.4.0-beta01")
+    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.4.0-beta01")
+    docs("androidx.compose.runtime:runtime-rxjava3:1.4.0-beta01")
+    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.4.0-beta01")
+    docs("androidx.compose.runtime:runtime-saveable:1.4.0-beta01")
+    samples("androidx.compose.runtime:runtime-saveable-samples:1.4.0-beta01")
+    samples("androidx.compose.runtime:runtime-samples:1.4.0-beta01")
     docs("androidx.compose.runtime:runtime-tracing:1.0.0-alpha02")
-    docs("androidx.compose.ui:ui:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-geometry:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-graphics:1.4.0-alpha05")
-    samples("androidx.compose.ui:ui-graphics-samples:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-test:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-test-junit4:1.4.0-alpha05")
-    samples("androidx.compose.ui:ui-test-samples:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-text:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-text-google-fonts:1.4.0-alpha05")
-    samples("androidx.compose.ui:ui-text-samples:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-tooling:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-tooling-data:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-tooling-preview:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-unit:1.4.0-alpha05")
-    samples("androidx.compose.ui:ui-unit-samples:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-util:1.4.0-alpha05")
-    docs("androidx.compose.ui:ui-viewbinding:1.4.0-alpha05")
-    samples("androidx.compose.ui:ui-viewbinding-samples:1.4.0-alpha05")
-    samples("androidx.compose.ui:ui-samples:1.4.0-alpha05")
+    docs("androidx.compose.ui:ui:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-geometry:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-graphics:1.4.0-beta01")
+    samples("androidx.compose.ui:ui-graphics-samples:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-test:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-test-junit4:1.4.0-beta01")
+    samples("androidx.compose.ui:ui-test-samples:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-text:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-text-google-fonts:1.4.0-beta01")
+    samples("androidx.compose.ui:ui-text-samples:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-tooling:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-tooling-data:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-tooling-preview:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-unit:1.4.0-beta01")
+    samples("androidx.compose.ui:ui-unit-samples:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-util:1.4.0-beta01")
+    docs("androidx.compose.ui:ui-viewbinding:1.4.0-beta01")
+    samples("androidx.compose.ui:ui-viewbinding-samples:1.4.0-beta01")
+    samples("androidx.compose.ui:ui-samples:1.4.0-beta01")
     docs("androidx.concurrent:concurrent-futures:1.1.0")
     docs("androidx.concurrent:concurrent-futures-ktx:1.1.0")
-    docs("androidx.constraintlayout:constraintlayout:2.2.0-alpha06")
-    docs("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha06")
-    docs("androidx.constraintlayout:constraintlayout-core:1.1.0-alpha06")
+    docs("androidx.constraintlayout:constraintlayout:2.2.0-alpha07")
+    docs("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha07")
+    docs("androidx.constraintlayout:constraintlayout-core:1.1.0-alpha07")
     docs("androidx.contentpager:contentpager:1.0.0")
     docs("androidx.coordinatorlayout:coordinatorlayout:1.2.0")
     docs("androidx.core.uwb:uwb:1.0.0-alpha04")
@@ -122,8 +122,9 @@
     docs("androidx.core:core:1.10.0-alpha02")
     docs("androidx.core:core-ktx:1.10.0-alpha02")
     docs("androidx.core:core-splashscreen:1.1.0-alpha01")
-    docs("androidx.credentials:credentials:1.0.0-alpha01")
-    docs("androidx.credentials:credentials-play-services-auth:1.0.0-alpha01")
+    docs("androidx.credentials:credentials:1.0.0-alpha02")
+    docs("androidx.credentials:credentials-play-services-auth:1.0.0-alpha02")
+    docs("androidx.credentials:credentials-provider:1.0.0-alpha02")
     docs("androidx.cursoradapter:cursoradapter:1.0.0")
     docs("androidx.customview:customview:1.2.0-alpha02")
     docs("androidx.customview:customview-poolingcontainer:1.0.0-rc01")
@@ -138,23 +139,23 @@
     docs("androidx.datastore:datastore-rxjava3:1.1.0-alpha01")
     docs("androidx.documentfile:documentfile:1.1.0-alpha01")
     docs("androidx.draganddrop:draganddrop:1.0.0")
-    docs("androidx.drawerlayout:drawerlayout:1.2.0-alpha01")
+    docs("androidx.drawerlayout:drawerlayout:1.2.0-beta01")
     docs("androidx.dynamicanimation:dynamicanimation:1.1.0-alpha02")
     docs("androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03")
-    docs("androidx.emoji2:emoji2:1.3.0-beta01")
-    docs("androidx.emoji2:emoji2-bundled:1.3.0-beta01")
-    docs("androidx.emoji2:emoji2-emojipicker:1.0.0-alpha01")
-    docs("androidx.emoji2:emoji2-views:1.3.0-beta01")
-    docs("androidx.emoji2:emoji2-views-helper:1.3.0-beta01")
+    docs("androidx.emoji2:emoji2:1.3.0-beta02")
+    docs("androidx.emoji2:emoji2-bundled:1.3.0-beta02")
+    docs("androidx.emoji2:emoji2-emojipicker:1.0.0-alpha02")
+    docs("androidx.emoji2:emoji2-views:1.3.0-beta02")
+    docs("androidx.emoji2:emoji2-views-helper:1.3.0-beta02")
     docs("androidx.emoji:emoji:1.2.0-alpha03")
     docs("androidx.emoji:emoji-appcompat:1.2.0-alpha03")
     docs("androidx.emoji:emoji-bundled:1.2.0-alpha03")
     docs("androidx.enterprise:enterprise-feedback:1.1.0")
     docs("androidx.enterprise:enterprise-feedback-testing:1.1.0")
-    docs("androidx.exifinterface:exifinterface:1.3.5")
-    docs("androidx.fragment:fragment:1.6.0-alpha04")
-    docs("androidx.fragment:fragment-ktx:1.6.0-alpha04")
-    docs("androidx.fragment:fragment-testing:1.6.0-alpha04")
+    docs("androidx.exifinterface:exifinterface:1.3.6")
+    docs("androidx.fragment:fragment:1.6.0-alpha05")
+    docs("androidx.fragment:fragment-ktx:1.6.0-alpha05")
+    docs("androidx.fragment:fragment-testing:1.6.0-alpha05")
     docs("androidx.glance:glance:1.0.0-alpha05")
     docs("androidx.glance:glance-appwidget:1.0.0-alpha05")
     docs("androidx.glance:glance-appwidget-preview:1.0.0-alpha05")
@@ -226,18 +227,18 @@
     docs("androidx.navigation:navigation-testing:2.6.0-alpha05")
     docs("androidx.navigation:navigation-ui:2.6.0-alpha05")
     docs("androidx.navigation:navigation-ui-ktx:2.6.0-alpha05")
-    docs("androidx.paging:paging-common:3.2.0-alpha03")
-    docs("androidx.paging:paging-common-ktx:3.2.0-alpha03")
-    docs("androidx.paging:paging-compose:1.0.0-alpha17")
+    docs("androidx.paging:paging-common:3.2.0-alpha04")
+    docs("androidx.paging:paging-common-ktx:3.2.0-alpha04")
+    docs("androidx.paging:paging-compose:1.0.0-alpha18")
     samples("androidx.paging:paging-compose-samples:3.0.0-alpha08")
-    docs("androidx.paging:paging-guava:3.2.0-alpha03")
-    docs("androidx.paging:paging-runtime:3.2.0-alpha03")
-    docs("androidx.paging:paging-runtime-ktx:3.2.0-alpha03")
-    docs("androidx.paging:paging-rxjava2:3.2.0-alpha03")
-    docs("androidx.paging:paging-rxjava2-ktx:3.2.0-alpha03")
-    docs("androidx.paging:paging-rxjava3:3.2.0-alpha03")
-    samples("androidx.paging:paging-samples:3.2.0-alpha03")
-    docs("androidx.paging:paging-testing:3.2.0-alpha03")
+    docs("androidx.paging:paging-guava:3.2.0-alpha04")
+    docs("androidx.paging:paging-runtime:3.2.0-alpha04")
+    docs("androidx.paging:paging-runtime-ktx:3.2.0-alpha04")
+    docs("androidx.paging:paging-rxjava2:3.2.0-alpha04")
+    docs("androidx.paging:paging-rxjava2-ktx:3.2.0-alpha04")
+    docs("androidx.paging:paging-rxjava3:3.2.0-alpha04")
+    samples("androidx.paging:paging-samples:3.2.0-alpha04")
+    docs("androidx.paging:paging-testing:3.2.0-alpha04")
     docs("androidx.palette:palette:1.0.0")
     docs("androidx.palette:palette-ktx:1.0.0")
     docs("androidx.percentlayout:percentlayout:1.0.1")
@@ -248,7 +249,7 @@
     docs("androidx.privacysandbox.tools:tools-apigenerator:1.0.0-alpha02")
     docs("androidx.privacysandbox.tools:tools-apipackager:1.0.0-alpha02")
     docs("androidx.privacysandbox.tools:tools-core:1.0.0-alpha02")
-    docs("androidx.profileinstaller:profileinstaller:1.3.0-alpha03")
+    docs("androidx.profileinstaller:profileinstaller:1.3.0-beta01")
     docs("androidx.recommendation:recommendation:1.0.0")
     docs("androidx.recyclerview:recyclerview:1.3.0-rc01")
     docs("androidx.recyclerview:recyclerview-selection:2.0.0-alpha01")
@@ -308,12 +309,13 @@
     docs("androidx.textclassifier:textclassifier:1.0.0-alpha04")
     docs("androidx.tracing:tracing:1.2.0-alpha02")
     docs("androidx.tracing:tracing-ktx:1.2.0-alpha02")
-    docs("androidx.tracing:tracing-perfetto:1.0.0-alpha09")
-    docs("androidx.tracing:tracing-perfetto-common:1.0.0-alpha09")
+    docs("androidx.tracing:tracing-perfetto:1.0.0-alpha10")
+    docs("androidx.tracing:tracing-perfetto-common:1.0.0-alpha10")
     docs("androidx.transition:transition:1.4.1")
     docs("androidx.transition:transition-ktx:1.4.1")
-    docs("androidx.tv:tv-foundation:1.0.0-alpha03")
-    docs("androidx.tv:tv-material:1.0.0-alpha03")
+    docs("androidx.tv:tv-foundation:1.0.0-alpha04")
+    docs("androidx.tv:tv-material:1.0.0-alpha04")
+    samples("androidx.tv:tv-samples:1.0.0-alpha04")
     docs("androidx.tvprovider:tvprovider:1.1.0-alpha01")
     docs("androidx.vectordrawable:vectordrawable:1.2.0-beta01")
     docs("androidx.vectordrawable:vectordrawable-animated:1.2.0-alpha01")
@@ -321,19 +323,19 @@
     docs("androidx.versionedparcelable:versionedparcelable:1.1.1")
     docs("androidx.viewpager2:viewpager2:1.1.0-beta01")
     docs("androidx.viewpager:viewpager:1.1.0-alpha01")
-    docs("androidx.wear.compose:compose-foundation:1.2.0-alpha03")
-    samples("androidx.wear.compose:compose-foundation-samples:1.2.0-alpha03")
-    docs("androidx.wear.compose:compose-material:1.2.0-alpha03")
-    docs("androidx.wear.compose:compose-material-core:1.2.0-alpha03")
-    samples("androidx.wear.compose:compose-material-samples:1.2.0-alpha03")
+    docs("androidx.wear.compose:compose-foundation:1.2.0-alpha04")
+    samples("androidx.wear.compose:compose-foundation-samples:1.2.0-alpha04")
+    docs("androidx.wear.compose:compose-material:1.2.0-alpha04")
+    docs("androidx.wear.compose:compose-material-core:1.2.0-alpha04")
+    samples("androidx.wear.compose:compose-material-samples:1.2.0-alpha04")
     docs("androidx.wear.compose:compose-material3:1.0.0-alpha01")
-    samples("androidx.wear.compose:compose-material3-samples:1.2.0-alpha03")
-    docs("androidx.wear.compose:compose-navigation:1.2.0-alpha03")
-    samples("androidx.wear.compose:compose-navigation-samples:1.2.0-alpha03")
-    docs("androidx.wear.protolayout:protolayout:1.0.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-expression:1.0.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-proto:1.0.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-renderer:1.0.0-alpha02")
+    samples("androidx.wear.compose:compose-material3-samples:1.2.0-alpha04")
+    docs("androidx.wear.compose:compose-navigation:1.2.0-alpha04")
+    samples("androidx.wear.compose:compose-navigation-samples:1.2.0-alpha04")
+    docs("androidx.wear.protolayout:protolayout:1.0.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-expression:1.0.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-proto:1.0.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-renderer:1.0.0-alpha03")
     docs("androidx.wear.tiles:tiles:1.1.0")
     docs("androidx.wear.tiles:tiles-material:1.1.0")
     docs("androidx.wear.tiles:tiles-proto:1.1.0")
@@ -363,7 +365,7 @@
     docs("androidx.wear:wear-input:1.2.0-alpha02")
     samples("androidx.wear:wear-input-samples:1.2.0-alpha01")
     docs("androidx.wear:wear-input-testing:1.2.0-alpha02")
-    docs("androidx.webkit:webkit:1.7.0-alpha01")
+    docs("androidx.webkit:webkit:1.7.0-alpha02")
     docs("androidx.window:window:1.1.0-alpha04")
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
     docs("androidx.window:window-core:1.1.0-alpha04")
@@ -372,11 +374,11 @@
     docs("androidx.window:window-rxjava2:1.1.0-alpha04")
     docs("androidx.window:window-rxjava3:1.1.0-alpha04")
     docs("androidx.window:window-testing:1.1.0-alpha04")
-    docs("androidx.work:work-gcm:2.8.0-rc01")
-    docs("androidx.work:work-multiprocess:2.8.0-rc01")
-    docs("androidx.work:work-runtime:2.8.0-rc01")
-    docs("androidx.work:work-runtime-ktx:2.8.0-rc01")
-    docs("androidx.work:work-rxjava2:2.8.0-rc01")
-    docs("androidx.work:work-rxjava3:2.8.0-rc01")
-    docs("androidx.work:work-testing:2.8.0-rc01")
+    docs("androidx.work:work-gcm:2.8.0")
+    docs("androidx.work:work-multiprocess:2.8.0")
+    docs("androidx.work:work-runtime:2.8.0")
+    docs("androidx.work:work-runtime-ktx:2.8.0")
+    docs("androidx.work:work-rxjava2:2.8.0")
+    docs("androidx.work:work-rxjava3:2.8.0")
+    docs("androidx.work:work-testing:2.8.0")
 }
diff --git a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
index 64702c0..58b53c0 100644
--- a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
+++ b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
@@ -59,6 +59,7 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -874,6 +875,7 @@
 
     }
 
+    @Ignore // b/268534501
     @Test
     @SdkSuppress(minSdkVersion = 33, maxSdkVersion = 33) // b/262909049: Failing on SDK 34
     public void testDurationScaleChangeListener() throws InterruptedException {
diff --git a/emoji2/emoji2-emojipicker/samples/src/main/res/layout-land/main.xml b/emoji2/emoji2-emojipicker/samples/src/main/res/layout-land/main.xml
index 6f076ad..7c10005 100644
--- a/emoji2/emoji2-emojipicker/samples/src/main/res/layout-land/main.xml
+++ b/emoji2/emoji2-emojipicker/samples/src/main/res/layout-land/main.xml
@@ -46,6 +46,5 @@
         android:id="@+id/emoji_picker"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        app:emojiGridColumns="20"
-        app:emojiGridRows="5" />
+        app:emojiGridColumns="20" />
 </LinearLayout>
diff --git a/emoji2/emoji2-emojipicker/samples/src/main/res/layout/main.xml b/emoji2/emoji2-emojipicker/samples/src/main/res/layout/main.xml
index 085f307..f79a375 100644
--- a/emoji2/emoji2-emojipicker/samples/src/main/res/layout/main.xml
+++ b/emoji2/emoji2-emojipicker/samples/src/main/res/layout/main.xml
@@ -46,6 +46,5 @@
         android:id="@+id/emoji_picker"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        app:emojiGridRows="15"
         app:emojiGridColumns="9" />
 </LinearLayout>
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerBodyAdapter.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerBodyAdapter.kt
index 4f688fd..7f8fa6b9 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerBodyAdapter.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerBodyAdapter.kt
@@ -33,7 +33,7 @@
 internal class EmojiPickerBodyAdapter(
     private val context: Context,
     private val emojiGridColumns: Int,
-    private val emojiGridRows: Float,
+    private val emojiGridRows: Float?,
     private val stickyVariantProvider: StickyVariantProvider,
     private val emojiPickerItemsProvider: () -> EmojiPickerItems,
     private val onEmojiPickedListener: EmojiPickerBodyAdapter.(EmojiViewItem) -> Unit,
@@ -43,25 +43,25 @@
     private var emojiCellHeight: Int? = null
 
     @UiThread
-    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
-        when (viewType.toItemType()) {
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+        emojiCellWidth = emojiCellWidth ?: (getParentWidth(parent) / emojiGridColumns)
+        emojiCellHeight =
+            emojiCellHeight ?: emojiGridRows?.let { getEmojiCellTotalHeight(parent) / it }
+                ?.toInt() ?: emojiCellWidth
+
+        return when (viewType.toItemType()) {
             ItemType.CATEGORY_TITLE -> createSimpleHolder(R.layout.category_text_view, parent)
             ItemType.PLACEHOLDER_TEXT -> createSimpleHolder(
                 R.layout.empty_category_text_view, parent
             ) {
-                minimumHeight =
-                    emojiCellHeight ?: (getEmojiCellTotalHeight(parent) / (emojiGridRows)).toInt()
-                        .also { emojiCellHeight = it }
+                minimumHeight = emojiCellHeight!!
             }
 
             ItemType.EMOJI -> {
                 EmojiViewHolder(context,
                     parent,
-                    emojiCellWidth ?: (getParentWidth(parent) / emojiGridColumns).also {
-                        emojiCellWidth = it
-                    },
-                    emojiCellHeight ?: (getEmojiCellTotalHeight(parent) / (emojiGridRows)).toInt()
-                        .also { emojiCellHeight = it },
+                    emojiCellWidth!!,
+                    emojiCellHeight!!,
                     layoutInflater,
                     stickyVariantProvider,
                     onEmojiPickedListener = { emojiViewItem ->
@@ -81,9 +81,8 @@
                         }
                     })
             }
-
-            ItemType.PLACEHOLDER_EMOJI -> object : ViewHolder(View(context)) {}
         }
+    }
 
     override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
         val item = emojiPickerItemsProvider().getBodyItem(position)
@@ -99,8 +98,6 @@
             ItemType.EMOJI -> {
                 (viewHolder as EmojiViewHolder).bindEmoji((item as EmojiViewData).emoji)
             }
-
-            ItemType.PLACEHOLDER_EMOJI -> {}
         }
     }
 
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerConstants.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerConstants.kt
index 479e1ff..0956f96 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerConstants.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerConstants.kt
@@ -22,9 +22,6 @@
     // The default number of body columns.
     const val DEFAULT_BODY_COLUMNS = 9
 
-    // The default number of body rows.
-    const val DEFAULT_BODY_ROWS = 7.5f
-
     // The default number of rows of recent items held.
     const val DEFAULT_MAX_RECENT_ITEM_ROWS = 3
 
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerItems.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerItems.kt
index 33ea012..7ac2aa6 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerItems.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerItems.kt
@@ -24,8 +24,7 @@
  * [titleItem] comes first.
  * [contentItems] comes after [titleItem].
  * [emptyPlaceholderItem] will be served after [titleItem] only if [contentItems] is empty.
- * [forceContentSize], if provided, will truncate [contentItems] to certain size or pad with
- * [PlaceholderEmoji]s.
+ * [maxContentItemCount], if provided, will truncate [contentItems] to certain size.
  *
  * [categoryIconId] is the corresponding category icon in emoji picker header.
  */
@@ -33,23 +32,24 @@
     @DrawableRes internal val categoryIconId: Int,
     internal val titleItem: CategoryTitle,
     private val contentItems: List<EmojiViewData>,
-    private val forceContentSize: Int? = null,
+    private val maxContentItemCount: Int? = null,
     private val emptyPlaceholderItem: PlaceholderText? = null
 ) {
 
     val size: Int
-        get() = 1 /* title */ +
-            (forceContentSize ?: maxOf(
-                contentItems.size,
-                if (emptyPlaceholderItem != null) 1 else 0
-            ))
+        get() = 1 /* title */ + when {
+            contentItems.isEmpty() -> if (emptyPlaceholderItem != null) 1 else 0
+            maxContentItemCount != null && contentItems.size > maxContentItemCount ->
+                maxContentItemCount
+            else -> contentItems.size
+        }
 
     operator fun get(index: Int): ItemViewData {
         if (index == 0) return titleItem
         val contentIndex = index - 1
         if (contentIndex < contentItems.size) return contentItems[contentIndex]
         if (contentIndex == 0 && emptyPlaceholderItem != null) return emptyPlaceholderItem
-        return PlaceholderEmoji
+        throw IndexOutOfBoundsException()
     }
 
     fun getAll(): List<ItemViewData> = IntRange(0, size - 1).map { get(it) }
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerView.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerView.kt
index ca5569f..c7f1d07 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerView.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerView.kt
@@ -50,19 +50,21 @@
         internal var emojiCompatLoaded: Boolean = false
     }
 
+    private var _emojiGridRows: Float? = null
     /**
      * The number of rows of the emoji picker.
      *
-     * Default value([EmojiPickerConstants.DEFAULT_BODY_ROWS]: 7.5) will be used if emojiGridRows
-     * is set to non-positive value. Float value indicates that we will display partial of the last
-     * row and have content down, so the users get the idea that they can scroll down for more
-     * contents.
+     * Optional field. If not set, the value will be calculated based on parent view height and
+     * [emojiGridColumns].
+     * Float value indicates that the picker could display the last row partially, so the users get
+     * the idea that they can scroll down for more contents.
      * @attr ref androidx.emoji2.emojipicker.R.styleable.EmojiPickerView_emojiGridRows
      */
-    var emojiGridRows: Float = EmojiPickerConstants.DEFAULT_BODY_ROWS
+    var emojiGridRows: Float
+        get() = _emojiGridRows ?: -1F
         set(value) {
-            field = if (value > 0) value else EmojiPickerConstants.DEFAULT_BODY_ROWS
-            // this step is to ensure the layout refresh when emojiGridRows is reset
+            _emojiGridRows = value.takeIf { it > 0 }
+            // Refresh when emojiGridRows is reset
             if (isLaidOut) {
                 showEmojiPickerView()
             }
@@ -77,8 +79,8 @@
      */
     var emojiGridColumns: Int = EmojiPickerConstants.DEFAULT_BODY_COLUMNS
         set(value) {
-            field = if (value > 0) value else EmojiPickerConstants.DEFAULT_BODY_COLUMNS
-            // this step is to ensure the layout refresh when emojiGridColumns is reset
+            field = value.takeIf { it > 0 } ?: EmojiPickerConstants.DEFAULT_BODY_COLUMNS
+            // Refresh when emojiGridColumns is reset
             if (isLaidOut) {
                 showEmojiPickerView()
             }
@@ -88,6 +90,7 @@
     private val scope = CoroutineScope(EmptyCoroutineContext)
 
     private var recentEmojiProvider: RecentEmojiProvider = DefaultRecentEmojiProvider(context)
+    private var recentNeedsRefreshing: Boolean = true
     private val recentItems: MutableList<EmojiViewData> = mutableListOf()
     private lateinit var recentItemGroup: ItemGroup
 
@@ -99,10 +102,11 @@
     init {
         val typedArray: TypedArray =
             context.obtainStyledAttributes(attrs, R.styleable.EmojiPickerView, 0, 0)
-        emojiGridRows = typedArray.getFloat(
-            R.styleable.EmojiPickerView_emojiGridRows,
-            EmojiPickerConstants.DEFAULT_BODY_ROWS
-        )
+        _emojiGridRows = with(R.styleable.EmojiPickerView_emojiGridRows) {
+            if (typedArray.hasValue(this)) {
+                typedArray.getFloat(this, 0F)
+            } else null
+        }
         emojiGridColumns = typedArray.getInt(
             R.styleable.EmojiPickerView_emojiGridColumns,
             EmojiPickerConstants.DEFAULT_BODY_COLUMNS
@@ -145,15 +149,13 @@
         return EmojiPickerBodyAdapter(
             context,
             emojiGridColumns,
-            emojiGridRows,
+            _emojiGridRows,
             stickyVariantProvider,
             emojiPickerItemsProvider = { emojiPickerItems },
             onEmojiPickedListener = { emojiViewItem ->
                 onEmojiPickedListener?.accept(emojiViewItem)
-
-                scope.launch {
-                    recentEmojiProvider.recordSelection(emojiViewItem.emoji)
-                }
+                recentEmojiProvider.recordSelection(emojiViewItem.emoji)
+                recentNeedsRefreshing = true
             }
         )
     }
@@ -163,7 +165,7 @@
             R.drawable.quantum_gm_ic_access_time_filled_vd_theme_24,
             CategoryTitle(context.getString(R.string.emoji_category_recent)),
             recentItems,
-            forceContentSize = DEFAULT_MAX_RECENT_ITEM_ROWS * emojiGridColumns,
+            maxContentItemCount = DEFAULT_MAX_RECENT_ITEM_ROWS * emojiGridColumns,
             emptyPlaceholderItem = PlaceholderText(
                 context.getString(R.string.emoji_empty_recent_category)
             )
@@ -194,7 +196,6 @@
             spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
                 override fun getSpanSize(position: Int): Int {
                     return when (emojiPickerItems.getBodyItem(position).itemType) {
-                        ItemType.PLACEHOLDER_EMOJI -> 0
                         ItemType.CATEGORY_TITLE, ItemType.PLACEHOLDER_TEXT -> emojiGridColumns
                         else -> 1
                     }
@@ -243,11 +244,14 @@
                 addOnScrollListener(object : RecyclerView.OnScrollListener() {
                     override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                         super.onScrolled(recyclerView, dx, dy)
-                        val position =
-                            bodyLayoutManager.findFirstCompletelyVisibleItemPosition()
                         headerAdapter.selectedGroupIndex =
-                            emojiPickerItems.groupIndexByItemPosition(position)
-                        if (position !in emojiPickerItems.groupRange(recentItemGroup)) {
+                            emojiPickerItems.groupIndexByItemPosition(
+                                bodyLayoutManager.findFirstCompletelyVisibleItemPosition()
+                            )
+                        if (recentNeedsRefreshing &&
+                            bodyLayoutManager.findFirstVisibleItemPosition() !in
+                            emojiPickerItems.groupRange(recentItemGroup)
+                        ) {
                             scope.launch {
                                 refreshRecent()
                             }
@@ -268,18 +272,37 @@
     }
 
     internal suspend fun refreshRecent() {
+        if (!recentNeedsRefreshing) {
+            return
+        }
+        val oldGroupSize = if (::recentItemGroup.isInitialized) recentItemGroup.size else 0
         val recent = recentEmojiProvider.getRecentEmojiList()
-        recentItems.clear()
-        recentItems.addAll(recent.map {
-            EmojiViewData(
-                it,
-                updateToSticky = false,
-            )
-        })
-        if (isLaidOut) {
-            val range = emojiPickerItems.groupRange(recentItemGroup)
-            withContext(Dispatchers.Main) {
-                bodyAdapter.notifyItemRangeChanged(range.first, range.last + 1)
+        withContext(Dispatchers.Main) {
+            recentItems.clear()
+            recentItems.addAll(recent.map {
+                EmojiViewData(
+                    it,
+                    updateToSticky = false,
+                )
+            })
+            if (::emojiPickerItems.isInitialized) {
+                val range = emojiPickerItems.groupRange(recentItemGroup)
+                if (recentItemGroup.size > oldGroupSize) {
+                    bodyAdapter.notifyItemRangeInserted(
+                        range.first + oldGroupSize,
+                        recentItemGroup.size - oldGroupSize
+                    )
+                } else if (recentItemGroup.size < oldGroupSize) {
+                    bodyAdapter.notifyItemRangeRemoved(
+                        range.first + recentItemGroup.size,
+                        oldGroupSize - recentItemGroup.size
+                    )
+                }
+                bodyAdapter.notifyItemRangeChanged(
+                    range.first,
+                    minOf(oldGroupSize, recentItemGroup.size)
+                )
+                recentNeedsRefreshing = false
             }
         }
     }
@@ -295,6 +318,7 @@
     fun setRecentEmojiProvider(recentEmojiProvider: RecentEmojiProvider) {
         this.recentEmojiProvider = recentEmojiProvider
         scope.launch {
+            recentNeedsRefreshing = true
             refreshRecent()
         }
     }
@@ -406,4 +430,4 @@
     override fun removeViewsInLayout(start: Int, count: Int) {
         throw UnsupportedOperationException(EmojiPickerConstants.REMOVE_VIEW_EXCEPTION_MESSAGE)
     }
-}
+}
\ No newline at end of file
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/ItemViewData.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/ItemViewData.kt
index d71b573..73a1549 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/ItemViewData.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/ItemViewData.kt
@@ -20,7 +20,6 @@
     CATEGORY_TITLE,
     PLACEHOLDER_TEXT,
     EMOJI,
-    PLACEHOLDER_EMOJI,
 }
 
 /**
@@ -50,8 +49,6 @@
     val dataIndex: Int = 0
 ) : ItemViewData(ItemType.EMOJI)
 
-internal object PlaceholderEmoji : ItemViewData(ItemType.PLACEHOLDER_EMOJI)
-
 internal object Extensions {
     internal fun Int.toItemType() = ItemType.values()[this]
 }
diff --git a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentIssueRegistry.kt b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentIssueRegistry.kt
index f44dbf7..3032c3a 100644
--- a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentIssueRegistry.kt
+++ b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentIssueRegistry.kt
@@ -26,7 +26,7 @@
 @Suppress("UnstableApiUsage")
 class FragmentIssueRegistry : IssueRegistry() {
     // tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         FragmentTagDetector.ISSUE,
diff --git a/fragment/fragment-testing-lint/src/main/java/androidx/fragment/testing/lint/FragmentTestingIssueRegistry.kt b/fragment/fragment-testing-lint/src/main/java/androidx/fragment/testing/lint/FragmentTestingIssueRegistry.kt
index 304b578..3ba8a76 100644
--- a/fragment/fragment-testing-lint/src/main/java/androidx/fragment/testing/lint/FragmentTestingIssueRegistry.kt
+++ b/fragment/fragment-testing-lint/src/main/java/androidx/fragment/testing/lint/FragmentTestingIssueRegistry.kt
@@ -22,7 +22,7 @@
 
 @Suppress("UnstableApiUsage")
 class FragmentTestingIssueRegistry : IssueRegistry() {
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(GradleConfigurationDetector.ISSUE)
     override val vendor = Vendor(
diff --git a/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/FragmentTestingManifestIssueRegistry.kt b/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/FragmentTestingManifestIssueRegistry.kt
index 41a082b..7ce1350 100644
--- a/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/FragmentTestingManifestIssueRegistry.kt
+++ b/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/FragmentTestingManifestIssueRegistry.kt
@@ -22,7 +22,7 @@
 
 @Suppress("UnstableApiUsage")
 class FragmentTestingManifestIssueRegistry : IssueRegistry() {
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(GradleConfigurationDetector.ISSUE)
     override val vendor = Vendor(
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
index e941ddc..a57500f 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
@@ -31,6 +31,7 @@
 import androidx.glance.action.clickable
 import androidx.glance.appwidget.lazy.LazyColumn
 import androidx.glance.appwidget.lazy.ReservedItemIdRangeEnd
+import androidx.glance.appwidget.lazy.items
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.padding
 import androidx.glance.text.Text
@@ -38,6 +39,13 @@
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.assertIs
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.FlowPreview
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.debounce
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
 import org.junit.Rule
 import org.junit.Test
 
@@ -341,6 +349,41 @@
         }
     }
 
+    @OptIn(FlowPreview::class)
+    @Test
+    fun clickTriggersOnlyOneLambda() = runBlocking {
+        val received = MutableStateFlow(-1)
+        TestGlanceAppWidget.uiDefinition = {
+            LazyColumn {
+                items((0..4).toList()) {
+                    Button(
+                        "$it",
+                        onClick = {
+                            launch { received.emit(it) }
+                        }
+                    )
+                }
+            }
+        }
+
+        mHostRule.startHost()
+
+        val buttons = arrayOfNulls<FrameLayout>(5)
+        waitForListViewChildren { list ->
+            for (it in 0..4) {
+                val button = list.getUnboxedListItem<FrameLayout>(it)
+                buttons[it] = assertIs<FrameLayout>(button)
+            }
+        }
+        (0..4).shuffled().forEach { index ->
+            mHostRule.onHostActivity {
+                buttons[index]!!.performClick()
+            }
+            val lastClicked = received.debounce(500.milliseconds).first()
+            assertThat(lastClicked).isEqualTo(index)
+        }
+    }
+
     private fun waitForListViewChildren(action: (list: ListView) -> Unit = {}) {
         mHostRule.onHostView { }
 
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyList.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyList.kt
index a9286e32..5e4d046 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyList.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyList.kt
@@ -17,6 +17,7 @@
 package androidx.glance.appwidget.lazy
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.key
 import androidx.glance.Emittable
 import androidx.glance.EmittableWithChildren
 import androidx.glance.GlanceModifier
@@ -99,14 +100,18 @@
     alignment: Alignment,
     content: @Composable () -> Unit
 ) {
-    GlanceNode(
-        factory = ::EmittableLazyListItem,
-        update = {
-            this.set(itemId) { this.itemId = it }
-            this.set(alignment) { this.alignment = it }
-        },
-        content = content
-    )
+    // We wrap LazyListItem in the key composable to ensure that lambda actions declared within each
+    // item's scope will get a unique ID based on the currentCompositeKeyHash.
+    key(itemId) {
+        GlanceNode(
+            factory = ::EmittableLazyListItem,
+            update = {
+                this.set(itemId) { this.itemId = it }
+                this.set(alignment) { this.alignment = it }
+            },
+            content = content
+        )
+    }
 }
 
 /**
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
index 79ace6f..c0d1f50 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
@@ -23,6 +23,7 @@
 import androidx.glance.layout.fillMaxWidth
 import androidx.glance.layout.wrapContentHeight
 import androidx.annotation.RequiresApi
+import androidx.compose.runtime.key
 import androidx.compose.ui.unit.Dp
 import androidx.glance.Emittable
 
@@ -105,14 +106,18 @@
     alignment: Alignment,
     content: @Composable () -> Unit
 ) {
-    GlanceNode(
-        factory = ::EmittableLazyVerticalGridListItem,
-        update = {
-            this.set(itemId) { this.itemId = it }
-            this.set(alignment) { this.alignment = it }
-        },
-        content = content
-    )
+    // We wrap LazyVerticalGridItem in the key composable to ensure that lambda actions declared
+    // within each item's scope will get a unique ID based on the currentCompositeKeyHash.
+    key(itemId) {
+        GlanceNode(
+            factory = ::EmittableLazyVerticalGridListItem,
+            update = {
+                this.set(itemId) { this.itemId = it }
+                this.set(alignment) { this.alignment = it }
+            },
+            content = content
+        )
+    }
 }
 
 @JvmDefaultWithCompatibility
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 3a0ccb7..8407295 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -2,13 +2,13 @@
 # -----------------------------------------------------------------------------
 # All of the following should be updated in sync.
 # -----------------------------------------------------------------------------
-androidGradlePlugin = "8.1.0-alpha03"
+androidGradlePlugin = "8.0.0-alpha07"
 # NOTE: When updating the lint version we also need to update the `api` version
 # supported by `IssueRegistry`'s.' For e.g. r.android.com/1331903
-androidLint = "31.1.0-alpha03"
+androidLint = "31.0.0-alpha07"
 # Once you have a chosen version of AGP to upgrade to, go to
 # https://developer.android.com/studio/archive and find the matching version of Studio.
-androidStudio = "2022.3.1.3"
+androidStudio = "2022.2.1.7"
 # -----------------------------------------------------------------------------
 
 androidGradlePluginMin = "7.0.4"
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 22a9b26..49b6a25 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -29,20 +29,15 @@
          <trust group="^com[.]android($|([.].*))" regex="true" reason="b/215430394"/>
       </trusted-artifacts>
       <trusted-keys>
-         <trusted-key id="00089ee8c3afa95a854d0f1df800dd0933ecf7f7" group="com.google.guava" name="guava"/>
-         <trusted-key id="012579464d01c06a" group="org.apache"/>
-         <trusted-key id="019082bc00e0324e2aef4cf00d3b328562a119a7" group="org.openjdk.jmh"/>
-         <trusted-key id="02216ed811210daa" group="io.github.detekt.sarif4k"/>
-         <trusted-key id="0315bfb7970a144f">
-            <trusting group="com.sun.istack"/>
-            <trusting group="com.sun.xml.bind.mvn"/>
-            <trusting group="com.sun.xml.fastinfoset"/>
-            <trusting group="javax.xml.bind"/>
-            <trusting group="org.glassfish.jaxb"/>
-            <trusting group="org.jvnet.staxex"/>
+         <trusted-key id="00089ee8c3afa95a854d0f1df800dd0933ecf7f7">
+            <trusting group="com.google.guava"/>
+            <trusting group="com.google.guava" name="guava"/>
          </trusted-key>
-         <trusted-key id="0374cf2e8dd1bdfd" group="org.sonatype.oss"/>
-         <trusted-key id="042b29e928995b9db963c636c7ca19b7b620d787" group="org.apache.maven" name="maven-ant-tasks"/>
+         <trusted-key id="019082bc00e0324e2aef4cf00d3b328562a119a7" group="org.openjdk.jmh"/>
+         <trusted-key id="042b29e928995b9db963c636c7ca19b7b620d787">
+            <trusting group="org.apache.maven"/>
+            <trusting group="org.apache.maven" name="maven-ant-tasks"/>
+         </trusted-key>
          <trusted-key id="04543577d6a9cc626239c50c7ecbd740ff06aeb5">
             <trusting group="com.sun.activation"/>
             <trusting group="com.sun.istack"/>
@@ -51,22 +46,25 @@
             <trusting group="org.jvnet.staxex"/>
             <trusting group="^com[.]sun($|([.].*))" regex="true"/>
          </trusted-key>
-         <trusted-key id="04e9b2e1f06ecbbe0ed0aac562ba9c275d14234e" group="^com[.]squareup($|([.].*))" regex="true"/>
+         <trusted-key id="04e9b2e1f06ecbbe0ed0aac562ba9c275d14234e">
+            <trusting group="com.squareup.curtains"/>
+            <trusting group="com.squareup.leakcanary"/>
+            <trusting group="^com[.]squareup($|([.].*))" regex="true"/>
+         </trusted-key>
          <trusted-key id="06a228aab83a18a8df7b84b08614d6ab265b4c63" group="org.apache.ant"/>
          <trusted-key id="0785b3eff60b1b1bea94e0bb7c25280eae63ebe5" group="org.apache.httpcomponents"/>
          <trusted-key id="08f0aab4d0c1a4bdde340765b341ddb020fcb6ab" group="org.bouncycastle"/>
-         <trusted-key id="09a79e1e15a04694" group="org.vafer"/>
          <trusted-key id="0cc641c3a62453ab390066c4a41f13c999945293" group="commons-logging"/>
+         <trusted-key id="0cde80149711eb46dff17ae421a24b3f8b0f594a" group="org.apache"/>
          <trusted-key id="0d35d3f60078655126908e8af3d1600878e85a3d" group="io.netty"/>
          <trusted-key id="0d5d634755737a19abbe2930d4da5eab3cd7e958" group="com.google.devtools.ksp"/>
-         <trusted-key id="0d8f8561aa7a5dd20bae27043c0a8f4744f37328" group="com.github.ben-manes.caffeine" name="caffeine"/>
-         <trusted-key id="0e91c2de43b72bb1" group="org.ec4j.core"/>
+         <trusted-key id="0d8f8561aa7a5dd20bae27043c0a8f4744f37328">
+            <trusting group="com.github.ben-manes.caffeine"/>
+            <trusting group="com.github.ben-manes.caffeine" name="caffeine"/>
+         </trusted-key>
          <trusted-key id="0eb9d7c468f97e44051d650ad73c68ee4152c255" group="com.google.dagger"/>
          <trusted-key id="0f07d1201bddab67cfb84eb479752db6c966f0b8" group="com.google.android"/>
-         <trusted-key id="10066a9707090cf9" group="org.javassist"/>
-         <trusted-key id="10ae8966a146e8be" group="com.google.crypto.tink"/>
          <trusted-key id="10f3c7a02eca55e502badcf3991efb94db91127d" group="org.ow2"/>
-         <trusted-key id="1188b69f6d6259ca" group="com.google.accompanist"/>
          <trusted-key id="11b581967f079a30a3e93140d57506cd188fd842" group="com.google.api.grpc"/>
          <trusted-key id="120d6f34e627ed3a772ebbfe55c7e5e701832382">
             <trusting group="org.snakeyaml"/>
@@ -75,17 +73,27 @@
          <trusted-key id="12d16069219c90212a974d119ae296fd02e9f65b" group="org.apache.commons" name="commons-math3"/>
          <trusted-key id="13ac2213964abe1d1c147c0e1939a2520bab1d90" group="org.freemarker" name="freemarker"/>
          <trusted-key id="147b691a19097624902f4ea9689cbe64f4bc997f" group="^org[.]mockito($|([.].*))" regex="true"/>
-         <trusted-key id="151ba00a46886a5f95441a0f5d67bffcba1f9a39" group="com.google.gradle" name="osdetector-gradle-plugin"/>
+         <trusted-key id="151ba00a46886a5f95441a0f5d67bffcba1f9a39" group="com.google.gradle"/>
          <trusted-key id="1597ab231b7add7e14b1d9c43f00db67ae236e2e" group="org.conscrypt"/>
-         <trusted-key id="160a7a9cf46221a56b06ad64461a804f2609fd89" group="com.github.shyiko.klob" name="klob"/>
-         <trusted-key id="1861c322c56014b2" group="commons-lang"/>
+         <trusted-key id="160a7a9cf46221a56b06ad64461a804f2609fd89">
+            <trusting group="com.github.shyiko.klob"/>
+            <trusting group="com.github.shyiko.klob" name="klob"/>
+         </trusted-key>
          <trusted-key id="187366a3ffe6bf8f94b9136a9987b20c8f6a3064" group="com.google.protobuf"/>
-         <trusted-key id="190d5a957ff22273e601f7a7c92c5fec70161c62" group="org.codehaus.mojo"/>
+         <trusted-key id="190d5a957ff22273e601f7a7c92c5fec70161c62">
+            <trusting group="org.apache"/>
+            <trusting group="org.codehaus.mojo"/>
+         </trusted-key>
          <trusted-key id="19beab2d799c020f17c69126b16698a4adf4d638" group="org.checkerframework"/>
-         <trusted-key id="1b2718089ce964b8" group="com.thoughtworks.qdox"/>
-         <trusted-key id="1bc86444bbd2a24c3a40904a438e9634a2319637" group="co.nstant.in" name="cbor"/>
+         <trusted-key id="1bc86444bbd2a24c3a40904a438e9634a2319637">
+            <trusting group="co.nstant.in"/>
+            <trusting group="co.nstant.in" name="cbor"/>
+         </trusted-key>
          <trusted-key id="1cb7a3dbc99b562d69bfdfedae7af7ae095eb290" group="net.saff.checkmark"/>
-         <trusted-key id="1d0a8b5e77c678a7c724445abf984b4145ea13f7" group="com.squareup"/>
+         <trusted-key id="1d0a8b5e77c678a7c724445abf984b4145ea13f7">
+            <trusting group="com.squareup"/>
+            <trusting group="com.squareup" name="javapoet"/>
+         </trusted-key>
          <trusted-key id="1d9aa7f9e1e2824728b8cd1794b291aef984a085">
             <trusting group="io.reactivex"/>
             <trusting group="io.reactivex.rxjava2"/>
@@ -93,48 +101,50 @@
          </trusted-key>
          <trusted-key id="1dbb44e80f61493d6369b5fb95c15058a5eda4f1">
             <trusting group="com.google.gradle"/>
+            <trusting group="com.google.protobuf"/>
             <trusting group="com.google.protobuf" name="protobuf-gradle-plugin"/>
          </trusted-key>
-         <trusted-key id="1f47744c9b6e14f2049c2857f1f111af65925306" group="io.github.classgraph" name="classgraph"/>
-         <trusted-key id="1f8cf885d537a431" group="com.nhaarman.mockitokotlin2"/>
+         <trusted-key id="1f47744c9b6e14f2049c2857f1f111af65925306">
+            <trusting group="io.github.classgraph"/>
+            <trusting group="io.github.classgraph" name="classgraph"/>
+         </trusted-key>
          <trusted-key id="1fa37fbe4453c1073e7ef61d6449005f96bc97a3" group="de.undercouch"/>
-         <trusted-key id="205c8673dc742c7c" group="org.apache"/>
          <trusted-key id="20723a6399bc060154283b37cfae163b64ac9189" group="org.jetbrains.skiko"/>
-         <trusted-key id="21200d723f53ce38" group="com.squareup.leakcanary"/>
-         <trusted-key id="218fa0f6a941a037" group="com.github.kevinstern"/>
-         <trusted-key id="21939ff0ca2a6567" group="commons-codec"/>
-         <trusted-key id="21a24b3f8b0f594a" group="org.apache"/>
-         <trusted-key id="22b79f456b06f4e75b8b579db57bd58ef6d0a713" group="com.google.protobuf" name="protoc"/>
-         <trusted-key id="22e44ac0622b91c3" group="com.beust"/>
-         <trusted-key id="2383163bc40844fd" group="org.reactivestreams"/>
+         <trusted-key id="22b79f456b06f4e75b8b579db57bd58ef6d0a713">
+            <trusting group="com.google.protobuf"/>
+            <trusting group="com.google.protobuf" name="protoc"/>
+         </trusted-key>
          <trusted-key id="24d04176586361fda94ee0315f7786df73e61f56" group="com.google.devtools.ksp"/>
          <trusted-key id="26063b04869f7d235ccc057447586a1b75ef0de5" group="com.squareup.wire"/>
          <trusted-key id="263923711ef4fe3f3f0c28af11509ed50ec155e6" group="org.reactivestreams"/>
-         <trusted-key id="2a4f55d9cda5877731fbe7466eff5ef5523052d4" group="com.github.tschuchortdev" name="kotlin-compile-testing"/>
-         <trusted-key id="2bab4466b44f54f8f99bbbdd5ed22f661bbf0acc" group="com.almworks.sqlite4java" name="sqlite4java"/>
+         <trusted-key id="2a4f55d9cda5877731fbe7466eff5ef5523052d4">
+            <trusting group="com.github.tschuchortdev"/>
+            <trusting group="com.github.tschuchortdev" name="kotlin-compile-testing"/>
+         </trusted-key>
+         <trusted-key id="2bab4466b44f54f8f99bbbdd5ed22f661bbf0acc">
+            <trusting group="com.almworks.sqlite4java"/>
+            <trusting group="com.almworks.sqlite4java" name="sqlite4java"/>
+         </trusted-key>
          <trusted-key id="2bcbdd0f23ea1cafcc11d4860374cf2e8dd1bdfd">
             <trusting group="net.java"/>
             <trusting group="org.codehaus"/>
+            <trusting group="org.sonatype.oss"/>
          </trusted-key>
-         <trusted-key id="2be5d98f751f4136" group="org.pcollections"/>
          <trusted-key id="2db4f1ef0fa761ecc4ea935c86fdc7e2a11262cb">
             <trusting group="commons-codec"/>
             <trusting group="commons-io"/>
             <trusting group="org.apache.commons"/>
             <trusting group="xml-apis"/>
          </trusted-key>
-         <trusted-key id="2e2010f8a7ff4a41" group="org.apache"/>
          <trusted-key id="2e3a1affe42b5f53af19f780bcf4173966770193" group="org.jetbrains"/>
          <trusted-key id="2e92113263fc31c74ccbaab20e91c2de43b72bb1" group="org.ec4j.core"/>
-         <trusted-key id="2f566d4221d3ec52" group="com.ryanharter.auto.value"/>
          <trusted-key id="3051d45031e13516a6e8faff280d66a55f5316c5" group="org.bitbucket.b_c"/>
-         <trusted-key id="30e6f80434a72a7f">
-            <trusting group="org.apache.maven"/>
-            <trusting group="org.apache.maven.wagon"/>
-         </trusted-key>
          <trusted-key id="314fe82e5a4c5377bca2edec5208812e1e4a6db0" group="com.gradle"/>
          <trusted-key id="31bae2e51d95e0f8ad9b7bcc40a3c4432bd7308c" group="com.googlecode.juniversalchardet"/>
-         <trusted-key id="31fae244a81d64507b47182e1b2718089ce964b8" group="com.thoughtworks.qdox" name="qdox"/>
+         <trusted-key id="31fae244a81d64507b47182e1b2718089ce964b8">
+            <trusting group="com.thoughtworks.qdox"/>
+            <trusting group="com.thoughtworks.qdox" name="qdox"/>
+         </trusted-key>
          <trusted-key id="3288b8be8512d6c0ca185268c51e6cbc7ff46f0b">
             <trusting group="com.google.auto"/>
             <trusting group="com.google.auto.service"/>
@@ -142,27 +152,16 @@
          <trusted-key id="32b92f2ff75fdf37dc811c3c2f566d4221d3ec52" group="com.ryanharter.auto.value"/>
          <trusted-key id="33fd4bfd33554634053d73c0c2148900bcd3c2af" group="org.jetbrains.trove4j" name="trove4j"/>
          <trusted-key id="34441e504a937f43eb0daef96a65176a0fb1cd0b" group="org.codehaus.groovy"/>
-         <trusted-key id="353a436e043e3145" group="com.google.code.findbugs"/>
          <trusted-key id="3872ed7d5904493d23d78fa2c4c8cb73b1435348" group="com.android.tools.build"/>
-         <trusted-key id="3ad93c3c677a106e" group="io.perfmark"/>
-         <trusted-key id="3c0a8f4744f37328" group="com.github.ben-manes.caffeine"/>
-         <trusted-key id="3c27d97b0c83a85c" group="com.google.errorprone"/>
          <trusted-key id="3d11126ea77e4e07fbabb38614a84c976d265b25" group="com.google.protobuf"/>
          <trusted-key id="3dbc5d7dc2fb8dd68aa429bd353a436e043e3145" group="com.google.code.findbugs"/>
          <trusted-key id="3eb3846b3dc004c13883753ceef9ecc7d5d90518" group="com.google.dagger"/>
-         <trusted-key id="3f36885c24df4b75" group="org.mozilla"/>
-         <trusted-key id="3faad2cd5ecbb314" group="org.apache.commons"/>
-         <trusted-key id="41321490758aad6f" group="org.codehaus.groovy"/>
          <trusted-key id="41a1a08c62fca78b79d3081164a16faaec16a4be" group="org.apache.commons" name="commons-math3"/>
          <trusted-key id="41cd49b4ef5876f9e9f691dabac30622339994c4">
             <trusting group="com.google.testing.compile"/>
             <trusting group="com.google.truth"/>
          </trusted-key>
-         <trusted-key id="42575e0ccd6ba16a" group="org.xerial"/>
-         <trusted-key id="429c8816dea04cdb" group="org.xerial"/>
-         <trusted-key id="438e9634a2319637" group="co.nstant.in"/>
-         <trusted-key id="44ce7bf2825ea2cd" group="com.ibm.icu"/>
-         <trusted-key id="461a804f2609fd89" group="com.github.shyiko.klob"/>
+         <trusted-key id="44fbdbbc1a00fe414f1c1873586654072ead6677" group="org.sonatype.oss"/>
          <trusted-key id="47504b76cf89c15c0512d9afe16ab52d79fd224f">
             <trusting group="com.google.api"/>
             <trusting group="com.google.api-client"/>
@@ -173,24 +172,18 @@
             <trusting group="com.google.http-client"/>
             <trusting group="com.google.oauth-client"/>
          </trusted-key>
-         <trusted-key id="47586a1b75ef0de5" group="com.squareup.wire"/>
          <trusted-key id="475f3b8e59e6e63aa78067482c7b12f2a511e325">
             <trusting group="ch.qos.logback"/>
             <trusting group="org.slf4j"/>
          </trusted-key>
-         <trusted-key id="476634a4694e716a" group="com.googlecode.java-diff-utils"/>
          <trusted-key id="4791825bdea86eb9286a2ace88bb19a33a18445f" group="net.ltgt.gradle.incap"/>
          <trusted-key id="47bf592261cd1a8a69b703b4e0cb7823cfd00fbf">
+            <trusting group="com.jakewharton.android.repackaged"/>
             <trusting group="com.jakewharton.dex"/>
             <trusting group="com.squareup.retrofit2"/>
             <trusting group="^com[.]jakewharton($|([.].*))" regex="true"/>
          </trusted-key>
-         <trusted-key id="47dcfc2a59f59b5b" group="io.outfoxx"/>
          <trusted-key id="47eb6836245d2d40e89dfb4136d4e9618f3adab5" group="io.github.microutils" name="kotlin-logging-jvm"/>
-         <trusted-key id="4896f7312a5ace4d">
-            <trusting group="com.google.gradle"/>
-            <trusting group="com.google.protobuf"/>
-         </trusted-key>
          <trusted-key id="4bf79b8259007b566d2fce82296cd27f60eed12c" group="com.google.crypto.tink"/>
          <trusted-key id="4daded739cdf2cd0e48e0ec44044edf1bb73efea" group="jaxen" name="jaxen"/>
          <trusted-key id="4db1a49729b053caf015cee9a6adfc93ef34893e" group="org.hamcrest"/>
@@ -203,20 +196,20 @@
          <trusted-key id="4f8fec6785f611d9a712ea2734918b7d3969d2f5" group="com.google.dagger"/>
          <trusted-key id="517b94f8d0a46317a28d8ab30da8a5ec02d11ead" group="net.sf.jopt-simple"/>
          <trusted-key id="51b52dc5dd452f92be342cc2858fc4c4f43856a3" group="xerces"/>
-         <trusted-key id="5208812e1e4a6db0" group="com.gradle"/>
-         <trusted-key id="55c7e5e701832382" group="org.snakeyaml"/>
-         <trusted-key id="56b505dc8a29c69138a430b9429c8816dea04cdb" group="org.xerial" name="sqlite-jdbc"/>
+         <trusted-key id="55e770230e69cc6de143fb5b62c82e50836eb3ee" group="com.github.gundy"/>
+         <trusted-key id="56b505dc8a29c69138a430b9429c8816dea04cdb">
+            <trusting group="org.xerial"/>
+            <trusting group="org.xerial" name="sqlite-jdbc"/>
+         </trusted-key>
          <trusted-key id="5719e50eac5a4b1dd390b72c2a742740e08e7f8d" group="org.antlr"/>
-         <trusted-key id="571a5291e827e1c7" group="net.java"/>
          <trusted-key id="5767f9cde920750621875079a40e24b5b408dbd5" group="org.robolectric"/>
-         <trusted-key id="586654072ead6677" group="org.sonatype.oss"/>
          <trusted-key id="5897253bea3046aeea95a067e93671c7272b7b3f" group="org.jdom"/>
+         <trusted-key id="58e79b6abc762159dc0b1591164bd2247b936711" group="junit"/>
          <trusted-key id="5ce325996a35213326ae2c68912d2c0eccda55c0" group="com.google.errorprone"/>
-         <trusted-key id="5d67bffcba1f9a39" group="com.google.gradle"/>
-         <trusted-key id="5dceb296690bd5101756f2441f8cf885d537a431" group="com.nhaarman.mockitokotlin2" name="mockito-kotlin"/>
-         <trusted-key id="5e1f79a7c298661e" group="com.google.auto.value"/>
-         <trusted-key id="5ed22f661bbf0acc" group="com.almworks.sqlite4java"/>
-         <trusted-key id="5f7786df73e61f56" group="com.google.devtools.ksp"/>
+         <trusted-key id="5dceb296690bd5101756f2441f8cf885d537a431">
+            <trusting group="com.nhaarman.mockitokotlin2"/>
+            <trusting group="com.nhaarman.mockitokotlin2" name="mockito-kotlin"/>
+         </trusted-key>
          <trusted-key id="5fa41c402006eac55d72aafd99ce9d9f22dc5c99" group="org.json"/>
          <trusted-key id="600ea202b1ec682f4a788e5aac7a514bc9f9bb70" group="io.opencensus"/>
          <trusted-key id="6214760097dc5cfad0175ac2c9fbaa83a8753994">
@@ -228,15 +221,16 @@
             <trusting group="com.fasterxml.woodstox"/>
             <trusting group="org.codehaus.woodstox"/>
          </trusted-key>
-         <trusted-key id="628462a5eaba59d57e99ae5a840b2bf6da8ed8c8" group="com.google.android.apps.common.testing.accessibility.framework" name="accessibility-test-framework"/>
-         <trusted-key id="62ba9c275d14234e">
-            <trusting group="com.squareup.curtains"/>
-            <trusting group="com.squareup.leakcanary"/>
+         <trusted-key id="628462a5eaba59d57e99ae5a840b2bf6da8ed8c8">
+            <trusting group="com.google.android.apps.common.testing.accessibility.framework"/>
+            <trusting group="com.google.android.apps.common.testing.accessibility.framework" name="accessibility-test-framework"/>
          </trusted-key>
-         <trusted-key id="62c82e50836eb3ee" group="com.github.gundy"/>
          <trusted-key id="635ee627345f3c1dd422b2e207d3516820bcf6b1" group="com.github.ben-manes.caffeine"/>
-         <trusted-key id="6525fd70cc303655" group="org.codehaus.mojo"/>
-         <trusted-key id="666a4692ce11b7b3f4eb7b3410066a9707090cf9" group="org.javassist" name="javassist"/>
+         <trusted-key id="64b9b09f164aa0bf88742eb61188b69f6d6259ca" group="com.google.accompanist"/>
+         <trusted-key id="666a4692ce11b7b3f4eb7b3410066a9707090cf9">
+            <trusting group="org.javassist"/>
+            <trusting group="org.javassist" name="javassist"/>
+         </trusted-key>
          <trusted-key id="682f765eea718d250bbdb2f1685c46769dbb5e5d" group="com.squareup" name="kotlinpoet"/>
          <trusted-key id="694621a7227d8d5289699830abe9f3126bb741c1">
             <trusting group="com.google.guava"/>
@@ -244,13 +238,11 @@
             <trusting group="^com[.]google($|([.].*))" regex="true"/>
          </trusted-key>
          <trusted-key id="696b6199a2a9d8c29ce78cc0d041cad2e452550f" group="com.google.protobuf"/>
-         <trusted-key id="6a65176a0fb1cd0b" group="org.codehaus.groovy"/>
-         <trusted-key id="6ccc36cc6c69fc17" group="com.google"/>
+         <trusted-key id="6bdaca2c0493cca133b372d09c4f7e9d98b1cc53" group="org.apache"/>
          <trusted-key id="6dd3b8c64ef75253beb2c53ad908a43fb7ec07ac">
             <trusting group="com.sun.activation"/>
             <trusting group="jakarta.activation"/>
          </trusted-key>
-         <trusted-key id="6eff5ef5523052d4" group="com.github.tschuchortdev"/>
          <trusted-key id="6f538074ccebf35f28af9b066a0975f8b1127b83">
             <trusting group="org.jetbrains.kotlin"/>
             <trusting group="org.jetbrains.kotlin.jvm"/>
@@ -259,41 +251,52 @@
          <trusted-key id="6f656b7f6bfb238d38acf81f3c27d97b0c83a85c" group="com.google.errorprone"/>
          <trusted-key id="6f7e5acbcd02db60dfd232e45e1f79a7c298661e">
             <trusting group="com.google.auto"/>
+            <trusting group="com.google.auto.value"/>
             <trusting group="com.google.auto.value" name="auto-value"/>
          </trusted-key>
          <trusted-key id="70731c2ffb496dc4e8105aa3604f437c1682dde5" group="app.cash.paparazzi"/>
          <trusted-key id="70cd19bfd9f6c330027d6f260315bfb7970a144f">
+            <trusting group="com.sun.istack"/>
             <trusting group="com.sun.xml.bind"/>
+            <trusting group="com.sun.xml.bind.mvn"/>
+            <trusting group="com.sun.xml.fastinfoset"/>
             <trusting group="javax.xml.bind"/>
             <trusting group="org.glassfish"/>
             <trusting group="org.glassfish.jaxb"/>
             <trusting group="org.jvnet.staxex"/>
             <trusting group="^com[.]sun($|([.].*))" regex="true"/>
          </trusted-key>
-         <trusted-key id="72385ff0af338d52" group="org.threeten"/>
+         <trusted-key id="720746177725a89207a7075bfd5dea07fcb690a8" group="org.codehaus.mojo"/>
+         <trusted-key id="748f15b2cf9ba8f024155e6ed7c92b70fa1c814d" group="org.apache.logging.log4j"/>
          <trusted-key id="7615ad56144df2376f49d98b1669c4bb543e0445" group="com.google.errorprone"/>
          <trusted-key id="7616eb882daf57a11477aaf559a252fb1199d873" group="com.google.code.findbugs"/>
          <trusted-key id="78ab011fa6e5907950ea3e2747dcfc2a59f59b5b" group="io.outfoxx"/>
-         <trusted-key id="79156e0351af8604de9b186b09a79e1e15a04694" group="org.vafer" name="jdependency"/>
-         <trusted-key id="7999befba1039e8b" group="net.bytebuddy"/>
-         <trusted-key id="7a8860944fad5f62" group="org.apache.commons"/>
+         <trusted-key id="79156e0351af8604de9b186b09a79e1e15a04694">
+            <trusting group="org.vafer"/>
+            <trusting group="org.vafer" name="jdependency"/>
+         </trusted-key>
          <trusted-key id="7c669810892cbd3148fa92995b05ccde140c2876" group="org.eclipse.jgit"/>
-         <trusted-key id="7c7d8456294423ba" group="org.objenesis"/>
          <trusted-key id="7cb548acfe3d47e92afa566dc29b11246382a4d7" group="com.charleskorn.kaml"/>
-         <trusted-key id="7cd52b5a8295137c88fb5748dddafa7674e54418" group="org.testng" name="testng"/>
+         <trusted-key id="7cd52b5a8295137c88fb5748dddafa7674e54418">
+            <trusting group="org.testng"/>
+            <trusting group="org.testng" name="testng"/>
+         </trusted-key>
          <trusted-key id="7e22d50a7ebd9d2cd269b2d4056aca74d46000bf" group="io.netty"/>
          <trusted-key id="7f36e793ae3252e5d9e9b98fee9e7dc9d92fc896" group="com.google.errorprone"/>
          <trusted-key id="7faa0f2206de228f0db01ad741321490758aad6f" group="org.codehaus.groovy"/>
-         <trusted-key id="80f6d6b0d90c6747753344cab5a9e81b565e89e0" group="org.tomlj" name="tomlj"/>
+         <trusted-key id="808d78b17a5a2d7c3668e31fbffc9b54721244ad" group="org.apache.commons"/>
+         <trusted-key id="80f6d6b0d90c6747753344cab5a9e81b565e89e0">
+            <trusting group="org.tomlj"/>
+            <trusting group="org.tomlj" name="tomlj"/>
+         </trusted-key>
          <trusted-key id="8254180bfc943b816e0b5e2e5e2f2b3d474efe6b" group="it.unimi.dsi"/>
-         <trusted-key id="82b5574242c20d6f" group="org.antlr"/>
          <trusted-key id="82f833963889d7ed06f1e4dc6525fd70cc303655" group="org.codehaus.mojo"/>
          <trusted-key id="835a685c8c6f49c54980e5caf406f31bc1468eba" group="org.jcodec"/>
-         <trusted-key id="840b2bf6da8ed8c8" group="com.google.android.apps.common.testing.accessibility.framework"/>
          <trusted-key id="842afb86375d805422835bfd82b5574242c20d6f" group="org.antlr"/>
-         <trusted-key id="8569c95cadc508b09fe90f3002216ed811210daa" group="io.github.detekt.sarif4k" name="sarif4k"/>
-         <trusted-key id="85911f425ec61b51" group="org.junit"/>
-         <trusted-key id="8614d6ab265b4c63" group="org.apache.ant"/>
+         <trusted-key id="8569c95cadc508b09fe90f3002216ed811210daa">
+            <trusting group="io.github.detekt.sarif4k"/>
+            <trusting group="io.github.detekt.sarif4k" name="sarif4k"/>
+         </trusted-key>
          <trusted-key id="8756c4f765c9ac3cb6b85d62379ce192d401ab61">
             <trusting group="com.github.ajalt"/>
             <trusting group="com.github.javaparser"/>
@@ -302,7 +305,7 @@
             <trusting group="^org[.]jetbrains($|([.].*))" regex="true"/>
          </trusted-key>
          <trusted-key id="8858d45be9b276802318155b96fb9db219f3338d" group="kr.motd.maven"/>
-         <trusted-key id="88bb19a33a18445f" group="net.ltgt.gradle.incap"/>
+         <trusted-key id="88cd390855df292e2172da9742575e0ccd6ba16a " group="org.xerial"/>
          <trusted-key id="8a10792983023d5d14c93b488d7f1bec1e2ecae7">
             <trusting group="com.fasterxml"/>
             <trusting group="com.fasterxml.jackson"/>
@@ -312,116 +315,133 @@
          <trusted-key id="8df3b0aa23ed78be5233f6c2dea3d207428ef16d" group="com.linkedin.dexmaker"/>
          <trusted-key id="8e3a02905a1ae67e7b0f9acd3967d4eda591b991" group="org.jetbrains.kotlinx" name="kotlinx-html-jvm"/>
          <trusted-key id="8f9a3c6d105b9f57844a721d79e193516be7998f" group="org.dom4j" name="dom4j"/>
-         <trusted-key id="908366594e746bf3c449f5622be5d98f751f4136" group="org.pcollections" name="pcollections"/>
+         <trusted-key id="908366594e746bf3c449f5622be5d98f751f4136">
+            <trusting group="org.pcollections"/>
+            <trusting group="org.pcollections" name="pcollections"/>
+         </trusted-key>
          <trusted-key id="90ee19787a7bcf6fd37a1e9180c08b1c29100955">
             <trusting group="com.jakewharton.android.repackaged"/>
             <trusting group="com.squareup" name="javawriter"/>
          </trusted-key>
          <trusted-key id="95115197c5227c0887299d000f9fe62f88e938d8" group="com.google.dagger"/>
-         <trusted-key id="95c15058a5eda4f1" group="com.google.protobuf"/>
-         <trusted-key id="96fb9db219f3338d" group="kr.motd.maven"/>
-         <trusted-key id="971b04f56669b805" group="com.google.jsilver"/>
          <trusted-key id="98465301a4939c0279f2e847d89d05374952262b" group="org.jetbrains.dokka"/>
-         <trusted-key id="995efbf4a3d20beb">
-            <trusting group="com.pinterest"/>
-            <trusting group="com.pinterest.ktlint"/>
+         <trusted-key id="998af0e2b935996f5cebd56b9b1fda9f3c062231">
+            <trusting group="org.apache"/>
+            <trusting group="org.apache.maven"/>
          </trusted-key>
-         <trusted-key id="998af0e2b935996f5cebd56b9b1fda9f3c062231" group="org.apache.maven"/>
-         <trusted-key id="9a259c7ee636c5ed" group="com.google.errorprone"/>
-         <trusted-key id="9b1fda9f3c062231" group="org.apache"/>
          <trusted-key id="9bbc1c3e408ca09cf76d1a029c538d5a79281639" group="com.squareup.sqldelight"/>
-         <trusted-key id="9c4f7e9d98b1cc53" group="org.apache"/>
-         <trusted-key id="9c538d5a79281639" group="com.squareup.sqldelight"/>
          <trusted-key id="9d0a56aaa0d60e0c0c7dccc0b4c70893b62babe8">
             <trusting group="org.apache.logging"/>
             <trusting group="org.apache.logging.log4j"/>
          </trusted-key>
-         <trusted-key id="9daadc1c9fcc82d0" group="commons-cli"/>
          <trusted-key id="9e84765a7aa3e3d3d5598a408e3f0de7ae354651">
             <trusting group="com.google.code.gson"/>
             <trusting group="com.squareup"/>
             <trusting group="org.reactivestreams"/>
          </trusted-key>
-         <trusted-key id="9ffed7a118d45a44e4a1e47130e6f80434a72a7f" group="^org[.]apache[.]maven($|([.].*))" regex="true"/>
+         <trusted-key id="9ffed7a118d45a44e4a1e47130e6f80434a72a7f">
+            <trusting group="org.apache.maven"/>
+            <trusting group="org.apache.maven.wagon"/>
+            <trusting group="^org[.]apache[.]maven($|([.].*))" regex="true"/>
+         </trusted-key>
          <trusted-key id="a0e7010544c02bd4c072b1803e3d777c909a447c" group="io.opencensus"/>
-         <trusted-key id="a1b4460d8ba7b9af" group="org.mockito"/>
          <trusted-key id="a33a0b49a4c1ab590b0a4ddc1364c5e2df3e99c5" group="org.reactivestreams"/>
-         <trusted-key id="a40e24b5b408dbd5" group="org.robolectric"/>
          <trusted-key id="a413f67d71beec23add0ce0acb43338e060cf9fa">
             <trusting group="com.google.code.findbugs" name="jsr305"/>
             <trusting group="org.jacoco"/>
          </trusted-key>
-         <trusted-key id="a4fd709cc4b0515f2e6af04e218fa0f6a941a037" group="com.github.kevinstern" name="software-and-algorithms"/>
-         <trusted-key id="a5b2dde7843e7ca3e8caabd02383163bc40844fd" group="org.reactivestreams" name="reactive-streams"/>
+         <trusted-key id="a4fd709cc4b0515f2e6af04e218fa0f6a941a037">
+            <trusting group="com.github.kevinstern"/>
+            <trusting group="com.github.kevinstern" name="software-and-algorithms"/>
+         </trusted-key>
+         <trusted-key id="a5b2dde7843e7ca3e8caabd02383163bc40844fd">
+            <trusting group="org.reactivestreams"/>
+            <trusting group="org.reactivestreams" name="reactive-streams"/>
+         </trusted-key>
          <trusted-key id="a5bd02b93e7a40482eb1d66a5f69ad087600b22c" group="org.ow2.asm"/>
-         <trusted-key id="a6adfc93ef34893e" group="org.hamcrest"/>
          <trusted-key id="a6d6c97108b8585f91b158748671a8df71296252" group="^com[.]squareup($|([.].*))" regex="true"/>
-         <trusted-key id="a730529ca355a63e" group="org.ccil.cowan.tagsoup"/>
-         <trusted-key id="a7764f502a938c99" group="com.google.protobuf"/>
          <trusted-key id="a7892505cf1a58076453e52d7999befba1039e8b" group="net.bytebuddy"/>
          <trusted-key id="aa417737bd805456db3cbdde6601e5c08dccbb96" group="info.picocli" name="picocli"/>
          <trusted-key id="aa70c7c433d501636392ec02153e7a3c2b4e5118" group="org.eclipse.ee4j"/>
-         <trusted-key id="ac5ec74981f9cda6">
-            <trusting group="com.beust"/>
-            <trusting group="org.testng"/>
+         <trusted-key id="adbc987d1a7b91db6b0aaa81995efbf4a3d20beb">
+            <trusting group="com.pinterest"/>
+            <trusting group="com.pinterest.ktlint"/>
+            <trusting group="^com[.]pinterest($|([.].*))" regex="true"/>
          </trusted-key>
-         <trusted-key id="adbc987d1a7b91db6b0aaa81995efbf4a3d20beb" group="^com[.]pinterest($|([.].*))" regex="true"/>
-         <trusted-key id="ae2b18e836c5f30687f37efdcc6346f2ce3872d9" group="com.google.protobuf" name="protobuf-java"/>
+         <trusted-key id="ae2b18e836c5f30687f37efdcc6346f2ce3872d9">
+            <trusting group="com.google.protobuf"/>
+            <trusting group="com.google.protobuf" name="protobuf-java"/>
+         </trusted-key>
+         <trusted-key id="ae9e53fc28ff2ab1012273d0bf1518e0160788a2" group="org.apache" name="apache"/>
          <trusted-key id="afa2b1823fc021bfd08c211fd5f4c07a434ab3da" group="com.squareup"/>
          <trusted-key id="afcc4c7594d09e2182c60e0f7a01b0f236e5430f" group="com.google.code.gson"/>
          <trusted-key id="b02335aa54ccf21e52bbf9abd9c565aa72ba2fdd" group="io.grpc"/>
-         <trusted-key id="b252e5789636134a311e4463971b04f56669b805" group="com.google.jsilver" name="jsilver"/>
+         <trusted-key id="b252e5789636134a311e4463971b04f56669b805">
+            <trusting group="com.google.jsilver"/>
+            <trusting group="com.google.jsilver" name="jsilver"/>
+         </trusted-key>
          <trusted-key id="b41089a2da79b0fa5810252872385ff0af338d52">
+            <trusting group="org.threeten"/>
             <trusting group="org.threeten" name="threeten-extra"/>
             <trusting group="org.threeten" name="threetenbp"/>
          </trusted-key>
-         <trusted-key id="b47034c19c9b1f3dc3702f8d476634a4694e716a" group="com.googlecode.java-diff-utils" name="diffutils"/>
-         <trusted-key id="b4c70893b62babe8" group="org.apache.logging.log4j"/>
-         <trusted-key id="b57bd58ef6d0a713" group="com.google.protobuf"/>
-         <trusted-key id="b5a9e81b565e89e0" group="org.tomlj"/>
-         <trusted-key id="b6e73d84ea4fcc47166087253faad2cd5ecbb314" group="org.apache.commons" name="commons-parent"/>
-         <trusted-key id="b7c3b43d18eaa8b7" group="org.codehaus.mojo"/>
+         <trusted-key id="b46dc71e03feeb7f89d1f2491f7a8f87b9d8f501" group="org.jetbrains.trove4j"/>
+         <trusted-key id="b47034c19c9b1f3dc3702f8d476634a4694e716a">
+            <trusting group="com.googlecode.java-diff-utils"/>
+            <trusting group="com.googlecode.java-diff-utils" name="diffutils"/>
+         </trusted-key>
+         <trusted-key id="b4ac8cdc141af0ae468d16921da784ccb5c46dd5" group="net.bytebuddy"/>
+         <trusted-key id="b6e73d84ea4fcc47166087253faad2cd5ecbb314">
+            <trusting group="org.apache.commons"/>
+            <trusting group="org.apache.commons" name="commons-parent"/>
+         </trusted-key>
          <trusted-key id="b801e2f8ef035068ec1139cc29579f18fa8fd93b" group="com.google.j2objc"/>
-         <trusted-key id="bac30622339994c4" group="com.google.truth"/>
+         <trusted-key id="b9cca13c59f21c6ce841a8d1a4b1a03fb9c2ce23" group="com.squareup.leakcanary"/>
+         <trusted-key id="ba926f64ca647b6d853a38672e2010f8a7ff4a41" group="org.apache"/>
          <trusted-key id="bae5c184e3b70cb15617700598fe03a974ce0a0b" group="org.jetbrains.kotlin"/>
-         <trusted-key id="bb2914c1fa0811c3" group="net.bytebuddy"/>
-         <trusted-key id="bc87a3fd0a54480f0badbebd21939ff0ca2a6567" group="commons-codec" name="commons-codec"/>
+         <trusted-key id="bc87a3fd0a54480f0badbebd21939ff0ca2a6567">
+            <trusting group="commons-codec"/>
+            <trusting group="commons-codec" name="commons-codec"/>
+         </trusted-key>
          <trusted-key id="bcc135fc7ed8214f823d73e97fe9900f412d622e" group="com.google.flatbuffers"/>
          <trusted-key id="bdb5fa4fe719d787fb3d3197f6d4a1d411e9d1ae" group="com.google.guava"/>
-         <trusted-key id="be096e29edb8d141" group="net.sf.proguard"/>
          <trusted-key id="be685132afd2740d9095f9040cc0b712fee75827" group="org.assertj"/>
-         <trusted-key id="beabcfbee059e4e5" group="com.github.siom79.japicmp"/>
-         <trusted-key id="bede11eaf1164480" group="org.hamcrest"/>
-         <trusted-key id="bf1518e0160788a2" group="org.apache" name="apache"/>
-         <trusted-key id="bf984b4145ea13f7" group="com.squareup" name="javapoet"/>
-         <trusted-key id="bffc9b54721244ad" group="org.apache.commons"/>
-         <trusted-key id="c1b12a5d99c0729d" group="org.jetbrains"/>
-         <trusted-key id="c2148900bcd3c2af" group="org.jetbrains.trove4j"/>
-         <trusted-key id="c29b11246382a4d7" group="com.charleskorn.kaml"/>
-         <trusted-key id="c51e6cbc7ff46f0b" group="com.google.auto.service"/>
          <trusted-key id="c5aa57f4a38eba7b7f9156ddab2da4527f6ffc0b">
             <trusting group="com.squareup" name="kotlinpoet"/>
             <trusting group="com.squareup" name="kotlinpoet-javapoet"/>
          </trusted-key>
-         <trusted-key id="c6f7d1c804c821f49af3bfc13ad93c3c677a106e" group="io.perfmark" name="perfmark-api"/>
-         <trusted-key id="c70b844f002f21f6d2b9c87522e44ac0622b91c3" group="com.beust" name="jcommander"/>
+         <trusted-key id="c6f7d1c804c821f49af3bfc13ad93c3c677a106e">
+            <trusting group="io.perfmark"/>
+            <trusting group="io.perfmark" name="perfmark-api"/>
+         </trusted-key>
+         <trusted-key id="c70b844f002f21f6d2b9c87522e44ac0622b91c3">
+            <trusting group="com.beust"/>
+            <trusting group="com.beust" name="jcommander"/>
+         </trusted-key>
          <trusted-key id="c7be5bcc9fec15518cfda882b0f3710fa64900e7">
             <trusting group="com.google.auto"/>
             <trusting group="com.google.auto.service"/>
             <trusting group="com.google.auto.value"/>
             <trusting group="com.google.code.gson"/>
          </trusted-key>
-         <trusted-key id="c7ca19b7b620d787" group="org.apache.maven"/>
-         <trusted-key id="c8741082ff1b0ee96bcabeec10ae8966a146e8be" group="com.google.crypto.tink" name="tink-android"/>
-         <trusted-key id="c888b9955815ea83b48531784896f7312a5ace4d" group="^com[.]google($|([.].*))" regex="true"/>
-         <trusted-key id="c92c5fec70161c62" group="org.apache"/>
+         <trusted-key id="c8741082ff1b0ee96bcabeec10ae8966a146e8be">
+            <trusting group="com.google.crypto.tink"/>
+            <trusting group="com.google.crypto.tink" name="tink-android"/>
+         </trusted-key>
+         <trusted-key id="c888b9955815ea83b48531784896f7312a5ace4d">
+            <trusting group="com.google.gradle"/>
+            <trusting group="com.google.protobuf"/>
+            <trusting group="^com[.]google($|([.].*))" regex="true"/>
+         </trusted-key>
          <trusted-key id="c9a503282182ec4ecdb914ea102e05d8da6c286d" group="javax.xml.bind" name="jaxb-api"/>
          <trusted-key id="cacfbd4755a2fc78709bdd92be096e29edb8d141" group="net.sf.proguard"/>
-         <trusted-key id="cb3190ca7842439e57f3712e44ce7bf2825ea2cd" group="com.ibm.icu" name="icu4j"/>
-         <trusted-key id="cb43338e060cf9fa" group="org.jacoco"/>
+         <trusted-key id="cb3190ca7842439e57f3712e44ce7bf2825ea2cd">
+            <trusting group="com.ibm.icu"/>
+            <trusting group="com.ibm.icu" name="icu4j"/>
+         </trusted-key>
          <trusted-key id="cc4483cd6a3eb2939b948667a1b4460d8ba7b9af" group="org.mockito"/>
-         <trusted-key id="cc6346f2ce3872d9" group="com.google.protobuf"/>
          <trusted-key id="cd5464315f0b98c77e6e8ecd9daadc1c9fcc82d0">
+            <trusting group="commons-cli"/>
             <trusting group="commons-cli" name="commons-cli"/>
             <trusting group="org.apache.commons"/>
          </trusted-key>
@@ -429,31 +449,38 @@
             <trusting group="org.apache.ant"/>
             <trusting group="org.apache.commons"/>
          </trusted-key>
-         <trusted-key id="cf9f3090ce4cb752" group="org.abego.treelayout"/>
-         <trusted-key id="cfae163b64ac9189" group="org.jetbrains.skiko"/>
-         <trusted-key id="d041cad2e452550f" group="com.google.protobuf"/>
          <trusted-key id="d196a5e3e70732eeb2e5007f1861c322c56014b2" group="commons-lang"/>
+         <trusted-key id="d433f9c895710db8ab087fa6b7c3b43d18eaa8b7" group="org.codehaus.mojo"/>
          <trusted-key id="d477d51812e692011db11e66a6ea2e2bf22e0543" group="io.github.java-diff-utils"/>
          <trusted-key id="d4c89ea4aaf455fd88b22087efe8086f9e93774e" group="junit"/>
-         <trusted-key id="d4da5eab3cd7e958" group="com.google.devtools.ksp"/>
-         <trusted-key id="d4fb0b7b5e8c18c993a8a386eb9d04a9a679fe18" group="com.uber.nullaway" name="nullaway"/>
+         <trusted-key id="d4fb0b7b5e8c18c993a8a386eb9d04a9a679fe18">
+            <trusting group="com.uber.nullaway"/>
+            <trusting group="com.uber.nullaway" name="nullaway"/>
+         </trusted-key>
          <trusted-key id="d54a395b5cf3f86eb45f6e426b1b008864323b92" group="org.antlr"/>
-         <trusted-key id="d5f4c07a434ab3da" group="com.squareup"/>
-         <trusted-key id="d6f1bc78607808ec8e9f69437a8860944fad5f62" group="org.apache.commons" name="commons-parent"/>
-         <trusted-key id="d73c68ee4152c255" group="com.google.dagger"/>
+         <trusted-key id="d6f1bc78607808ec8e9f69437a8860944fad5f62">
+            <trusting group="org.apache.commons"/>
+            <trusting group="org.apache.commons" name="commons-parent"/>
+         </trusted-key>
          <trusted-key id="d75e25b78ebb19e47c0a99bca7764f502a938c99" group="com.google.protobuf"/>
-         <trusted-key id="d790f72ea8fd39551012b62dcf9f3090ce4cb752" group="org.abego.treelayout" name="org.abego.treelayout.core"/>
-         <trusted-key id="da7a1bb85b19e4fb05073431205c8673dc742c7c" group="org.apache.maven"/>
+         <trusted-key id="d790f72ea8fd39551012b62dcf9f3090ce4cb752">
+            <trusting group="org.abego.treelayout"/>
+            <trusting group="org.abego.treelayout" name="org.abego.treelayout.core"/>
+         </trusted-key>
+         <trusted-key id="da7a1bb85b19e4fb05073431205c8673dc742c7c">
+            <trusting group="org.apache"/>
+            <trusting group="org.apache.maven"/>
+         </trusted-key>
          <trusted-key id="db0597e3144342256bc81e3ec727d053c4481cf5" group="org.tensorflow"/>
          <trusted-key id="dbd744ace7ade6aa50dd591f66b50994442d2d40">
             <trusting group="com.squareup.okio"/>
             <trusting group="com.squareup.wire"/>
          </trusted-key>
-         <trusted-key id="dddafa7674e54418" group="org.testng"/>
-         <trusted-key id="e0130a3ed5a2079e" group="org.webjars"/>
-         <trusted-key id="e0cb7823cfd00fbf" group="com.jakewharton.android.repackaged"/>
+         <trusted-key id="dcba03381ef6c89096acd985ac5ec74981f9cda6">
+            <trusting group="com.beust"/>
+            <trusting group="org.testng"/>
+         </trusted-key>
          <trusted-key id="e0d98c5fd55a8af232290e58dee12b9896f97e34" group="org.pcollections"/>
-         <trusted-key id="e16ab52d79fd224f" group="com.google.api.grpc"/>
          <trusted-key id="e3a9f95079e84ce201f7cf60bede11eaf1164480" group="org.hamcrest"/>
          <trusted-key id="e62231331bca7e1f292c9b88c1b12a5d99c0729d" group="org.jetbrains"/>
          <trusted-key id="e77417ac194160a3fabd04969a259c7ee636c5ed">
@@ -461,20 +488,24 @@
             <trusting group="com.google.googlejavaformat"/>
          </trusted-key>
          <trusted-key id="e7dc75fc24fb3c8dfe8086ad3d5839a2262cbbfb" group="org.jetbrains.kotlinx"/>
+         <trusted-key id="e82d2eaf2e83830ce1f7f6be571a5291e827e1c7" group="net.java"/>
          <trusted-key id="e85aed155021af8a6c6b7a4a7c7d8456294423ba" group="org.objenesis"/>
          <trusted-key id="e8bf633b386b7ddcf1e1a9b3358a4abae72947c2" group="com.google.testparameterinjector"/>
-         <trusted-key id="ea0b70b5050192c98cfa7e4f3f36885c24df4b75" group="org.mozilla" name="rhino"/>
-         <trusted-key id="ea23db1360d9029481e7f2efecdfea3cb4493b94" group="jline" name="jline"/>
-         <trusted-key id="eaa526b91dd83ba3e1b9636fa730529ca355a63e" group="org.ccil.cowan.tagsoup" name="tagsoup"/>
-         <trusted-key id="eb380dc13c39f675" group="com.intellij"/>
-         <trusted-key id="eb9d04a9a679fe18" group="com.uber.nullaway"/>
-         <trusted-key id="ecdfea3cb4493b94" group="jline"/>
+         <trusted-key id="ea0b70b5050192c98cfa7e4f3f36885c24df4b75">
+            <trusting group="org.mozilla"/>
+            <trusting group="org.mozilla" name="rhino"/>
+         </trusted-key>
+         <trusted-key id="ea23db1360d9029481e7f2efecdfea3cb4493b94">
+            <trusting group="jline"/>
+            <trusting group="jline" name="jline"/>
+         </trusted-key>
+         <trusted-key id="eaa526b91dd83ba3e1b9636fa730529ca355a63e">
+            <trusting group="org.ccil.cowan.tagsoup"/>
+            <trusting group="org.ccil.cowan.tagsoup" name="tagsoup"/>
+         </trusted-key>
+         <trusted-key id="ec86f41279f2ec8ffd2f54906ccc36cc6c69fc17" group="com.google"/>
          <trusted-key id="ee0ca873074092f806f59b65d364abaa39a47320" group="com.google.errorprone"/>
-         <trusted-key id="ee9e7dc9d92fc896" group="com.google.errorprone"/>
-         <trusted-key id="eef9ecc7d5d90518" group="com.google.dagger"/>
-         <trusted-key id="efe8086f9e93774e" group="junit"/>
          <trusted-key id="f1a51e051f527e0c8e24d54d4b1e11d5a4b91e89" group="com.google.protobuf"/>
-         <trusted-key id="f1f111af65925306" group="io.github.classgraph"/>
          <trusted-key id="f254b35617dc255d9344bcfa873a8e86b4372146">
             <trusting group="org.apache"/>
             <trusting group="org.codehaus.mojo"/>
@@ -482,19 +513,25 @@
          </trusted-key>
          <trusted-key id="f3184bcd55f4d016e30d4c9bf42e87f9665015c9" group="org.jsoup"/>
          <trusted-key id="f42b96b8648b5c4a1c43a62fbb2914c1fa0811c3" group="net.bytebuddy"/>
-         <trusted-key id="f800dd0933ecf7f7" group="com.google.guava"/>
-         <trusted-key id="fa1703b1d287caea3a60f931e0130a3ed5a2079e" group="org.webjars" name="jquery"/>
+         <trusted-key id="fa1703b1d287caea3a60f931e0130a3ed5a2079e">
+            <trusting group="org.webjars"/>
+            <trusting group="org.webjars" name="jquery"/>
+         </trusted-key>
          <trusted-key id="fa77dcfef2ee6eb2debedd2c012579464d01c06a">
+            <trusting group="org.apache"/>
             <trusting group="org.apache" name="apache"/>
             <trusting group="org.codehaus.plexus"/>
          </trusted-key>
          <trusted-key id="fa7929f83ad44c4590f6cc6815c71c0a4e0b8edd" group="net.java.dev.jna"/>
-         <trusted-key id="faabc3738b1f58da2d776fa2eb380dc13c39f675" group="com.intellij" name="annotations"/>
+         <trusted-key id="faabc3738b1f58da2d776fa2eb380dc13c39f675">
+            <trusting group="com.intellij"/>
+            <trusting group="com.intellij" name="annotations"/>
+         </trusted-key>
          <trusted-key id="fc411cd3cb7dcb0abc9801058118b3bcdb1a5000" group="jakarta.xml.bind"/>
-         <trusted-key id="fd5dea07fcb690a8" group="org.codehaus.mojo"/>
          <trusted-key id="ff460acf3266fdce8eb8fe3ba797295e9d87bdd0" group="androidx.build.gradle.gcpbuildcache" name="gcpbuildcache"/>
          <trusted-key id="ff6e2c001948c5f2f38b0cc385911f425ec61b51">
             <trusting group="junit"/>
+            <trusting group="org.junit"/>
             <trusting group="org.junit" name="junit-bom"/>
             <trusting group="org.junit.jupiter"/>
             <trusting group="org.junit.platform"/>
@@ -549,6 +586,14 @@
             <sha256 value="bc787098a208e6bdc8d93720a162bbea01df1b26394d1c1ef5ec523b1d604e8b" origin="Generated by Gradle" reason="Artifact is not signed"/>
          </artifact>
       </component>
+      <component group="com.google.android.libraries.identity.googleid" name="googleid" version="0.0.2">
+         <artifact name="googleid-0.0.2.aar">
+            <sha256 value="ae69047587928df1ff82ce71e9f2ec40a777270f04f4a6d1f66241944961b682" origin="Generated by Gradle"/>
+         </artifact>
+         <artifact name="googleid-0.0.2.pom">
+            <sha256 value="100a2c6db1ec4aab9545ead93be094c9728ecc671fba8353648d04ef405f30c8" origin="Generated by Gradle"/>
+         </artifact>
+      </component>
       <component group="com.google.android.odml" name="image" version="1.0.0-beta1">
          <artifact name="image-1.0.0-beta1.aar">
             <sha256 value="2e71aa31f83a9415277f119de67195726f07d1760e9542c111778c320e3aa1f2" origin="Generated by Gradle" reason="Artifact is not signed"/>
@@ -777,94 +822,6 @@
             <pgp value="720746177725a89207a7075bfd5dea07fcb690a8"/>
          </artifact>
       </component>
-      <component group="org.jetbrains.dokka" name="all-modules-page-plugin" version="1.7.20-dev-178">
-         <artifact name="all-modules-page-plugin-1.7.20-dev-178.jar">
-            <sha256 value="968267f870e4c3a21b23fd61249a380df5b32d6eb4b295df93b9b25f0020e49f" origin="Generated manually"/>
-         </artifact>
-         <artifact name="all-modules-page-plugin-1.7.20-dev-178.module">
-            <sha256 value="c4692062327e1e4cea88e5c4ce10e9420525fe746c7b73aeb672738f7109389c" origin="Generated manually"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="android-documentation-plugin" version="1.7.20-dev-178">
-         <artifact name="android-documentation-plugin-1.7.20-dev-178.jar">
-            <sha256 value="d446f3e440984e927712e8fd894a0fcb004a1d5626a66f2e3eebf85497f7f4c9" origin="Generated manually"/>
-         </artifact>
-         <artifact name="android-documentation-plugin-1.7.20-dev-178.module">
-            <sha256 value="38745965f41d21794376b62b2c285f0feeb612e6a1eef8b32ce42bbba2330d48" origin="Generated manually"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="dokka-analysis" version="1.7.20-dev-178">
-         <artifact name="dokka-analysis-1.7.20-dev-178.jar">
-            <sha256 value="18e8e9dbf885e80de803c00744a820095511915f8eb13c6973478f37b8937f95" origin="Generated manually"/>
-         </artifact>
-         <artifact name="dokka-analysis-1.7.20-dev-178.module">
-            <sha256 value="c2238793675e470beff29a013f1ff97df3a89a53afadca94b022ff55d3d66dd7" origin="Generated manually"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="dokka-android-gradle-plugin" version="0.9.17-g014">
-         <artifact name="dokka-android-gradle-plugin-0.9.17-g014.jar">
-            <sha256 value="64b2e96fd20762351c74f08d598d49c25a490a3b685b8a09446e81d6db36fe81" origin="Generated by Gradle"/>
-         </artifact>
-         <artifact name="dokka-android-gradle-plugin-0.9.17-g014.pom">
-            <sha256 value="956ff381c6c775161a82823bb52d0aa40a8f6a37ab85059f149531f5e5efb7da" origin="Generated by Gradle"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="dokka-base" version="1.7.20-dev-178">
-         <artifact name="dokka-base-1.7.20-dev-178.jar">
-            <sha256 value="043de520b665454fa144a0018875a9303454f16c3cda45c63f3d354f86fdfe66" origin="Generated manually"/>
-         </artifact>
-         <artifact name="dokka-base-1.7.20-dev-178.module">
-            <sha256 value="ddee298e92ee3e8b60c55967bc2b66d8871725db2758d8f44bec3069a7165986" origin="Generated manually"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="dokka-cli" version="1.7.20-dev-178">
-         <artifact name="dokka-cli-1.7.20-dev-178.jar">
-            <sha256 value="4ed2e6846156cd619b00ba942c1bb46489a9cd88118fa7a9236d9ceb2b036930" origin="Generated manually"/>
-         </artifact>
-         <artifact name="dokka-cli-1.7.20-dev-178.pom">
-            <sha256 value="68d9a1bbaa5bca1fea9034450be55cc25ad3f7017f9d017c9b4b65db2f47064a" origin="Generated manually"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="dokka-fatjar" version="0.9.17-g014">
-         <artifact name="dokka-fatjar-0.9.17-g014.jar">
-            <sha256 value="47cf09501402a101e555588cf5fa9ed83f8572bce9fd60db29e74b5d079628e3" origin="Generated by Gradle"/>
-         </artifact>
-         <artifact name="dokka-fatjar-0.9.17-g014.pom">
-            <sha256 value="ceb601f55f14337261fea474bb061407dc0e52146f80d74cd0b43d66febd401f" origin="Generated by Gradle"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="dokka-gradle-plugin" version="0.9.17-g014">
-         <artifact name="dokka-gradle-plugin-0.9.17-g014.jar">
-            <sha256 value="643a7eddeb521832c6021508b7477b603517438481bc06633dca12eb1f339422" origin="Generated by Gradle"/>
-         </artifact>
-         <artifact name="dokka-gradle-plugin-0.9.17-g014.pom">
-            <sha256 value="b217e9a1f1503c9f0c744b736fc2afed6fa6c3c2e86e5276a3c549f5bd48baef" origin="Generated by Gradle"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="kotlin-analysis-compiler" version="1.7.20-dev-178">
-         <artifact name="kotlin-analysis-compiler-1.7.20-dev-178.jar">
-            <sha256 value="051c0ed61798fb30ca74eabe20b0c97e510db34080dd4ca40bae7c6465625f8d" origin="Generated manually"/>
-         </artifact>
-         <artifact name="kotlin-analysis-compiler-1.7.20-dev-178.pom">
-            <sha256 value="9dded49204804e237fc0b237b1f073b87a4bde9901eca6482fc3b6dddf44bf4c" origin="Generated manually"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="kotlin-analysis-intellij" version="1.7.20-dev-178">
-         <artifact name="kotlin-analysis-intellij-1.7.20-dev-178.jar">
-            <sha256 value="85976e1cdd4152d93e6c20be62e0b725c357119955c0a1cc0026a1ba60610acd" origin="Generated manually"/>
-         </artifact>
-         <artifact name="kotlin-analysis-intellij-1.7.20-dev-178.pom">
-            <sha256 value="7bb00911c8f9610c56748277169ea6d95f2d32afca4e9edcfcb4efe23c43cca4" origin="Generated manually"/>
-         </artifact>
-      </component>
-      <component group="org.jetbrains.dokka" name="templating-plugin" version="1.7.20-dev-178">
-         <artifact name="templating-plugin-1.7.20-dev-178.jar">
-            <sha256 value="41347b118770f3dc48a14c18f728395c40ce6f769018709a0d018bade1a64237" origin="Generated manually"/>
-         </artifact>
-         <artifact name="templating-plugin-1.7.20-dev-178.module">
-            <sha256 value="86b38d52c54ffdd52344326e751c5f8020dd7783bc1c8324435932c470b46d1f" origin="Generated manually"/>
-         </artifact>
-      </component>
       <component group="org.jetbrains.kotlin" name="kotlin-reflect" version="1.3.71">
          <artifact name="kotlin-reflect-1.3.71.pom">
             <sha256 value="4df94aaeee8d900be431386e31ef44e82a66e57c3ae30866aec2875aff01fe70" origin="Generated by Gradle"/>
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/SyncStrategyTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/SyncStrategyTest.kt
index f47e622..38050ea 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/SyncStrategyTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/SyncStrategyTest.kt
@@ -42,58 +42,72 @@
     @RequiresApi(Build.VERSION_CODES.O)
     @Test
     fun testSyncStrategy_Always() {
-        val egl = createAndSetupEGLManager(EGLSpec.V14)
-        if (egl.supportsNativeAndroidFence()) {
-            val strategy = SyncStrategy.ALWAYS
-            val fence = strategy.createSyncFence(egl.eglSpec)
-            assertTrue(fence != null)
-            fence?.close()
+        withEgl { egl ->
+            if (egl.supportsNativeAndroidFence()) {
+                val strategy = SyncStrategy.ALWAYS
+                val fence = strategy.createSyncFence(egl.eglSpec)
+                assertTrue(fence != null)
+                fence?.close()
+            }
         }
     }
 
     @Test
     fun testSyncStrategy_onFirstShow_FrontBufferUsageOff_Invisible() {
-        val egl = createAndSetupEGLManager(EGLSpec.V14)
-        if (egl.supportsNativeAndroidFence()) {
-            val strategy = FrontBufferSyncStrategy(0L)
-            val fence = strategy.createSyncFence(EGLSpec.V14)
-            assertTrue(fence != null)
-            fence?.close()
+        withEgl { egl ->
+            if (egl.supportsNativeAndroidFence()) {
+                val strategy = FrontBufferSyncStrategy(0L)
+                val fence = strategy.createSyncFence(EGLSpec.V14)
+                assertTrue(fence != null)
+                fence?.close()
+            }
         }
     }
 
     @Test
     fun testSyncStrategy_onFirstShow_FrontBufferUsageOff_Visible() {
-        val egl = createAndSetupEGLManager(EGLSpec.V14)
-        if (egl.supportsNativeAndroidFence()) {
-            val strategy = FrontBufferSyncStrategy(0L)
-            strategy.isVisible = true
-            val fence = strategy.createSyncFence(EGLSpec.V14)
-            assertTrue(fence == null)
-            fence?.close()
+        withEgl { egl ->
+            if (egl.supportsNativeAndroidFence()) {
+                val strategy = FrontBufferSyncStrategy(0L)
+                strategy.isVisible = true
+                val fence = strategy.createSyncFence(EGLSpec.V14)
+                assertTrue(fence == null)
+                fence?.close()
+            }
         }
     }
 
     @Test
     fun testSyncStrategy_onFirstShow_FrontBufferUsageOn_Invisible() {
-        val egl = createAndSetupEGLManager(EGLSpec.V14)
-        if (egl.supportsNativeAndroidFence()) {
-            val strategy = FrontBufferSyncStrategy(mUsageFlags)
-            val fence = strategy.createSyncFence(egl.eglSpec)
-            assertTrue(fence != null)
-            fence?.close()
+        withEgl { egl ->
+            if (egl.supportsNativeAndroidFence()) {
+                val strategy = FrontBufferSyncStrategy(mUsageFlags)
+                val fence = strategy.createSyncFence(egl.eglSpec)
+                assertTrue(fence != null)
+                fence?.close()
+            }
         }
     }
 
     @Test
     fun testSyncStrategy_onFirstShow_FrontBufferUsageOn_Visible() {
+        withEgl { egl ->
+            if (egl.supportsNativeAndroidFence()) {
+                val strategy = FrontBufferSyncStrategy(mUsageFlags)
+                strategy.isVisible = true
+                val fence = strategy.createSyncFence(EGLSpec.V14)
+                assertTrue(fence == null)
+                fence?.close()
+            }
+        }
+    }
+
+    private fun withEgl(block: (egl: EGLManager) -> Unit) {
         val egl = createAndSetupEGLManager(EGLSpec.V14)
-        if (egl.supportsNativeAndroidFence()) {
-            val strategy = FrontBufferSyncStrategy(mUsageFlags)
-            strategy.isVisible = true
-            val fence = strategy.createSyncFence(EGLSpec.V14)
-            assertTrue(fence == null)
-            fence?.close()
+        try {
+            block(egl)
+        } finally {
+            releaseEGLManager(egl)
         }
     }
 
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
index f7e5a2b..d2a9139 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
@@ -58,7 +58,6 @@
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertTrue
 import org.junit.Assert.fail
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -221,7 +220,6 @@
         }
     }
 
-    @Ignore // b/266736718
     @Test
     fun testCreatePBufferSurface() {
         testEGLManager {
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt
index ac90937..8676442 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt
@@ -58,13 +58,23 @@
      * [androidx.health.connect.client.records.metadata.Metadata.id] generated. Insertion of
      * multiple [records] is executed in a transaction - if one fails, none is inserted.
      *
+     * @param records List of records to insert
+     * @return List of unique identifiers in the order of inserted records.
+     * @throws RemoteException For any IPC transportation failures.
+     * @throws SecurityException For requests with unpermitted access.
+     * @throws IOException For any disk I/O issues.
+     * @throws IllegalStateException If service is not available.
+     *
      * For example, to insert basic data like step counts:
+     *
      * @sample androidx.health.connect.client.samples.InsertSteps
      *
      * To insert more complex data like nutrition for a user who’s eaten a banana:
+     *
      * @sample androidx.health.connect.client.samples.InsertNutrition
      *
      * To insert some heart rate data:
+     *
      * @sample androidx.health.connect.client.samples.InsertHeartRateSeries
      *
      * [androidx.health.connect.client.records.metadata.Metadata.clientRecordId] can be used to
@@ -74,13 +84,6 @@
      * with the higher
      * [androidx.health.connect.client.records.metadata.Metadata.clientRecordVersion] takes
      * precedence.
-     *
-     * @param records List of records to insert
-     * @return List of unique identifiers in the order of inserted records.
-     * @throws RemoteException For any IPC transportation failures.
-     * @throws SecurityException For requests with unpermitted access.
-     * @throws IOException For any disk I/O issues.
-     * @throws IllegalStateException If service is not available.
      */
     suspend fun insertRecords(records: List<Record>): InsertRecordsResponse
 
@@ -90,7 +93,7 @@
      *
      * @param records List of records to update
      * @throws RemoteException For any IPC transportation failures. Update with invalid identifiers
-     * will result in IPC failure.
+     *   will result in IPC failure.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
@@ -101,19 +104,20 @@
      * Deletes one or more [Record] by their identifiers. Deletion of multiple [Record] is executed
      * in single transaction - if one fails, none is deleted.
      *
-     * Example usage to delete written steps data by its unique identifier:
-     * @sample androidx.health.connect.client.samples.DeleteByUniqueIdentifier
-     *
      * @param recordType Which type of [Record] to delete, such as `Steps::class`
      * @param recordIdsList List of [androidx.health.connect.client.records.metadata.Metadata.id] of
-     * [Record] to delete
+     *   [Record] to delete
      * @param clientRecordIdsList List of client record IDs of [Record] to delete
      * @throws RemoteException For any IPC transportation failures. Deleting by invalid identifiers
-     * such as a non-existing identifier or deleting the same record multiple times will result in
-     * IPC failure.
+     *   such as a non-existing identifier or deleting the same record multiple times will result in
+     *   IPC failure.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
+     *
+     * Example usage to delete written steps data by its unique identifier:
+     *
+     * @sample androidx.health.connect.client.samples.DeleteByUniqueIdentifier
      */
     suspend fun deleteRecords(
         recordType: KClass<out Record>,
@@ -126,15 +130,16 @@
      * filtered to [Record] belonging to the calling application). Deletion of multiple [Record] is
      * executed in a transaction - if one fails, none is deleted.
      *
-     * Example usage to delete written steps data in a time range:
-     * @sample androidx.health.connect.client.samples.DeleteByTimeRange
-     *
      * @param recordType Which type of [Record] to delete, such as `Steps::class`
      * @param timeRangeFilter The [TimeRangeFilter] to delete from
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
+     *
+     * Example usage to delete written steps data in a time range:
+     *
+     * @sample androidx.health.connect.client.samples.DeleteByTimeRange
      */
     suspend fun deleteRecords(recordType: KClass<out Record>, timeRangeFilter: TimeRangeFilter)
 
@@ -143,10 +148,10 @@
      *
      * @param recordType Which type of [Record] to read, such as `Steps::class`
      * @param recordId [androidx.health.connect.client.records.metadata.Metadata.id] of [Record] to
-     * read
+     *   read
      * @return The [Record] data point.
      * @throws RemoteException For any IPC transportation failures. Update with invalid identifiers
-     * will result in IPC failure.
+     *   will result in IPC failure.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
@@ -159,17 +164,17 @@
     /**
      * Retrieves a collection of [Record]s.
      *
-     * Example code to read basic data like step counts:
-     * @sample androidx.health.connect.client.samples.ReadStepsRange
-     *
      * @param T the type of [Record]
      * @param request [ReadRecordsRequest] object specifying time range and other filters
-     *
      * @return a response containing a collection of [Record]s.
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
+     *
+     * Example code to read basic data like step counts:
+     *
+     * @sample androidx.health.connect.client.samples.ReadStepsRange
      */
     suspend fun <T : Record> readRecords(request: ReadRecordsRequest<T>): ReadRecordsResponse<T>
 
@@ -177,20 +182,21 @@
      * Reads [AggregateMetric]s according to requested read criteria: [Record]s from
      * [AggregateRequest.dataOriginFilter] and within [AggregateRequest.timeRangeFilter].
      *
-     * Example code to aggregate cumulative data like distance:
-     * @sample androidx.health.connect.client.samples.AggregateDistance
-     *
-     * Example code to retrieve statistical aggregates like maximum or minimum heart rate:
-     * @sample androidx.health.connect.client.samples.AggregateHeartRate
-     *
      * @param request [AggregateRequest] object specifying [AggregateMetric]s to aggregate and other
-     * filters.
-     *
+     *   filters.
      * @return the [AggregationResult] that contains aggregated values.
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
+     *
+     * Example code to aggregate cumulative data like distance:
+     *
+     * @sample androidx.health.connect.client.samples.AggregateDistance
+     *
+     * Example code to retrieve statistical aggregates like maximum or minimum heart rate:
+     *
+     * @sample androidx.health.connect.client.samples.AggregateHeartRate
      */
     suspend fun aggregate(request: AggregateRequest): AggregationResult
 
@@ -205,18 +211,18 @@
      * An [AggregationResultGroupedByDuration] is returned only if there are [Record] to aggregate
      * within start and end time of the row.
      *
-     * Example code to retrieve cumulative step count for each minute within provided time range:
-     * @sample androidx.health.connect.client.samples.AggregateIntoMinutes
-     *
      * @param request [AggregateGroupByDurationRequest] object specifying [AggregateMetric]s to
-     * aggregate and other filters.
-     *
+     *   aggregate and other filters.
      * @return a list of [AggregationResultGroupedByDuration]s, each contains aggregated values and
-     * start/end time of the row. The list is sorted by time in ascending order.
+     *   start/end time of the row. The list is sorted by time in ascending order.
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
+     *
+     * Example code to retrieve cumulative step count for each minute within provided time range:
+     *
+     * @sample androidx.health.connect.client.samples.AggregateIntoMinutes
      */
     suspend fun aggregateGroupByDuration(
         request: AggregateGroupByDurationRequest,
@@ -233,18 +239,18 @@
      * An [AggregationResultGroupedByPeriod] is returned only if there are [Record] to aggregate
      * within start and end time of the row.
      *
-     * Example code to retrieve cumulative step count for each month within provided time range:
-     * @sample androidx.health.connect.client.samples.AggregateIntoMonths
-     *
      * @param request [AggregateGroupByPeriodRequest] object specifying [AggregateMetric]s to
-     * aggregate and other filters.
-     *
+     *   aggregate and other filters.
      * @return a list of [AggregationResultGroupedByPeriod]s, each contains aggregated values and
-     * start/end time of the row. The list is sorted by time in ascending order.
+     *   start/end time of the row. The list is sorted by time in ascending order.
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
+     *
+     * Example code to retrieve cumulative step count for each month within provided time range:
+     *
+     * @sample androidx.health.connect.client.samples.AggregateIntoMonths
      */
     suspend fun aggregateGroupByPeriod(
         request: AggregateGroupByPeriodRequest,
@@ -263,11 +269,9 @@
      *
      * @param request Includes interested types of record to observe changes and optional filters.
      * @return a changes-token
-     *
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IllegalStateException If service is not available.
-     *
      * @see getChanges
      */
     suspend fun getChangesToken(request: ChangesTokenRequest): String
@@ -292,12 +296,10 @@
      *
      * @param notificationIntentAction an action to be used for broadcast messages.
      * @param recordTypes specifies [Record] types of interest.
-     *
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
-     *
      * @see unregisterFromDataNotifications
      * @see androidx.health.connect.client.datanotification.DataNotification
      */
@@ -311,13 +313,11 @@
      * Unregisters the provided [notificationIntentAction] from data notifications.
      *
      * @param notificationIntentAction an action previously registered using
-     * [registerForDataNotifications] method.
-     *
+     *   [registerForDataNotifications] method.
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IOException For any disk I/O issues.
      * @throws IllegalStateException If service is not available.
-     *
      * @see registerForDataNotifications
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY) // Not yet ready for public
@@ -345,13 +345,11 @@
      * ```
      *
      * @param changesToken A Changes-Token that represents a specific point in time in Android
-     * Health Platform.
+     *   Health Platform.
      * @return a [ChangesResponse] with changes since provided [changesToken].
-     *
      * @throws RemoteException For any IPC transportation failures.
      * @throws SecurityException For requests with unpermitted access.
      * @throws IllegalStateException If service is not available.
-     *
      * @see getChangesToken
      */
     suspend fun getChanges(changesToken: String): ChangesResponse
@@ -368,8 +366,8 @@
          * if they want to re-direct the user to Health Connect.
          */
         @get:JvmName("getHealthConnectSettingsAction")
-        @JvmStatic val ACTION_HEALTH_CONNECT_SETTINGS =
-                "androidx.health.ACTION_HEALTH_CONNECT_SETTINGS"
+        @JvmStatic
+        val ACTION_HEALTH_CONNECT_SETTINGS = "androidx.health.ACTION_HEALTH_CONNECT_SETTINGS"
 
         /**
          * The Health Connect SDK is not unavailable on this device at the time. This can be due to
@@ -397,11 +395,11 @@
         @RestrictTo(RestrictTo.Scope.LIBRARY)
         @IntDef(
             value =
-            [
-                SDK_UNAVAILABLE,
-                SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED,
-                SDK_AVAILABLE,
-            ]
+                [
+                    SDK_UNAVAILABLE,
+                    SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED,
+                    SDK_AVAILABLE,
+                ]
         )
         annotation class AvailabilityStatus
 
@@ -410,8 +408,8 @@
          *
          * @param context the context
          * @param providerPackageName optional package provider to choose for backend implementation
-         * @return One of [SDK_UNAVAILABLE], [SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED]
-         * or [SDK_AVAILABLE]
+         * @return One of [SDK_UNAVAILABLE], [SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED] or
+         *   [SDK_AVAILABLE]
          * @sample androidx.health.connect.client.samples.AvailabilityCheckSamples
          */
         @JvmOverloads
@@ -474,11 +472,10 @@
          *
          * @param context the context
          * @param providerPackageName optional alternative package provider to choose for backend
-         * implementation
+         *   implementation
          * @return instance of [HealthConnectClient] ready for issuing requests
          * @throws UnsupportedOperationException if service not available due to SDK version too low
          * @throws IllegalStateException if service not available due to not installed
-         *
          * @see isProviderAvailable
          */
         @JvmOverloads
@@ -517,7 +514,7 @@
             return packageInfo.applicationInfo.enabled &&
                 (packageName != DEFAULT_PROVIDER_PACKAGE_NAME ||
                     PackageInfoCompat.getLongVersionCode(packageInfo) >=
-                    DEFAULT_PROVIDER_MIN_VERSION_CODE) &&
+                        DEFAULT_PROVIDER_MIN_VERSION_CODE) &&
                 hasBindableService(packageManager, packageName)
         }
 
@@ -534,6 +531,7 @@
 
         /**
          * Tag used in SDK debug logs.
+         *
          * @suppress
          */
         @RestrictTo(RestrictTo.Scope.LIBRARY)
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java
index 0c619b1..70c172b 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/widget/GridWidgetTest.java
@@ -949,6 +949,7 @@
         verifyBeginAligned();
     }
 
+    @Ignore // b/269352002
     @Test
     public void testRedundantAppendRemove() throws Throwable {
         Intent intent = new Intent();
diff --git a/libraryversions.toml b/libraryversions.toml
index 0abe361..4877b50 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -31,7 +31,7 @@
 CONSTRAINTLAYOUT_CORE = "1.1.0-alpha08"
 CONTENTPAGER = "1.1.0-alpha01"
 COORDINATORLAYOUT = "1.3.0-alpha01"
-CORE = "1.10.0-alpha03"
+CORE = "1.10.0-beta01"
 CORE_ANIMATION = "1.0.0-beta02"
 CORE_ANIMATION_TESTING = "1.0.0-beta01"
 CORE_APPDIGEST = "1.0.0-alpha01"
@@ -82,7 +82,7 @@
 LEANBACK_TAB = "1.1.0-beta01"
 LEGACY = "1.1.0-alpha01"
 LIBYUV = "0.1.0-dev01"
-LIFECYCLE = "2.6.0-beta01"
+LIFECYCLE = "2.6.0-rc01"
 LIFECYCLE_EXTENSIONS = "2.2.0"
 LOADER = "1.2.0-alpha01"
 MEDIA = "1.7.0-alpha02"
@@ -96,7 +96,7 @@
 PERCENTLAYOUT = "1.1.0-alpha01"
 PREFERENCE = "1.3.0-alpha01"
 PRINT = "1.1.0-beta01"
-PRIVACYSANDBOX_ADS = "1.0.0-alpha01"
+PRIVACYSANDBOX_ADS = "1.0.0-beta01"
 PRIVACYSANDBOX_SDKRUNTIME = "1.0.0-alpha01"
 PRIVACYSANDBOX_TOOLS = "1.0.0-alpha03"
 PRIVACYSANDBOX_UI = "1.0.0-alpha01"
@@ -129,7 +129,7 @@
 TEST_UIAUTOMATOR = "2.3.0-alpha03"
 TEXT = "1.0.0-alpha01"
 TRACING = "1.2.0-alpha02"
-TRACING_PERFETTO = "1.0.0-alpha10"
+TRACING_PERFETTO = "1.0.0-alpha11"
 TRANSITION = "1.5.0-alpha01"
 TV = "1.0.0-alpha04"
 TVPROVIDER = "1.1.0-alpha02"
@@ -140,19 +140,19 @@
 VIEWPAGER = "1.1.0-alpha02"
 VIEWPAGER2 = "1.2.0-alpha01"
 WEAR = "1.3.0-alpha05"
-WEAR_COMPOSE = "1.2.0-alpha04"
+WEAR_COMPOSE = "1.2.0-alpha05"
 WEAR_COMPOSE_MATERIAL3 = "1.0.0-alpha01"
 WEAR_INPUT = "1.2.0-alpha03"
 WEAR_INPUT_TESTING = "1.2.0-alpha03"
 WEAR_ONGOING = "1.1.0-alpha01"
 WEAR_PHONE_INTERACTIONS = "1.1.0-alpha04"
-WEAR_PROTOLAYOUT = "1.0.0-alpha03"
+WEAR_PROTOLAYOUT = "1.0.0-alpha04"
 WEAR_REMOTE_INTERACTIONS = "1.1.0-alpha01"
 WEAR_TILES = "1.2.0-alpha01"
 WEAR_WATCHFACE = "1.2.0-alpha07"
 WEBKIT = "1.7.0-alpha03"
-WINDOW = "1.1.0-alpha05"
-WINDOW_EXTENSIONS = "1.1.0-alpha02"
+WINDOW = "1.1.0-alpha06"
+WINDOW_EXTENSIONS = "1.1.0-alpha03"
 WINDOW_EXTENSIONS_CORE = "1.0.0-alpha01"
 WINDOW_SIDECAR = "1.0.0-rc01"
 WORK = "2.9.0-alpha01"
diff --git a/lifecycle/lifecycle-livedata-core-ktx-lint/src/main/java/androidx/lifecycle/lint/LiveDataCoreIssueRegistry.kt b/lifecycle/lifecycle-livedata-core-ktx-lint/src/main/java/androidx/lifecycle/lint/LiveDataCoreIssueRegistry.kt
index 0b251e7..b0aab4e 100644
--- a/lifecycle/lifecycle-livedata-core-ktx-lint/src/main/java/androidx/lifecycle/lint/LiveDataCoreIssueRegistry.kt
+++ b/lifecycle/lifecycle-livedata-core-ktx-lint/src/main/java/androidx/lifecycle/lint/LiveDataCoreIssueRegistry.kt
@@ -23,7 +23,7 @@
 @Suppress("UnstableApiUsage")
 class LiveDataCoreIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues get() = listOf(NonNullableMutableLiveDataDetector.ISSUE)
     override val vendor = Vendor(
         feedbackUrl = "https://issuetracker.google.com/issues/new?component=413132",
diff --git a/lifecycle/lifecycle-livedata/src/main/java/androidx/lifecycle/Transformations.kt b/lifecycle/lifecycle-livedata/src/main/java/androidx/lifecycle/Transformations.kt
index 26d7c36..c3b9ed6 100644
--- a/lifecycle/lifecycle-livedata/src/main/java/androidx/lifecycle/Transformations.kt
+++ b/lifecycle/lifecycle-livedata/src/main/java/androidx/lifecycle/Transformations.kt
@@ -177,19 +177,20 @@
 @CheckResult
 fun <X> LiveData<X>.distinctUntilChanged(): LiveData<X> {
     val outputLiveData = MediatorLiveData<X>()
-    outputLiveData.addSource(this, object : Observer<X> {
-        var firstTime = true
-
-        override fun onChanged(value: X) {
-            val previousValue = outputLiveData.value
-            if (firstTime ||
-                previousValue == null && value != null ||
-                previousValue != null && previousValue != value
-            ) {
-                firstTime = false
-                outputLiveData.value = value
-            }
+    var firstTime = true
+    if (isInitialized) {
+        outputLiveData.value = value
+        firstTime = false
+    }
+    outputLiveData.addSource(this) { value ->
+        val previousValue = outputLiveData.value
+        if (firstTime ||
+            previousValue == null && value != null ||
+            previousValue != null && previousValue != value
+        ) {
+            firstTime = false
+            outputLiveData.value = value
         }
-    })
+    }
     return outputLiveData
 }
\ No newline at end of file
diff --git a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java
index 4b1a493..d7f3527 100644
--- a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java
+++ b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java
@@ -193,6 +193,19 @@
     }
 
     @Test
+    public void testDistinctUntilChanged_initialValueIsSet() {
+        MutableLiveData<String> originalLiveData = new MutableLiveData<>("value");
+
+        LiveData<String> dedupedLiveData = Transformations.distinctUntilChanged(originalLiveData);
+        assertThat(dedupedLiveData.getValue(), is("value"));
+
+        CountingObserver<String> observer = new CountingObserver<>();
+        dedupedLiveData.observe(mOwner, observer);
+        assertThat(observer.mTimesUpdated, is(1));
+        assertThat(dedupedLiveData.getValue(), is("value"));
+    }
+
+    @Test
     public void testDistinctUntilChanged_triggersOnInitialNullValue() {
         MutableLiveData<String> originalLiveData = new MutableLiveData<>();
         originalLiveData.setValue(null);
diff --git a/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleRuntimeIssueRegistry.kt b/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleRuntimeIssueRegistry.kt
index ca0bb57..b655be5 100644
--- a/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleRuntimeIssueRegistry.kt
+++ b/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleRuntimeIssueRegistry.kt
@@ -23,7 +23,7 @@
 @Suppress("UnstableApiUsage")
 class LifecycleRuntimeIssueRegistry : IssueRegistry() {
     // tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         LifecycleWhenChecks.ISSUE,
diff --git a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
index a4f7ce8..312cadd 100644
--- a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
@@ -25,7 +25,7 @@
 
 class AndroidXIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues get(): List<Issue> {
         return Issues
     }
diff --git a/lint-checks/src/main/java/androidx/build/lint/BanUncheckedReflection.kt b/lint-checks/src/main/java/androidx/build/lint/BanUncheckedReflection.kt
index 7bab6f3..ab2b60d 100644
--- a/lint-checks/src/main/java/androidx/build/lint/BanUncheckedReflection.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/BanUncheckedReflection.kt
@@ -17,19 +17,17 @@
 
 package androidx.build.lint
 
-import com.android.sdklib.SdkVersionInfo.HIGHEST_KNOWN_API
-import com.android.tools.lint.detector.api.ApiConstraint
 import com.android.tools.lint.detector.api.Category
 import com.android.tools.lint.detector.api.Detector
 import com.android.tools.lint.detector.api.Implementation
-import com.android.tools.lint.detector.api.Incident
 import com.android.tools.lint.detector.api.Issue
 import com.android.tools.lint.detector.api.JavaContext
 import com.android.tools.lint.detector.api.Scope
+import com.android.sdklib.SdkVersionInfo.HIGHEST_KNOWN_API
+import com.android.tools.lint.detector.api.Incident
 import com.android.tools.lint.detector.api.Severity
 import com.android.tools.lint.detector.api.SourceCodeScanner
-import com.android.tools.lint.detector.api.VersionChecks.Companion.isPrecededByVersionCheckExit
-import com.android.tools.lint.detector.api.VersionChecks.Companion.isWithinVersionCheckConditional
+import com.android.tools.lint.detector.api.VersionChecks
 import com.intellij.psi.PsiAnnotation
 import com.intellij.psi.PsiMethod
 import org.jetbrains.uast.UCallExpression
@@ -57,14 +55,15 @@
         if (!context.evaluator.isMemberInClass(method, METHOD_REFLECTION_CLASS)) return
 
         // Flag if the call isn't inside or preceded by an SDK_INT check.
-        if (!isWithinVersionCheckConditional(
+        if (!VersionChecks.isWithinVersionCheckConditional(
                 context,
                 node,
-                ApiConstraint.get(HIGHEST_KNOWN_API), false
+                HIGHEST_KNOWN_API,
+                false
             ) &&
-            !isWithinVersionCheckConditional(context, node, ApiConstraint.get(1), true) &&
-            !isPrecededByVersionCheckExit(context, node, ApiConstraint.get(HIGHEST_KNOWN_API)) &&
-            !isPrecededByVersionCheckExit(context, node, ApiConstraint.get(1)) &&
+            !VersionChecks.isWithinVersionCheckConditional(context, node, 1, true) &&
+            !VersionChecks.isPrecededByVersionCheckExit(context, node, HIGHEST_KNOWN_API) &&
+            !VersionChecks.isPrecededByVersionCheckExit(context, node, 1) &&
             !isWithinDeprecatedSinceApiMethod(node) &&
             !isWithinDeprecatedSinceApiClass(node)
         ) {
diff --git a/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt b/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
index 9e9ffe2..62d19a0 100644
--- a/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
@@ -202,7 +202,8 @@
                 ?: return
 
             // Change: Removed SimpleDateFormat and Animator checks
-            var api = apiDatabase.getMethodVersions(owner, name, desc).min()
+            @Suppress("DEPRECATION") // b/262915628
+            var api = apiDatabase.getMethodVersion(owner, name, desc)
             if (api == -1) {
                 return
             }
@@ -259,9 +260,10 @@
                             for (type in inheritanceChain) {
                                 val expressionOwner = evaluator.getQualifiedName(type)
                                 if (expressionOwner != null && expressionOwner != owner) {
-                                    val specificApi = apiDatabase.getMethodVersions(
+                                    @Suppress("DEPRECATION") // b/262915628
+                                    val specificApi = apiDatabase.getMethodVersion(
                                         expressionOwner, name, desc
-                                    ).min()
+                                    )
                                     if (specificApi == -1) {
                                         if (apiDatabase.isRelevantOwner(expressionOwner)) {
                                             return
@@ -338,8 +340,9 @@
                         ) {
                             break
                         }
+                        @Suppress("DEPRECATION") // b/262915628
                         val specificApi =
-                            apiDatabase.getMethodVersions(expressionOwner, name, desc).min()
+                            apiDatabase.getMethodVersion(expressionOwner, name, desc)
                         if (specificApi == -1) {
                             if (apiDatabase.isRelevantOwner(expressionOwner)) {
                                 break
@@ -384,9 +387,10 @@
                                 if (provider != null) {
                                     val methodOwner = evaluator.getQualifiedName(provider)
                                     if (methodOwner != null) {
-                                        val methodApi = apiDatabase.getMethodVersions(
+                                        @Suppress("DEPRECATION") // b/262915628
+                                        val methodApi = apiDatabase.getMethodVersion(
                                             methodOwner, name, desc
-                                        ).min()
+                                        )
                                         if (methodApi == -1 || methodApi <= minSdk) {
                                             // Yes, we found another call that doesn't have an API requirement
                                             return
@@ -852,7 +856,8 @@
         private fun classAvailableAtMinSdk(className: String): Boolean {
             val apiDatabase = apiDatabase ?: return false
             val minSdk = getMinSdk(context)
-            val version = apiDatabase.getClassVersions(className).min()
+            @Suppress("DEPRECATION") // b/262915628
+            val version = apiDatabase.getClassVersion(className)
             return version <= minSdk
         }
 
diff --git a/navigation/OWNERS b/navigation/OWNERS
index bf053cd..ec2387e6 100644
--- a/navigation/OWNERS
+++ b/navigation/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 409828
+# Bug component: 606741
 [email protected]
 [email protected]
 [email protected]
diff --git a/navigation/navigation-common-lint/src/main/java/androidx/navigation/common/lint/NavigationCommonIssueRegistry.kt b/navigation/navigation-common-lint/src/main/java/androidx/navigation/common/lint/NavigationCommonIssueRegistry.kt
index f5a5d52..ff861cd 100644
--- a/navigation/navigation-common-lint/src/main/java/androidx/navigation/common/lint/NavigationCommonIssueRegistry.kt
+++ b/navigation/navigation-common-lint/src/main/java/androidx/navigation/common/lint/NavigationCommonIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class NavigationCommonIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         EmptyNavDeepLinkDetector.EmptyNavDeepLink
diff --git a/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/NavigationComposeIssueRegistry.kt b/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/NavigationComposeIssueRegistry.kt
index b6b5d155..402db3be 100644
--- a/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/NavigationComposeIssueRegistry.kt
+++ b/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/NavigationComposeIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class NavigationComposeIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         ComposableDestinationInComposeScopeDetector.ComposableDestinationInComposeScope,
diff --git a/navigation/navigation-compose/samples/build.gradle b/navigation/navigation-compose/samples/build.gradle
index 8ee9740..4cc57c0 100644
--- a/navigation/navigation-compose/samples/build.gradle
+++ b/navigation/navigation-compose/samples/build.gradle
@@ -30,6 +30,7 @@
 
     compileOnly(projectOrArtifact(":annotation:annotation-sampled"))
     implementation("androidx.compose.foundation:foundation:1.0.1")
+    implementation projectOrArtifact(":compose:ui:ui-tooling")
     implementation(projectOrArtifact(":navigation:navigation-compose"))
     implementation("androidx.compose.material:material:1.0.1")
     implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
diff --git a/navigation/navigation-compose/samples/src/main/java/androidx/navigation/compose/samples/NavigationSamples.kt b/navigation/navigation-compose/samples/src/main/java/androidx/navigation/compose/samples/NavigationSamples.kt
index d38c258..4cc5ef4 100644
--- a/navigation/navigation-compose/samples/src/main/java/androidx/navigation/compose/samples/NavigationSamples.kt
+++ b/navigation/navigation-compose/samples/src/main/java/androidx/navigation/compose/samples/NavigationSamples.kt
@@ -21,6 +21,7 @@
 import androidx.annotation.Sampled
 import androidx.annotation.StringRes
 import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
@@ -35,11 +36,15 @@
 import androidx.compose.material.Scaffold
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color.Companion.LightGray
+import androidx.compose.ui.platform.LocalInspectionMode
 import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.navigation.NavController
@@ -242,6 +247,27 @@
     }
 }
 
+@Preview
+@Composable
+fun NavHostPreview() {
+    CompositionLocalProvider(
+        LocalInspectionMode provides true,
+    ) {
+        Box(Modifier.fillMaxSize().background(Color.Red)) {
+            NavHost(
+                navController = rememberNavController(),
+                startDestination = "home"
+            ) {
+                composable("home") {
+                    Box(Modifier.fillMaxSize().background(Color.Blue)) {
+                        Text(text = "test", modifier = Modifier.testTag("text"))
+                    }
+                }
+            }
+        }
+    }
+}
+
 private val phrases = listOf(
     "Easy As Pie",
     "Wouldn't Harm a Fly",
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt
index 989e166..4cec329 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt
@@ -41,6 +41,7 @@
 import java.util.concurrent.TimeUnit
 import kotlin.reflect.KClass
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -696,6 +697,7 @@
         assertWithMessage("Entry2 should have been stopped").that(entry1Stopped).isTrue()
     }
 
+    @Ignore // b/269297210
     @LargeTest
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
diff --git a/navigation/navigation-runtime-lint/src/main/java/androidx/navigation/runtime/lint/NavigationRuntimeIssueRegistry.kt b/navigation/navigation-runtime-lint/src/main/java/androidx/navigation/runtime/lint/NavigationRuntimeIssueRegistry.kt
index 48b846a..b4d90ba 100644
--- a/navigation/navigation-runtime-lint/src/main/java/androidx/navigation/runtime/lint/NavigationRuntimeIssueRegistry.kt
+++ b/navigation/navigation-runtime-lint/src/main/java/androidx/navigation/runtime/lint/NavigationRuntimeIssueRegistry.kt
@@ -27,7 +27,7 @@
  */
 class NavigationRuntimeIssueRegistry : IssueRegistry() {
     // Tests are run with this version. We ensure that with ApiLintVersionsTest
-    override val api = 14
+    override val api = 13
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         DeepLinkInActivityDestinationDetector.DeepLinkInActivityDestination
diff --git a/privacysandbox/ads/ads-adservices-java/api/1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices-java/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..26eea8b
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/1.0.0-beta01.txt
@@ -0,0 +1,92 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.java.adid {
+
+  public abstract class AdIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adid.AdId> getAdIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AdIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.adselection {
+
+  public abstract class AdSelectionManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> reportImpressionAsync(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome> selectAdsAsync(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    field public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures.Companion Companion;
+  }
+
+  public static final class AdSelectionManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.appsetid {
+
+  public abstract class AppSetIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.appsetid.AppSetId> getAppSetIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AppSetIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.customaudience {
+
+  public abstract class CustomAudienceManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> joinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> leaveCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion Companion;
+  }
+
+  public static final class CustomAudienceManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.measurement {
+
+  public abstract class MeasurementManagerFutures {
+    method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> deleteRegistrationsAsync(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest);
+    method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures.Companion Companion;
+  }
+
+  public static final class MeasurementManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.topics {
+
+  public abstract class TopicsManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse> getTopicsAsync(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures.Companion Companion;
+  }
+
+  public static final class TopicsManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices-java/api/public_plus_experimental_1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices-java/api/public_plus_experimental_1.0.0-beta01.txt
new file mode 100644
index 0000000..26eea8b
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/public_plus_experimental_1.0.0-beta01.txt
@@ -0,0 +1,92 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.java.adid {
+
+  public abstract class AdIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adid.AdId> getAdIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AdIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.adselection {
+
+  public abstract class AdSelectionManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> reportImpressionAsync(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome> selectAdsAsync(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    field public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures.Companion Companion;
+  }
+
+  public static final class AdSelectionManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.appsetid {
+
+  public abstract class AppSetIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.appsetid.AppSetId> getAppSetIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AppSetIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.customaudience {
+
+  public abstract class CustomAudienceManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> joinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> leaveCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion Companion;
+  }
+
+  public static final class CustomAudienceManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.measurement {
+
+  public abstract class MeasurementManagerFutures {
+    method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> deleteRegistrationsAsync(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest);
+    method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures.Companion Companion;
+  }
+
+  public static final class MeasurementManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.topics {
+
+  public abstract class TopicsManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse> getTopicsAsync(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures.Companion Companion;
+  }
+
+  public static final class TopicsManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices-java/api/res-1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices-java/api/res-1.0.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/res-1.0.0-beta01.txt
diff --git a/privacysandbox/ads/ads-adservices-java/api/restricted_1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices-java/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..26eea8b
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,92 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.java.adid {
+
+  public abstract class AdIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adid.AdId> getAdIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AdIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.adselection {
+
+  public abstract class AdSelectionManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> reportImpressionAsync(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome> selectAdsAsync(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    field public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures.Companion Companion;
+  }
+
+  public static final class AdSelectionManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.appsetid {
+
+  public abstract class AppSetIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.appsetid.AppSetId> getAppSetIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AppSetIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.customaudience {
+
+  public abstract class CustomAudienceManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> joinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> leaveCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion Companion;
+  }
+
+  public static final class CustomAudienceManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.measurement {
+
+  public abstract class MeasurementManagerFutures {
+    method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> deleteRegistrationsAsync(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest);
+    method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures.Companion Companion;
+  }
+
+  public static final class MeasurementManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.topics {
+
+  public abstract class TopicsManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse> getTopicsAsync(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures.Companion Companion;
+  }
+
+  public static final class TopicsManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/TestUtil.java b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/TestUtil.java
index 8d5d99a..6da172a 100644
--- a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/TestUtil.java
+++ b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/TestUtil.java
@@ -135,6 +135,21 @@
         runShellCommand("setprop debug.adservices.disable_measurement_enrollment_check null");
     }
 
+    // Force using bundled files instead of using MDD downloaded files. This helps to make the test
+    // results deterministic.
+    public void shouldForceUseBundledFiles(boolean shouldUse) {
+        if (shouldUse) {
+            runShellCommand("device_config put adservices classifier_force_use_bundled_files true");
+        }
+        else {
+            runShellCommand("device_config delete adservices classifier_force_use_bundled_files");
+        }
+    }
+
+    public void enableVerboseLogging() {
+        runShellCommand("setprop log.tag.adservices VERBOSE");
+    }
+
     @SuppressWarnings("deprecation")
     // Used to get the package name. Copied over from com.android.adservices.AndroidServiceBinder
     public String getAdServicesPackageName() {
diff --git a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/topics/TopicsManagerTest.java b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/topics/TopicsManagerTest.java
index 49c545ae..b6155a8 100644
--- a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/topics/TopicsManagerTest.java
+++ b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/topics/TopicsManagerTest.java
@@ -66,6 +66,10 @@
         mTestUtil.overrideAllowlists(true);
         // TODO: Remove this override.
         mTestUtil.enableEnrollmentCheck(true);
+        // Force to use bundled files to make test result deterministic.
+        mTestUtil.shouldForceUseBundledFiles(true);
+        // Enable verbose logging.
+        mTestUtil.enableVerboseLogging();
     }
 
     @After
@@ -76,6 +80,7 @@
         mTestUtil.overrideConsentManagerDebugMode(false);
         mTestUtil.overrideAllowlists(false);
         mTestUtil.enableEnrollmentCheck(false);
+        mTestUtil.shouldForceUseBundledFiles(false);
     }
 
     @Test
@@ -92,7 +97,7 @@
         GetTopicsResponse response = topicsManager.getTopicsAsync(request).get();
 
         // At beginning, Sdk1 receives no topic.
-        assertThat(response.getTopics().isEmpty());
+        assertThat(response.getTopics()).isEmpty();
 
         // Now force the Epoch Computation Job. This should be done in the same epoch for
         // callersCanLearnMap to have the entry for processing.
@@ -106,8 +111,8 @@
         response = topicsManager.getTopicsAsync(request).get();
         assertThat(response.getTopics()).isNotEmpty();
 
-        // Top 5 classifications for empty string with v2 model are [10230, 10253, 10227, 10250,
-        // 10257]. This is computed by running the model on the device for empty string.
+        // Top 5 classifications for empty string with v2 model are [10147, 10253, 10175, 10254,
+        // 10333]. This is computed by running the model on the device for empty string.
         // These 5 classification topics will become top 5 topics of the epoch since there is
         // no other apps calling Topics API.
         // The app will be assigned one random topic from one of these 5 topics.
@@ -116,7 +121,7 @@
         Topic topic = response.getTopics().get(0);
 
         // topic is one of the 5 classification topics of the Test App.
-        assertThat(topic.getTopicId()).isIn(Arrays.asList(10230, 10253, 10227, 10250, 10257));
+        assertThat(topic.getTopicId()).isIn(Arrays.asList(10147, 10253, 10175, 10254, 10333));
 
         assertThat(topic.getModelVersion()).isAtLeast(1L);
         assertThat(topic.getTaxonomyVersion()).isAtLeast(1L);
diff --git a/privacysandbox/ads/ads-adservices/api/1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..30cd307
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/1.0.0-beta01.txt
@@ -0,0 +1,345 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.adid {
+
+  public final class AdId {
+    method public String getAdId();
+    method public boolean isLimitAdTrackingEnabled();
+    property public final String adId;
+    property public final boolean isLimitAdTrackingEnabled;
+  }
+
+  public abstract class AdIdManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract suspend Object? getAdId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adid.AdId>);
+    method public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager.Companion Companion;
+  }
+
+  public static final class AdIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.adselection {
+
+  public final class AdSelectionConfig {
+    ctor public AdSelectionConfig(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller, android.net.Uri decisionLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals, java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals, android.net.Uri trustedScoringSignalsUri);
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getAdSelectionSignals();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> getCustomAudienceBuyers();
+    method public android.net.Uri getDecisionLogicUri();
+    method public java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> getPerBuyerSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getSeller();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getSellerSignals();
+    method public android.net.Uri getTrustedScoringSignalsUri();
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers;
+    property public final android.net.Uri decisionLogicUri;
+    property public final java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals;
+    property public final android.net.Uri trustedScoringSignalsUri;
+  }
+
+  public abstract class AdSelectionManager {
+    method public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? reportImpression(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? selectAds(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome>);
+    field public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion Companion;
+  }
+
+  public static final class AdSelectionManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+  }
+
+  public final class AdSelectionOutcome {
+    ctor public AdSelectionOutcome(long adSelectionId, android.net.Uri renderUri);
+    method public long getAdSelectionId();
+    method public android.net.Uri getRenderUri();
+    property public final long adSelectionId;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class ReportImpressionRequest {
+    ctor public ReportImpressionRequest(long adSelectionId, androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig getAdSelectionConfig();
+    method public long getAdSelectionId();
+    property public final androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig;
+    property public final long adSelectionId;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.appsetid {
+
+  public final class AppSetId {
+    ctor public AppSetId(String id, int scope);
+    method public String getId();
+    method public int getScope();
+    property public final String id;
+    property public final int scope;
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetId.Companion Companion;
+    field public static final int SCOPE_APP = 1; // 0x1
+    field public static final int SCOPE_DEVELOPER = 2; // 0x2
+  }
+
+  public static final class AppSetId.Companion {
+  }
+
+  public abstract class AppSetIdManager {
+    method public abstract suspend Object? getAppSetId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.appsetid.AppSetId>);
+    method public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager.Companion Companion;
+  }
+
+  public static final class AppSetIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.common {
+
+  public final class AdData {
+    ctor public AdData(android.net.Uri renderUri, String metadata);
+    method public String getMetadata();
+    method public android.net.Uri getRenderUri();
+    property public final String metadata;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class AdSelectionSignals {
+    ctor public AdSelectionSignals(String signals);
+    method public String getSignals();
+    property public final String signals;
+  }
+
+  public final class AdTechIdentifier {
+    ctor public AdTechIdentifier(String identifier);
+    method public String getIdentifier();
+    property public final String identifier;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.customaudience {
+
+  public final class CustomAudience {
+    ctor public CustomAudience(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads, optional java.time.Instant? activationTime, optional java.time.Instant? expirationTime, optional androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals, optional androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals);
+    method public java.time.Instant? getActivationTime();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> getAds();
+    method public android.net.Uri getBiddingLogicUri();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public android.net.Uri getDailyUpdateUri();
+    method public java.time.Instant? getExpirationTime();
+    method public String getName();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? getTrustedBiddingSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? getUserBiddingSignals();
+    property public final java.time.Instant? activationTime;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads;
+    property public final android.net.Uri biddingLogicUri;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final android.net.Uri dailyUpdateUri;
+    property public final java.time.Instant? expirationTime;
+    property public final String name;
+    property public final androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals;
+  }
+
+  public static final class CustomAudience.Builder {
+    ctor public CustomAudience.Builder(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setActivationTime(java.time.Instant activationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setAds(java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBiddingLogicUri(android.net.Uri biddingLogicUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBuyer(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setDailyUpdateUri(android.net.Uri dailyUpdateUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setExpirationTime(java.time.Instant expirationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setName(String name);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setTrustedBiddingData(androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData trustedBiddingSignals);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setUserBiddingSignals(androidx.privacysandbox.ads.adservices.common.AdSelectionSignals userBiddingSignals);
+  }
+
+  public abstract class CustomAudienceManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? joinCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? leaveCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion Companion;
+  }
+
+  public static final class CustomAudienceManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+  }
+
+  public final class JoinCustomAudienceRequest {
+    ctor public JoinCustomAudienceRequest(androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience getCustomAudience();
+    property public final androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience;
+  }
+
+  public final class LeaveCustomAudienceRequest {
+    ctor public LeaveCustomAudienceRequest(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name);
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public String getName();
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final String name;
+  }
+
+  public final class TrustedBiddingData {
+    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    method public java.util.List<java.lang.String> getTrustedBiddingKeys();
+    method public android.net.Uri getTrustedBiddingUri();
+    property public final java.util.List<java.lang.String> trustedBiddingKeys;
+    property public final android.net.Uri trustedBiddingUri;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.measurement {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class DeletionRequest {
+    ctor public DeletionRequest(int deletionMode, int matchBehavior, optional java.time.Instant start, optional java.time.Instant end, optional java.util.List<? extends android.net.Uri> domainUris, optional java.util.List<? extends android.net.Uri> originUris);
+    method public int getDeletionMode();
+    method public java.util.List<android.net.Uri> getDomainUris();
+    method public java.time.Instant getEnd();
+    method public int getMatchBehavior();
+    method public java.util.List<android.net.Uri> getOriginUris();
+    method public java.time.Instant getStart();
+    property public final int deletionMode;
+    property public final java.util.List<android.net.Uri> domainUris;
+    property public final java.time.Instant end;
+    property public final int matchBehavior;
+    property public final java.util.List<android.net.Uri> originUris;
+    property public final java.time.Instant start;
+    field public static final androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Companion Companion;
+    field public static final int DELETION_MODE_ALL = 0; // 0x0
+    field public static final int DELETION_MODE_EXCLUDE_INTERNAL_DATA = 1; // 0x1
+    field public static final int MATCH_BEHAVIOR_DELETE = 0; // 0x0
+    field public static final int MATCH_BEHAVIOR_PRESERVE = 1; // 0x1
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class DeletionRequest.Builder {
+    ctor public DeletionRequest.Builder(int deletionMode, int matchBehavior);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setDomainUris(java.util.List<? extends android.net.Uri> domainUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setEnd(java.time.Instant end);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setOriginUris(java.util.List<? extends android.net.Uri> originUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setStart(java.time.Instant start);
+  }
+
+  public static final class DeletionRequest.Companion {
+  }
+
+  public abstract class MeasurementManager {
+    ctor public MeasurementManager();
+    method public abstract suspend Object? deleteRegistrations(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
+    method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    field public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion Companion;
+    field public static final int MEASUREMENT_API_STATE_DISABLED = 0; // 0x0
+    field public static final int MEASUREMENT_API_STATE_ENABLED = 1; // 0x1
+  }
+
+  public static final class MeasurementManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
+    ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceRegistrationRequest {
+    ctor public WebSourceRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri, optional android.view.InputEvent? inputEvent, optional android.net.Uri? appDestination, optional android.net.Uri? webDestination, optional android.net.Uri? verifiedDestination);
+    method public android.net.Uri? getAppDestination();
+    method public android.view.InputEvent? getInputEvent();
+    method public android.net.Uri getTopOriginUri();
+    method public android.net.Uri? getVerifiedDestination();
+    method public android.net.Uri? getWebDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> getWebSourceParams();
+    property public final android.net.Uri? appDestination;
+    property public final android.view.InputEvent? inputEvent;
+    property public final android.net.Uri topOriginUri;
+    property public final android.net.Uri? verifiedDestination;
+    property public final android.net.Uri? webDestination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams;
+  }
+
+  public static final class WebSourceRegistrationRequest.Builder {
+    ctor public WebSourceRegistrationRequest.Builder(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setAppDestination(android.net.Uri? appDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setVerifiedDestination(android.net.Uri? verifiedDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setWebDestination(android.net.Uri? webDestination);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerParams {
+    ctor public WebTriggerParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerRegistrationRequest {
+    ctor public WebTriggerRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams, android.net.Uri destination);
+    method public android.net.Uri getDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> getWebTriggerParams();
+    property public final android.net.Uri destination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.topics {
+
+  public final class GetTopicsRequest {
+    ctor public GetTopicsRequest(optional String adsSdkName, optional boolean shouldRecordObservation);
+    method public String getAdsSdkName();
+    method public boolean getShouldRecordObservation();
+    property public final String adsSdkName;
+    property public final boolean shouldRecordObservation;
+  }
+
+  public static final class GetTopicsRequest.Builder {
+    ctor public GetTopicsRequest.Builder();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest build();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setAdsSdkName(String adsSdkName);
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setShouldRecordObservation(boolean shouldRecordObservation);
+  }
+
+  public final class GetTopicsResponse {
+    ctor public GetTopicsResponse(java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics);
+    method public java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> getTopics();
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics;
+  }
+
+  public final class Topic {
+    ctor public Topic(long taxonomyVersion, long modelVersion, int topicId);
+    method public long getModelVersion();
+    method public long getTaxonomyVersion();
+    method public int getTopicId();
+    property public final long modelVersion;
+    property public final long taxonomyVersion;
+    property public final int topicId;
+  }
+
+  public abstract class TopicsManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract suspend Object? getTopics(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse>);
+    method public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion Companion;
+  }
+
+  public static final class TopicsManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta01.txt
new file mode 100644
index 0000000..30cd307
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta01.txt
@@ -0,0 +1,345 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.adid {
+
+  public final class AdId {
+    method public String getAdId();
+    method public boolean isLimitAdTrackingEnabled();
+    property public final String adId;
+    property public final boolean isLimitAdTrackingEnabled;
+  }
+
+  public abstract class AdIdManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract suspend Object? getAdId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adid.AdId>);
+    method public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager.Companion Companion;
+  }
+
+  public static final class AdIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.adselection {
+
+  public final class AdSelectionConfig {
+    ctor public AdSelectionConfig(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller, android.net.Uri decisionLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals, java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals, android.net.Uri trustedScoringSignalsUri);
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getAdSelectionSignals();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> getCustomAudienceBuyers();
+    method public android.net.Uri getDecisionLogicUri();
+    method public java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> getPerBuyerSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getSeller();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getSellerSignals();
+    method public android.net.Uri getTrustedScoringSignalsUri();
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers;
+    property public final android.net.Uri decisionLogicUri;
+    property public final java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals;
+    property public final android.net.Uri trustedScoringSignalsUri;
+  }
+
+  public abstract class AdSelectionManager {
+    method public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? reportImpression(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? selectAds(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome>);
+    field public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion Companion;
+  }
+
+  public static final class AdSelectionManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+  }
+
+  public final class AdSelectionOutcome {
+    ctor public AdSelectionOutcome(long adSelectionId, android.net.Uri renderUri);
+    method public long getAdSelectionId();
+    method public android.net.Uri getRenderUri();
+    property public final long adSelectionId;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class ReportImpressionRequest {
+    ctor public ReportImpressionRequest(long adSelectionId, androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig getAdSelectionConfig();
+    method public long getAdSelectionId();
+    property public final androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig;
+    property public final long adSelectionId;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.appsetid {
+
+  public final class AppSetId {
+    ctor public AppSetId(String id, int scope);
+    method public String getId();
+    method public int getScope();
+    property public final String id;
+    property public final int scope;
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetId.Companion Companion;
+    field public static final int SCOPE_APP = 1; // 0x1
+    field public static final int SCOPE_DEVELOPER = 2; // 0x2
+  }
+
+  public static final class AppSetId.Companion {
+  }
+
+  public abstract class AppSetIdManager {
+    method public abstract suspend Object? getAppSetId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.appsetid.AppSetId>);
+    method public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager.Companion Companion;
+  }
+
+  public static final class AppSetIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.common {
+
+  public final class AdData {
+    ctor public AdData(android.net.Uri renderUri, String metadata);
+    method public String getMetadata();
+    method public android.net.Uri getRenderUri();
+    property public final String metadata;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class AdSelectionSignals {
+    ctor public AdSelectionSignals(String signals);
+    method public String getSignals();
+    property public final String signals;
+  }
+
+  public final class AdTechIdentifier {
+    ctor public AdTechIdentifier(String identifier);
+    method public String getIdentifier();
+    property public final String identifier;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.customaudience {
+
+  public final class CustomAudience {
+    ctor public CustomAudience(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads, optional java.time.Instant? activationTime, optional java.time.Instant? expirationTime, optional androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals, optional androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals);
+    method public java.time.Instant? getActivationTime();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> getAds();
+    method public android.net.Uri getBiddingLogicUri();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public android.net.Uri getDailyUpdateUri();
+    method public java.time.Instant? getExpirationTime();
+    method public String getName();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? getTrustedBiddingSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? getUserBiddingSignals();
+    property public final java.time.Instant? activationTime;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads;
+    property public final android.net.Uri biddingLogicUri;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final android.net.Uri dailyUpdateUri;
+    property public final java.time.Instant? expirationTime;
+    property public final String name;
+    property public final androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals;
+  }
+
+  public static final class CustomAudience.Builder {
+    ctor public CustomAudience.Builder(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setActivationTime(java.time.Instant activationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setAds(java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBiddingLogicUri(android.net.Uri biddingLogicUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBuyer(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setDailyUpdateUri(android.net.Uri dailyUpdateUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setExpirationTime(java.time.Instant expirationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setName(String name);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setTrustedBiddingData(androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData trustedBiddingSignals);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setUserBiddingSignals(androidx.privacysandbox.ads.adservices.common.AdSelectionSignals userBiddingSignals);
+  }
+
+  public abstract class CustomAudienceManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? joinCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? leaveCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion Companion;
+  }
+
+  public static final class CustomAudienceManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+  }
+
+  public final class JoinCustomAudienceRequest {
+    ctor public JoinCustomAudienceRequest(androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience getCustomAudience();
+    property public final androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience;
+  }
+
+  public final class LeaveCustomAudienceRequest {
+    ctor public LeaveCustomAudienceRequest(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name);
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public String getName();
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final String name;
+  }
+
+  public final class TrustedBiddingData {
+    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    method public java.util.List<java.lang.String> getTrustedBiddingKeys();
+    method public android.net.Uri getTrustedBiddingUri();
+    property public final java.util.List<java.lang.String> trustedBiddingKeys;
+    property public final android.net.Uri trustedBiddingUri;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.measurement {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class DeletionRequest {
+    ctor public DeletionRequest(int deletionMode, int matchBehavior, optional java.time.Instant start, optional java.time.Instant end, optional java.util.List<? extends android.net.Uri> domainUris, optional java.util.List<? extends android.net.Uri> originUris);
+    method public int getDeletionMode();
+    method public java.util.List<android.net.Uri> getDomainUris();
+    method public java.time.Instant getEnd();
+    method public int getMatchBehavior();
+    method public java.util.List<android.net.Uri> getOriginUris();
+    method public java.time.Instant getStart();
+    property public final int deletionMode;
+    property public final java.util.List<android.net.Uri> domainUris;
+    property public final java.time.Instant end;
+    property public final int matchBehavior;
+    property public final java.util.List<android.net.Uri> originUris;
+    property public final java.time.Instant start;
+    field public static final androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Companion Companion;
+    field public static final int DELETION_MODE_ALL = 0; // 0x0
+    field public static final int DELETION_MODE_EXCLUDE_INTERNAL_DATA = 1; // 0x1
+    field public static final int MATCH_BEHAVIOR_DELETE = 0; // 0x0
+    field public static final int MATCH_BEHAVIOR_PRESERVE = 1; // 0x1
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class DeletionRequest.Builder {
+    ctor public DeletionRequest.Builder(int deletionMode, int matchBehavior);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setDomainUris(java.util.List<? extends android.net.Uri> domainUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setEnd(java.time.Instant end);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setOriginUris(java.util.List<? extends android.net.Uri> originUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setStart(java.time.Instant start);
+  }
+
+  public static final class DeletionRequest.Companion {
+  }
+
+  public abstract class MeasurementManager {
+    ctor public MeasurementManager();
+    method public abstract suspend Object? deleteRegistrations(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
+    method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    field public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion Companion;
+    field public static final int MEASUREMENT_API_STATE_DISABLED = 0; // 0x0
+    field public static final int MEASUREMENT_API_STATE_ENABLED = 1; // 0x1
+  }
+
+  public static final class MeasurementManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
+    ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceRegistrationRequest {
+    ctor public WebSourceRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri, optional android.view.InputEvent? inputEvent, optional android.net.Uri? appDestination, optional android.net.Uri? webDestination, optional android.net.Uri? verifiedDestination);
+    method public android.net.Uri? getAppDestination();
+    method public android.view.InputEvent? getInputEvent();
+    method public android.net.Uri getTopOriginUri();
+    method public android.net.Uri? getVerifiedDestination();
+    method public android.net.Uri? getWebDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> getWebSourceParams();
+    property public final android.net.Uri? appDestination;
+    property public final android.view.InputEvent? inputEvent;
+    property public final android.net.Uri topOriginUri;
+    property public final android.net.Uri? verifiedDestination;
+    property public final android.net.Uri? webDestination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams;
+  }
+
+  public static final class WebSourceRegistrationRequest.Builder {
+    ctor public WebSourceRegistrationRequest.Builder(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setAppDestination(android.net.Uri? appDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setVerifiedDestination(android.net.Uri? verifiedDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setWebDestination(android.net.Uri? webDestination);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerParams {
+    ctor public WebTriggerParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerRegistrationRequest {
+    ctor public WebTriggerRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams, android.net.Uri destination);
+    method public android.net.Uri getDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> getWebTriggerParams();
+    property public final android.net.Uri destination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.topics {
+
+  public final class GetTopicsRequest {
+    ctor public GetTopicsRequest(optional String adsSdkName, optional boolean shouldRecordObservation);
+    method public String getAdsSdkName();
+    method public boolean getShouldRecordObservation();
+    property public final String adsSdkName;
+    property public final boolean shouldRecordObservation;
+  }
+
+  public static final class GetTopicsRequest.Builder {
+    ctor public GetTopicsRequest.Builder();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest build();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setAdsSdkName(String adsSdkName);
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setShouldRecordObservation(boolean shouldRecordObservation);
+  }
+
+  public final class GetTopicsResponse {
+    ctor public GetTopicsResponse(java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics);
+    method public java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> getTopics();
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics;
+  }
+
+  public final class Topic {
+    ctor public Topic(long taxonomyVersion, long modelVersion, int topicId);
+    method public long getModelVersion();
+    method public long getTaxonomyVersion();
+    method public int getTopicId();
+    property public final long modelVersion;
+    property public final long taxonomyVersion;
+    property public final int topicId;
+  }
+
+  public abstract class TopicsManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract suspend Object? getTopics(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse>);
+    method public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion Companion;
+  }
+
+  public static final class TopicsManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices/api/res-1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices/api/res-1.0.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/res-1.0.0-beta01.txt
diff --git a/privacysandbox/ads/ads-adservices/api/restricted_1.0.0-beta01.txt b/privacysandbox/ads/ads-adservices/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..30cd307
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,345 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.adid {
+
+  public final class AdId {
+    method public String getAdId();
+    method public boolean isLimitAdTrackingEnabled();
+    property public final String adId;
+    property public final boolean isLimitAdTrackingEnabled;
+  }
+
+  public abstract class AdIdManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract suspend Object? getAdId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adid.AdId>);
+    method public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager.Companion Companion;
+  }
+
+  public static final class AdIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.adselection {
+
+  public final class AdSelectionConfig {
+    ctor public AdSelectionConfig(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller, android.net.Uri decisionLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals, java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals, android.net.Uri trustedScoringSignalsUri);
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getAdSelectionSignals();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> getCustomAudienceBuyers();
+    method public android.net.Uri getDecisionLogicUri();
+    method public java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> getPerBuyerSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getSeller();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getSellerSignals();
+    method public android.net.Uri getTrustedScoringSignalsUri();
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers;
+    property public final android.net.Uri decisionLogicUri;
+    property public final java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals;
+    property public final android.net.Uri trustedScoringSignalsUri;
+  }
+
+  public abstract class AdSelectionManager {
+    method public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? reportImpression(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? selectAds(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome>);
+    field public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion Companion;
+  }
+
+  public static final class AdSelectionManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+  }
+
+  public final class AdSelectionOutcome {
+    ctor public AdSelectionOutcome(long adSelectionId, android.net.Uri renderUri);
+    method public long getAdSelectionId();
+    method public android.net.Uri getRenderUri();
+    property public final long adSelectionId;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class ReportImpressionRequest {
+    ctor public ReportImpressionRequest(long adSelectionId, androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig getAdSelectionConfig();
+    method public long getAdSelectionId();
+    property public final androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig;
+    property public final long adSelectionId;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.appsetid {
+
+  public final class AppSetId {
+    ctor public AppSetId(String id, int scope);
+    method public String getId();
+    method public int getScope();
+    property public final String id;
+    property public final int scope;
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetId.Companion Companion;
+    field public static final int SCOPE_APP = 1; // 0x1
+    field public static final int SCOPE_DEVELOPER = 2; // 0x2
+  }
+
+  public static final class AppSetId.Companion {
+  }
+
+  public abstract class AppSetIdManager {
+    method public abstract suspend Object? getAppSetId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.appsetid.AppSetId>);
+    method public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager.Companion Companion;
+  }
+
+  public static final class AppSetIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.common {
+
+  public final class AdData {
+    ctor public AdData(android.net.Uri renderUri, String metadata);
+    method public String getMetadata();
+    method public android.net.Uri getRenderUri();
+    property public final String metadata;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class AdSelectionSignals {
+    ctor public AdSelectionSignals(String signals);
+    method public String getSignals();
+    property public final String signals;
+  }
+
+  public final class AdTechIdentifier {
+    ctor public AdTechIdentifier(String identifier);
+    method public String getIdentifier();
+    property public final String identifier;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.customaudience {
+
+  public final class CustomAudience {
+    ctor public CustomAudience(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads, optional java.time.Instant? activationTime, optional java.time.Instant? expirationTime, optional androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals, optional androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals);
+    method public java.time.Instant? getActivationTime();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> getAds();
+    method public android.net.Uri getBiddingLogicUri();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public android.net.Uri getDailyUpdateUri();
+    method public java.time.Instant? getExpirationTime();
+    method public String getName();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? getTrustedBiddingSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? getUserBiddingSignals();
+    property public final java.time.Instant? activationTime;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads;
+    property public final android.net.Uri biddingLogicUri;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final android.net.Uri dailyUpdateUri;
+    property public final java.time.Instant? expirationTime;
+    property public final String name;
+    property public final androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals;
+  }
+
+  public static final class CustomAudience.Builder {
+    ctor public CustomAudience.Builder(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setActivationTime(java.time.Instant activationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setAds(java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBiddingLogicUri(android.net.Uri biddingLogicUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBuyer(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setDailyUpdateUri(android.net.Uri dailyUpdateUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setExpirationTime(java.time.Instant expirationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setName(String name);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setTrustedBiddingData(androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData trustedBiddingSignals);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setUserBiddingSignals(androidx.privacysandbox.ads.adservices.common.AdSelectionSignals userBiddingSignals);
+  }
+
+  public abstract class CustomAudienceManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? joinCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? leaveCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion Companion;
+  }
+
+  public static final class CustomAudienceManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+  }
+
+  public final class JoinCustomAudienceRequest {
+    ctor public JoinCustomAudienceRequest(androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience getCustomAudience();
+    property public final androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience;
+  }
+
+  public final class LeaveCustomAudienceRequest {
+    ctor public LeaveCustomAudienceRequest(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name);
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public String getName();
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final String name;
+  }
+
+  public final class TrustedBiddingData {
+    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    method public java.util.List<java.lang.String> getTrustedBiddingKeys();
+    method public android.net.Uri getTrustedBiddingUri();
+    property public final java.util.List<java.lang.String> trustedBiddingKeys;
+    property public final android.net.Uri trustedBiddingUri;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.measurement {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class DeletionRequest {
+    ctor public DeletionRequest(int deletionMode, int matchBehavior, optional java.time.Instant start, optional java.time.Instant end, optional java.util.List<? extends android.net.Uri> domainUris, optional java.util.List<? extends android.net.Uri> originUris);
+    method public int getDeletionMode();
+    method public java.util.List<android.net.Uri> getDomainUris();
+    method public java.time.Instant getEnd();
+    method public int getMatchBehavior();
+    method public java.util.List<android.net.Uri> getOriginUris();
+    method public java.time.Instant getStart();
+    property public final int deletionMode;
+    property public final java.util.List<android.net.Uri> domainUris;
+    property public final java.time.Instant end;
+    property public final int matchBehavior;
+    property public final java.util.List<android.net.Uri> originUris;
+    property public final java.time.Instant start;
+    field public static final androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Companion Companion;
+    field public static final int DELETION_MODE_ALL = 0; // 0x0
+    field public static final int DELETION_MODE_EXCLUDE_INTERNAL_DATA = 1; // 0x1
+    field public static final int MATCH_BEHAVIOR_DELETE = 0; // 0x0
+    field public static final int MATCH_BEHAVIOR_PRESERVE = 1; // 0x1
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class DeletionRequest.Builder {
+    ctor public DeletionRequest.Builder(int deletionMode, int matchBehavior);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setDomainUris(java.util.List<? extends android.net.Uri> domainUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setEnd(java.time.Instant end);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setOriginUris(java.util.List<? extends android.net.Uri> originUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setStart(java.time.Instant start);
+  }
+
+  public static final class DeletionRequest.Companion {
+  }
+
+  public abstract class MeasurementManager {
+    ctor public MeasurementManager();
+    method public abstract suspend Object? deleteRegistrations(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
+    method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    field public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion Companion;
+    field public static final int MEASUREMENT_API_STATE_DISABLED = 0; // 0x0
+    field public static final int MEASUREMENT_API_STATE_ENABLED = 1; // 0x1
+  }
+
+  public static final class MeasurementManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
+    ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceRegistrationRequest {
+    ctor public WebSourceRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri, optional android.view.InputEvent? inputEvent, optional android.net.Uri? appDestination, optional android.net.Uri? webDestination, optional android.net.Uri? verifiedDestination);
+    method public android.net.Uri? getAppDestination();
+    method public android.view.InputEvent? getInputEvent();
+    method public android.net.Uri getTopOriginUri();
+    method public android.net.Uri? getVerifiedDestination();
+    method public android.net.Uri? getWebDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> getWebSourceParams();
+    property public final android.net.Uri? appDestination;
+    property public final android.view.InputEvent? inputEvent;
+    property public final android.net.Uri topOriginUri;
+    property public final android.net.Uri? verifiedDestination;
+    property public final android.net.Uri? webDestination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams;
+  }
+
+  public static final class WebSourceRegistrationRequest.Builder {
+    ctor public WebSourceRegistrationRequest.Builder(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setAppDestination(android.net.Uri? appDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setVerifiedDestination(android.net.Uri? verifiedDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setWebDestination(android.net.Uri? webDestination);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerParams {
+    ctor public WebTriggerParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerRegistrationRequest {
+    ctor public WebTriggerRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams, android.net.Uri destination);
+    method public android.net.Uri getDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> getWebTriggerParams();
+    property public final android.net.Uri destination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.topics {
+
+  public final class GetTopicsRequest {
+    ctor public GetTopicsRequest(optional String adsSdkName, optional boolean shouldRecordObservation);
+    method public String getAdsSdkName();
+    method public boolean getShouldRecordObservation();
+    property public final String adsSdkName;
+    property public final boolean shouldRecordObservation;
+  }
+
+  public static final class GetTopicsRequest.Builder {
+    ctor public GetTopicsRequest.Builder();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest build();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setAdsSdkName(String adsSdkName);
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setShouldRecordObservation(boolean shouldRecordObservation);
+  }
+
+  public final class GetTopicsResponse {
+    ctor public GetTopicsResponse(java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics);
+    method public java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> getTopics();
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics;
+  }
+
+  public final class Topic {
+    ctor public Topic(long taxonomyVersion, long modelVersion, int topicId);
+    method public long getModelVersion();
+    method public long getTaxonomyVersion();
+    method public int getTopicId();
+    property public final long modelVersion;
+    property public final long taxonomyVersion;
+    property public final int topicId;
+  }
+
+  public abstract class TopicsManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract suspend Object? getTopics(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse>);
+    method public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion Companion;
+  }
+
+  public static final class TopicsManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices/build.gradle b/privacysandbox/ads/ads-adservices/build.gradle
index 2679d8e..1c3ab60 100644
--- a/privacysandbox/ads/ads-adservices/build.gradle
+++ b/privacysandbox/ads/ads-adservices/build.gradle
@@ -28,7 +28,7 @@
     api(libs.kotlinStdlib)
     api(libs.kotlinCoroutinesCore)
     implementation("androidx.core:core-ktx:1.8.0")
-    api(projectOrArtifact(":annotation:annotation"))
+    api("androidx.annotation:annotation:1.6.0")
 
     androidTestImplementation(libs.junit)
     androidTestImplementation(libs.kotlinTestJunit)
diff --git a/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/RecyclerViewIssueRegistry.kt b/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/RecyclerViewIssueRegistry.kt
index 877177f..4e2d8ab 100644
--- a/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/RecyclerViewIssueRegistry.kt
+++ b/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/RecyclerViewIssueRegistry.kt
@@ -25,7 +25,7 @@
 
 class RecyclerViewIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues: List<Issue>
         get() = listOf(
             InvalidSetHasFixedSizeDetector.ISSUE
diff --git a/recyclerview/recyclerview/api/current.txt b/recyclerview/recyclerview/api/current.txt
index 3750c3c..ca945e9 100644
--- a/recyclerview/recyclerview/api/current.txt
+++ b/recyclerview/recyclerview/api/current.txt
@@ -470,6 +470,7 @@
     method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
     method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
     method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public static void setDebugAssertionsEnabled(boolean);
     method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
     method public void setHasFixedSize(boolean);
     method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
@@ -483,6 +484,7 @@
     method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
     method @Deprecated public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
     method public void setScrollingTouchSlop(int);
+    method public static void setVerboseLoggingEnabled(boolean);
     method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
     method public void smoothScrollBy(@Px int, @Px int);
     method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
diff --git a/recyclerview/recyclerview/api/public_plus_experimental_current.txt b/recyclerview/recyclerview/api/public_plus_experimental_current.txt
index 3750c3c..ca945e9 100644
--- a/recyclerview/recyclerview/api/public_plus_experimental_current.txt
+++ b/recyclerview/recyclerview/api/public_plus_experimental_current.txt
@@ -470,6 +470,7 @@
     method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
     method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
     method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public static void setDebugAssertionsEnabled(boolean);
     method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
     method public void setHasFixedSize(boolean);
     method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
@@ -483,6 +484,7 @@
     method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
     method @Deprecated public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
     method public void setScrollingTouchSlop(int);
+    method public static void setVerboseLoggingEnabled(boolean);
     method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
     method public void smoothScrollBy(@Px int, @Px int);
     method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
diff --git a/recyclerview/recyclerview/api/restricted_current.txt b/recyclerview/recyclerview/api/restricted_current.txt
index 31a4f238..2b2bdad 100644
--- a/recyclerview/recyclerview/api/restricted_current.txt
+++ b/recyclerview/recyclerview/api/restricted_current.txt
@@ -470,6 +470,7 @@
     method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
     method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
     method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public static void setDebugAssertionsEnabled(boolean);
     method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
     method public void setHasFixedSize(boolean);
     method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
@@ -483,6 +484,7 @@
     method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
     method @Deprecated public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
     method public void setScrollingTouchSlop(int);
+    method public static void setVerboseLoggingEnabled(boolean);
     method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
     method public void smoothScrollBy(@Px int, @Px int);
     method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GapWorker.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GapWorker.java
index b2d9f2e..5bbdcf1 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GapWorker.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GapWorker.java
@@ -157,7 +157,7 @@
     }
 
     public void add(RecyclerView recyclerView) {
-        if (RecyclerView.DEBUG && mRecyclerViews.contains(recyclerView)) {
+        if (RecyclerView.sDebugAssertionsEnabled && mRecyclerViews.contains(recyclerView)) {
             throw new IllegalStateException("RecyclerView already present in worker list!");
         }
         mRecyclerViews.add(recyclerView);
@@ -165,7 +165,7 @@
 
     public void remove(RecyclerView recyclerView) {
         boolean removeSuccess = mRecyclerViews.remove(recyclerView);
-        if (RecyclerView.DEBUG && !removeSuccess) {
+        if (RecyclerView.sDebugAssertionsEnabled && !removeSuccess) {
             throw new IllegalStateException("RecyclerView removal failed!");
         }
     }
@@ -175,7 +175,7 @@
      */
     void postFromTraversal(RecyclerView recyclerView, int prefetchDx, int prefetchDy) {
         if (recyclerView.isAttachedToWindow()) {
-            if (RecyclerView.DEBUG && !mRecyclerViews.contains(recyclerView)) {
+            if (RecyclerView.sDebugAssertionsEnabled && !mRecyclerViews.contains(recyclerView)) {
                 throw new IllegalStateException("attempting to post unregistered view!");
             }
             if (mPostTimeNs == 0) {
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
index 149cc67..22e7245 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
@@ -219,7 +219,8 @@
 
     static final String TAG = "RecyclerView";
 
-    static final boolean DEBUG = false;
+    static boolean sDebugAssertionsEnabled = false;
+    static boolean sVerboseLoggingEnabled = false;
 
     static final boolean VERBOSE_TRACING = false;
 
@@ -386,6 +387,35 @@
     private static final Class<?>[] LAYOUT_MANAGER_CONSTRUCTOR_SIGNATURE =
             new Class<?>[]{Context.class, AttributeSet.class, int.class, int.class};
 
+    /**
+     * Enable internal assertions about RecyclerView's state and throw exceptions if the
+     * assertions are violated.
+     * <p>
+     * This is primarily intended to diagnose problems with RecyclerView, and
+     * <strong>should not be enabled in production</strong> unless you have a specific reason to
+     * do so.
+     * <p>
+     * Enabling this may negatively affect performance and/or stability.
+     *
+     * @param debugAssertionsEnabled true to enable assertions; false to disable them
+     */
+    public static void setDebugAssertionsEnabled(boolean debugAssertionsEnabled) {
+        RecyclerView.sDebugAssertionsEnabled = debugAssertionsEnabled;
+    }
+
+    /**
+     * Enable verbose logging within RecyclerView itself.
+     * <p>
+     * Enabling this may negatively affect performance and reduce the utility of logcat due to
+     * high-volume logging.  This generally <strong>should not be enabled in production</strong>
+     * unless you have a specific reason for doing so.
+     *
+     * @param verboseLoggingEnabled true to enable logging; false to disable it
+     */
+    public static void setVerboseLoggingEnabled(boolean verboseLoggingEnabled) {
+        RecyclerView.sVerboseLoggingEnabled = verboseLoggingEnabled;
+    }
+
     private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver();
 
     final Recycler mRecycler = new Recycler();
@@ -983,7 +1013,7 @@
                         throw new IllegalArgumentException("Called attach on a child which is not"
                                 + " detached: " + vh + exceptionLabel());
                     }
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "reAttach " + vh);
                     }
                     vh.clearTmpDetachFlag();
@@ -1001,7 +1031,7 @@
                             throw new IllegalArgumentException("called detach on an already"
                                     + " detached child " + vh + exceptionLabel());
                         }
-                        if (DEBUG) {
+                        if (sVerboseLoggingEnabled) {
                             Log.d(TAG, "tmpDetach " + vh);
                         }
                         vh.addFlags(ViewHolder.FLAG_TMP_DETACHED);
@@ -1039,7 +1069,7 @@
                 // ensure it is not hidden because for adapter helper, the only thing matter is that
                 // LM thinks view is a child.
                 if (mChildHelper.isHidden(vh.itemView)) {
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "assuming view holder cannot be find because it is hidden");
                     }
                     return null;
@@ -1554,7 +1584,7 @@
             final ViewHolder viewHolder = getChildViewHolderInt(view);
             mRecycler.unscrapView(viewHolder);
             mRecycler.recycleViewHolderInternal(viewHolder);
-            if (DEBUG) {
+            if (sVerboseLoggingEnabled) {
                 Log.d(TAG, "after removing animated view: " + view + ", " + this);
             }
         }
@@ -1638,7 +1668,7 @@
         if (state == mScrollState) {
             return;
         }
-        if (DEBUG) {
+        if (sVerboseLoggingEnabled) {
             Log.d(TAG, "setting scroll state to " + state + " from " + mScrollState,
                     new Exception());
         }
@@ -2407,7 +2437,7 @@
     void stopInterceptRequestLayout(boolean performLayoutChildren) {
         if (mInterceptRequestLayoutDepth < 1) {
             //noinspection PointlessBooleanExpression
-            if (DEBUG) {
+            if (sDebugAssertionsEnabled) {
                 throw new IllegalStateException("stopInterceptRequestLayout was called more "
                         + "times than startInterceptRequestLayout."
                         + exceptionLabel());
@@ -4105,7 +4135,7 @@
     void onExitLayoutOrScroll(boolean enableChangeEvents) {
         mLayoutOrScrollCounter--;
         if (mLayoutOrScrollCounter < 1) {
-            if (DEBUG && mLayoutOrScrollCounter < 0) {
+            if (sDebugAssertionsEnabled && mLayoutOrScrollCounter < 0) {
                 throw new IllegalStateException("layout or scroll counter cannot go below zero."
                         + "Some calls are not matching" + exceptionLabel());
             }
@@ -5015,7 +5045,7 @@
         final int childCount = mChildHelper.getUnfilteredChildCount();
         for (int i = 0; i < childCount; i++) {
             final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
-            if (DEBUG && holder.mPosition == -1 && !holder.isRemoved()) {
+            if (sDebugAssertionsEnabled && holder.mPosition == -1 && !holder.isRemoved()) {
                 throw new IllegalStateException("view holder cannot have position -1 unless it"
                         + " is removed" + exceptionLabel());
             }
@@ -5054,7 +5084,7 @@
             if (holder == null || holder.mPosition < start || holder.mPosition > end) {
                 continue;
             }
-            if (DEBUG) {
+            if (sVerboseLoggingEnabled) {
                 Log.d(TAG, "offsetPositionRecordsForMove attached child " + i + " holder "
                         + holder);
             }
@@ -5075,7 +5105,7 @@
         for (int i = 0; i < childCount; i++) {
             final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
             if (holder != null && !holder.shouldIgnore() && holder.mPosition >= positionStart) {
-                if (DEBUG) {
+                if (sVerboseLoggingEnabled) {
                     Log.d(TAG, "offsetPositionRecordsForInsert attached child " + i + " holder "
                             + holder + " now at position " + (holder.mPosition + itemCount));
                 }
@@ -5095,7 +5125,7 @@
             final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
             if (holder != null && !holder.shouldIgnore()) {
                 if (holder.mPosition >= positionEnd) {
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i
                                 + " holder " + holder + " now at position "
                                 + (holder.mPosition - itemCount));
@@ -5103,7 +5133,7 @@
                     holder.offsetPosition(-itemCount, applyToPreLayout);
                     mState.mStructureChanged = true;
                 } else if (holder.mPosition >= positionStart) {
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i
                                 + " holder " + holder + " now REMOVED");
                     }
@@ -6284,7 +6314,7 @@
                 PoolingContainer.callPoolingContainerOnRelease(scrap.itemView);
                 return;
             }
-            if (DEBUG && scrapHeap.contains(scrap)) {
+            if (sDebugAssertionsEnabled && scrapHeap.contains(scrap)) {
                 throw new IllegalArgumentException("this scrap item already exists");
             }
             scrap.resetInternal();
@@ -6539,7 +6569,7 @@
             // if it is a removed holder, nothing to verify since we cannot ask adapter anymore
             // if it is not removed, verify the type and id.
             if (holder.isRemoved()) {
-                if (DEBUG && !mState.isPreLayout()) {
+                if (sDebugAssertionsEnabled && !mState.isPreLayout()) {
                     throw new IllegalStateException("should not receive a removed view unless it"
                             + " is pre layout" + exceptionLabel());
                 }
@@ -6788,7 +6818,7 @@
                     }
                 }
                 if (holder == null) { // fallback to pool
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "tryGetViewHolderForPositionByDeadline("
                                 + position + ") fetching from shared pool");
                     }
@@ -6818,7 +6848,7 @@
 
                     long end = getNanoTime();
                     mRecyclerPool.factorInCreateTime(type, end - start);
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "tryGetViewHolderForPositionByDeadline created new ViewHolder");
                     }
                 }
@@ -6845,7 +6875,7 @@
                 // do not update unless we absolutely have to.
                 holder.mPreLayoutPosition = position;
             } else if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {
-                if (DEBUG && holder.isRemoved()) {
+                if (sDebugAssertionsEnabled && holder.isRemoved()) {
                     throw new IllegalStateException("Removed holder should be bound and it should"
                             + " come here only in pre-layout. Holder: " + holder
                             + exceptionLabel());
@@ -6984,11 +7014,11 @@
          * @param cachedViewIndex The index of the view in cached views list
          */
         void recycleCachedViewAt(int cachedViewIndex) {
-            if (DEBUG) {
+            if (sVerboseLoggingEnabled) {
                 Log.d(TAG, "Recycling cached view at index " + cachedViewIndex);
             }
             ViewHolder viewHolder = mCachedViews.get(cachedViewIndex);
-            if (DEBUG) {
+            if (sVerboseLoggingEnabled) {
                 Log.d(TAG, "CachedViewHolder to be recycled: " + viewHolder);
             }
             addViewHolderToRecycledViewPool(viewHolder, true);
@@ -7026,7 +7056,7 @@
                     && mAdapter.onFailedToRecycleView(holder);
             boolean cached = false;
             boolean recycled = false;
-            if (DEBUG && mCachedViews.contains(holder)) {
+            if (sDebugAssertionsEnabled && mCachedViews.contains(holder)) {
                 throw new IllegalArgumentException("cached view received recycle internal? "
                         + holder + exceptionLabel());
             }
@@ -7072,7 +7102,7 @@
 
                 // TODO: consider cancelling an animation when an item is removed scrollBy,
                 // to return it to the pool faster
-                if (DEBUG) {
+                if (sVerboseLoggingEnabled) {
                     Log.d(TAG, "trying to recycle a non-recycleable holder. Hopefully, it will "
                             + "re-visit here. We are still removing it from animation lists"
                             + exceptionLabel());
@@ -7274,7 +7304,7 @@
                     if (!dryRun) {
                         mCachedViews.remove(i);
                     }
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "getScrapOrHiddenOrCachedHolderForPosition(" + position
                                 + ") found match in cache: " + holder);
                     }
@@ -7354,7 +7384,7 @@
             if (mState != null) {
                 mViewInfoStore.removeViewHolder(holder);
             }
-            if (DEBUG) Log.d(TAG, "dispatchViewRecycled: " + holder);
+            if (sVerboseLoggingEnabled) Log.d(TAG, "dispatchViewRecycled: " + holder);
         }
 
         void onAdapterChanged(Adapter<?> oldAdapter, Adapter<?> newAdapter,
@@ -7388,7 +7418,7 @@
                 } else {
                     holder.offsetPosition(inBetweenOffset, false);
                 }
-                if (DEBUG) {
+                if (sVerboseLoggingEnabled) {
                     Log.d(TAG, "offsetPositionRecordsForMove cached child " + i + " holder "
                             + holder);
                 }
@@ -7400,7 +7430,7 @@
             for (int i = 0; i < cachedCount; i++) {
                 final ViewHolder holder = mCachedViews.get(i);
                 if (holder != null && holder.mPosition >= insertedAt) {
-                    if (DEBUG) {
+                    if (sVerboseLoggingEnabled) {
                         Log.d(TAG, "offsetPositionRecordsForInsert cached " + i + " holder "
                                 + holder + " now at position " + (holder.mPosition + count));
                     }
@@ -7423,7 +7453,7 @@
                 final ViewHolder holder = mCachedViews.get(i);
                 if (holder != null) {
                     if (holder.mPosition >= removedEnd) {
-                        if (DEBUG) {
+                        if (sVerboseLoggingEnabled) {
                             Log.d(TAG, "offsetPositionRecordsForRemove cached " + i
                                     + " holder " + holder + " now at position "
                                     + (holder.mPosition - count));
@@ -9173,7 +9203,7 @@
          * @param position Scroll to this adapter position.
          */
         public void scrollToPosition(int position) {
-            if (DEBUG) {
+            if (sVerboseLoggingEnabled) {
                 Log.e(TAG, "You MUST implement scrollToPosition. It will soon become abstract");
             }
         }
@@ -9354,7 +9384,7 @@
                 }
             }
             if (lp.mPendingInvalidate) {
-                if (DEBUG) {
+                if (sVerboseLoggingEnabled) {
                     Log.d(TAG, "consuming pending invalidate on child " + lp.mViewHolder);
                 }
                 holder.itemView.invalidate();
@@ -9946,7 +9976,7 @@
         private void scrapOrRecycleView(Recycler recycler, int index, View view) {
             final ViewHolder viewHolder = getChildViewHolderInt(view);
             if (viewHolder.shouldIgnore()) {
-                if (DEBUG) {
+                if (sVerboseLoggingEnabled) {
                     Log.d(TAG, "ignoring view " + viewHolder);
                 }
                 return;
@@ -12246,7 +12276,7 @@
             mIsRecyclableCount = recyclable ? mIsRecyclableCount - 1 : mIsRecyclableCount + 1;
             if (mIsRecyclableCount < 0) {
                 mIsRecyclableCount = 0;
-                if (DEBUG) {
+                if (sDebugAssertionsEnabled) {
                     throw new RuntimeException("isRecyclable decremented below 0: "
                             + "unmatched pair of setIsRecyable() calls for " + this);
                 }
@@ -12257,7 +12287,7 @@
             } else if (recyclable && mIsRecyclableCount == 0) {
                 mFlags &= ~FLAG_NOT_RECYCLABLE;
             }
-            if (DEBUG) {
+            if (sVerboseLoggingEnabled) {
                 Log.d(TAG, "setIsRecyclable val:" + recyclable + ":" + this);
             }
         }
@@ -12852,7 +12882,7 @@
         protected void onChildAttachedToWindow(View child) {
             if (getChildPosition(child) == getTargetPosition()) {
                 mTargetView = child;
-                if (DEBUG) {
+                if (sVerboseLoggingEnabled) {
                     Log.d(TAG, "smooth scroll target view has been attached");
                 }
             }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt
index b1a65c0..9ad98bf 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt
@@ -29,7 +29,7 @@
  * @see javax.lang.model.type.TypeMirror
  * @see [XArrayType]
  */
-interface XType {
+interface XType : XAnnotated {
     /**
      * The Javapoet [TypeName] representation of the type
      */
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacKmAnnotation.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacKmAnnotation.kt
new file mode 100644
index 0000000..ac2d325
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacKmAnnotation.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2023 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 androidx.room.compiler.processing.javac
+
+import androidx.room.compiler.processing.InternalXAnnotation
+import androidx.room.compiler.processing.XAnnotationBox
+import androidx.room.compiler.processing.XAnnotationValue
+import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.javac.kotlin.KmAnnotationContainer
+
+internal class JavacKmAnnotation(
+    private val env: JavacProcessingEnv,
+    private val kmAnnotation: KmAnnotationContainer
+) : InternalXAnnotation() {
+    override fun <T : Annotation> asAnnotationBox(annotationClass: Class<T>): XAnnotationBox<T> {
+        throw UnsupportedOperationException("No plan to support XAnnotationBox.")
+    }
+
+    override val name: String
+        get() = typeElement.name
+
+    override val qualifiedName: String
+        get() = typeElement.qualifiedName
+
+    override val typeElement: JavacTypeElement by lazy {
+        requireNotNull(env.findTypeElement(kmAnnotation.className))
+    }
+
+    override val type: XType
+        get() = typeElement.type
+
+    override val annotationValues: List<XAnnotationValue> by lazy {
+        val methods = typeElement.getDeclaredMethods()
+        methods.map { method ->
+            JavacKmAnnotationValue(
+                method = method,
+                kmAnnotationArgumentContainer =
+                    kmAnnotation.getArguments(env).getValue(method.jvmName)
+            )
+        }
+    }
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacKmAnnotationValue.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacKmAnnotationValue.kt
new file mode 100644
index 0000000..c100d0b
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacKmAnnotationValue.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2023 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 androidx.room.compiler.processing.javac
+
+import androidx.room.compiler.processing.InternalXAnnotationValue
+import androidx.room.compiler.processing.XMethodElement
+import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.javac.kotlin.KmAnnotationArgumentContainer
+
+internal class JavacKmAnnotationValue(
+    private val method: XMethodElement,
+    override val valueType: XType = method.returnType,
+    private val kmAnnotationArgumentContainer: KmAnnotationArgumentContainer
+) : InternalXAnnotationValue() {
+    override val name: String = method.jvmName
+    override val value: Any? by lazy {
+        kmAnnotationArgumentContainer.getValue(method)
+    }
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt
index 3dd55ea..89420be 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt
@@ -17,6 +17,9 @@
 package androidx.room.compiler.processing.javac
 
 import androidx.room.compiler.codegen.XTypeName
+import androidx.room.compiler.processing.InternalXAnnotated
+import androidx.room.compiler.processing.XAnnotation
+import androidx.room.compiler.processing.XAnnotationBox
 import androidx.room.compiler.processing.XEquality
 import androidx.room.compiler.processing.XNullability
 import androidx.room.compiler.processing.XRawType
@@ -25,6 +28,8 @@
 import androidx.room.compiler.processing.javac.kotlin.KmTypeContainer
 import androidx.room.compiler.processing.ksp.ERROR_JTYPE_NAME
 import androidx.room.compiler.processing.safeTypeName
+import androidx.room.compiler.processing.unwrapRepeatedAnnotationsFromContainer
+import com.google.auto.common.MoreElements
 import com.google.auto.common.MoreTypes
 import javax.lang.model.type.TypeKind
 import javax.lang.model.type.TypeMirror
@@ -34,7 +39,8 @@
     internal val env: JavacProcessingEnv,
     open val typeMirror: TypeMirror,
     internal val maybeNullability: XNullability?,
-) : XType, XEquality {
+) : XType, XEquality, InternalXAnnotated {
+
     // Kotlin type information about the type if this type is driven from Kotlin code.
     abstract val kotlinType: KmTypeContainer?
 
@@ -85,6 +91,37 @@
 
     override fun asTypeName() = xTypeName
 
+    override fun <T : Annotation> getAnnotations(
+        annotation: KClass<T>,
+        containerAnnotation: KClass<out Annotation>?
+    ): List<XAnnotationBox<T>> {
+        throw UnsupportedOperationException("No plan to support XAnnotationBox.")
+    }
+
+    override fun hasAnnotation(
+        annotation: KClass<out Annotation>,
+        containerAnnotation: KClass<out Annotation>?
+    ): Boolean {
+        val annotationClassName: String = annotation.java.canonicalName!!
+        return getAllAnnotations().any { it.qualifiedName == annotationClassName }
+    }
+
+    override fun getAllAnnotations(): List<XAnnotation> {
+        return kotlinType?.annotations?.map {
+            JavacKmAnnotation(env, it)
+        } ?: typeMirror.annotationMirrors.map { mirror -> JavacAnnotation(env, mirror) }
+                .flatMap { annotation ->
+                    annotation.unwrapRepeatedAnnotationsFromContainer() ?: listOf(annotation)
+                }
+    }
+
+    override fun hasAnnotationWithPackage(pkg: String): Boolean {
+        return getAllAnnotations().any {
+            val element = (it.typeElement as JavacTypeElement).element
+            MoreElements.getPackage(element).toString() == pkg
+        }
+    }
+
     override fun equals(other: Any?): Boolean {
         return XEquality.equals(this, other)
     }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
index 5b09016..1029947 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
@@ -37,6 +37,7 @@
 import com.squareup.kotlinpoet.javapoet.JClassName
 import javax.lang.model.element.ElementKind
 import javax.lang.model.element.TypeElement
+import javax.lang.model.type.DeclaredType
 import javax.lang.model.type.TypeKind
 import javax.lang.model.util.ElementFilter
 
@@ -218,11 +219,15 @@
     }
 
     override val superInterfaces by lazy {
+        val superTypesFromKotlinMetadata = kotlinMetadata?.superTypes
+            ?.associateBy { it.className } ?: emptyMap()
         element.interfaces.map {
+            check(it is DeclaredType)
+            val interfaceName = ClassName.get(MoreElements.asType(it.asElement()))
             val element = MoreTypes.asTypeElement(it)
             env.wrap<JavacType>(
                 typeMirror = it,
-                kotlinType = KmClassContainer.createFor(env, element)?.type,
+                kotlinType = superTypesFromKotlinMetadata[interfaceName.canonicalName()],
                 elementNullability = element.nullability
             )
         }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/kotlin/KotlinClassMetadataUtils.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/kotlin/KotlinClassMetadataUtils.kt
index fdf221a..9e8131c 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/kotlin/KotlinClassMetadataUtils.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/kotlin/KotlinClassMetadataUtils.kt
@@ -16,7 +16,12 @@
 
 package androidx.room.compiler.processing.javac.kotlin
 
+import androidx.room.compiler.processing.XArrayType
+import androidx.room.compiler.processing.XEnumTypeElement
+import androidx.room.compiler.processing.XMethodElement
 import androidx.room.compiler.processing.XNullability
+import androidx.room.compiler.processing.javac.JavacKmAnnotation
+import androidx.room.compiler.processing.javac.JavacKmAnnotationValue
 import androidx.room.compiler.processing.javac.JavacProcessingEnv
 import androidx.room.compiler.processing.util.sanitizeAsJavaParameterName
 import javax.lang.model.element.Element
@@ -25,7 +30,10 @@
 import javax.tools.Diagnostic
 import kotlinx.metadata.Flag
 import kotlinx.metadata.Flags
+import kotlinx.metadata.KmAnnotation
+import kotlinx.metadata.KmAnnotationArgument
 import kotlinx.metadata.KmClass
+import kotlinx.metadata.KmClassifier
 import kotlinx.metadata.KmConstructor
 import kotlinx.metadata.KmFunction
 import kotlinx.metadata.KmProperty
@@ -50,10 +58,14 @@
 
     val type: KmTypeContainer by lazy {
         KmTypeContainer(
-            kmType = KmType(flags),
+            kmType = KmType(flags).apply {
+                classifier = KmClassifier.Class(kmClass.name)
+            },
             typeArguments = kmClass.typeParameters.map { kmTypeParameter ->
                 KmTypeContainer(
-                    kmType = KmType(kmTypeParameter.flags),
+                    kmType = KmType(kmTypeParameter.flags).apply {
+                        classifier = KmClassifier.Class(kmTypeParameter.name)
+                    },
                     typeArguments = emptyList(),
                     upperBounds = kmTypeParameter.upperBounds.map { it.asContainer() }
                 )
@@ -65,6 +77,10 @@
         kmClass.supertypes.firstOrNull()?.asContainer()
     }
 
+    val superTypes: List<KmTypeContainer> by lazy {
+        kmClass.supertypes.map { it.asContainer() }
+    }
+
     val typeParameters: List<KmTypeParameterContainer> by lazy {
         kmClass.typeParameters.map { it.asContainer() }
     }
@@ -265,6 +281,16 @@
 ) : KmFlags {
     override val flags: Flags
         get() = kmType.flags
+
+    val className: String? = kmType.classifier.let {
+        when (it) {
+            is KmClassifier.Class -> it.name.replace('/', '.')
+            else -> null
+        }
+    }
+
+    val annotations = kmType.annotations.map { it.asContainer() }
+
     fun isExtensionType() =
         kmType.annotations.any { it.className == "kotlin/ExtensionFunctionType" }
     fun isNullable() = Flag.Type.IS_NULLABLE(flags)
@@ -278,6 +304,49 @@
     )
 }
 
+internal class KmAnnotationContainer(private val kmAnnotation: KmAnnotation) {
+    val className = kmAnnotation.className.replace('/', '.')
+    fun getArguments(env: JavacProcessingEnv): Map<String, KmAnnotationArgumentContainer> {
+        return kmAnnotation.arguments.mapValues { (_, arg) ->
+            arg.asContainer(env)
+        }
+    }
+}
+
+internal class KmAnnotationArgumentContainer(
+    private val env: JavacProcessingEnv,
+    private val kmAnnotationArgument: KmAnnotationArgument
+) {
+    fun getValue(method: XMethodElement): Any? {
+        return kmAnnotationArgument.let {
+            when (it) {
+                is KmAnnotationArgument.LiteralValue<*> -> it.value
+                is KmAnnotationArgument.ArrayValue -> {
+                    it.elements.map {
+                        val valueType = (method.returnType as XArrayType).componentType
+                        JavacKmAnnotationValue(method, valueType, it.asContainer(env))
+                    }
+                }
+                is KmAnnotationArgument.EnumValue -> {
+                    val enumTypeElement = env.findTypeElement(
+                        it.enumClassName.replace('/', '.')) as XEnumTypeElement
+                    enumTypeElement.entries.associateBy { it.name }[it.enumEntryName]
+                }
+                is KmAnnotationArgument.AnnotationValue -> {
+                    val kmAnnotation = KmAnnotation(
+                        it.annotation.className,
+                        it.annotation.arguments
+                    ).asContainer()
+                    JavacKmAnnotation(env, kmAnnotation)
+                }
+                is KmAnnotationArgument.KClassValue -> {
+                    env.requireType(it.className.replace('/', '.'))
+                }
+            }
+        }
+    }
+}
+
 internal val KmTypeContainer.nullability: XNullability
     get() = if (isNullable()) {
         XNullability.NULLABLE
@@ -346,13 +415,14 @@
                 // it here since it is not valid name
                 name = "set-?".sanitizeAsJavaParameterName(0)
             ).apply { type = [email protected] }
+            val returnType = KmType(0).apply { classifier = KmClassifier.Class("Unit") }
             KmPropertyFunctionContainerImpl(
                 flags = this.setterFlags,
                 name = JvmAbi.computeSetterName(this.name),
                 jvmName = it.name,
                 descriptor = it.asString(),
                 parameters = listOf(param.asContainer()),
-                returnType = KmType(0).asContainer(),
+                returnType = returnType.asContainer(),
             )
         },
     )
@@ -373,4 +443,9 @@
     KmValueParameterContainer(
         kmValueParameter = this,
         type = this.type.asContainer()
-    )
\ No newline at end of file
+    )
+
+private fun KmAnnotation.asContainer() = KmAnnotationContainer(this)
+
+private fun KmAnnotationArgument.asContainer(env: JavacProcessingEnv) =
+    KmAnnotationArgumentContainer(env, this)
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt
index 1080617..4039290 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt
@@ -72,7 +72,7 @@
 
     override fun hasAnnotationWithPackage(pkg: String): Boolean {
         return annotations().any {
-            it.annotationType.resolve().declaration.qualifiedName?.getQualifier() == pkg
+            it.annotationType.resolve().declaration.packageName.asString() == pkg
         }
     }
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
index 51a0c6e..4e48afc 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
@@ -28,7 +28,9 @@
     val ksAnnotated: KSAnnotation
 ) : InternalXAnnotation() {
 
-    val ksType: KSType by lazy { ksAnnotated.annotationType.resolve() }
+    val ksType: KSType by lazy {
+        ksAnnotated.annotationType.resolve()
+    }
 
     override val name: String
         get() = ksAnnotated.shortName.asString()
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
index b0d03e1..d6b75dd 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
@@ -24,6 +24,7 @@
 import androidx.room.compiler.processing.tryBox
 import androidx.room.compiler.processing.tryUnbox
 import com.google.devtools.ksp.KspExperimental
+import com.google.devtools.ksp.symbol.KSAnnotation
 import com.google.devtools.ksp.symbol.KSClassDeclaration
 import com.google.devtools.ksp.symbol.KSType
 import com.google.devtools.ksp.symbol.KSTypeArgument
@@ -46,13 +47,13 @@
  * Similarly, we may not be able to get a [KSType] (e.g. if it resolves to error).
  */
 internal abstract class KspType(
-    val env: KspProcessingEnv,
+    env: KspProcessingEnv,
     val ksType: KSType,
     /**
      * Type resolver to convert KSType into its JVM representation.
      */
     protected val jvmTypeResolver: KspJvmTypeResolver?
-) : XType, XEquality {
+) : KspAnnotated(env), XType, XEquality {
     override val rawType by lazy {
         KspRawType(this)
     }
@@ -213,6 +214,8 @@
         }
     }
 
+    override fun annotations(): Sequence<KSAnnotation> = ksType.annotations
+
     override fun isNone(): Boolean {
         // even void is converted to Unit so we don't have none type in KSP
         // see: KspTypeTest.noneType
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
index d96e81d..2b79b8b 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
@@ -1106,6 +1106,158 @@
         }
     }
 
+    @Test
+    fun typeAnnotations() {
+        val kotlinSource = Source.kotlin(
+            "foo.bar.Subject.kt",
+            """
+            package foo.bar
+
+            interface MyInterface
+            open class Base
+
+            @Target(AnnotationTarget.TYPE)
+            annotation class A
+
+            class Subject(i: @A MyInterface) : @A Base(), @A MyInterface {
+                val p: @A MyInterface = TODO()
+                fun f(a: @A MyInterface): @A MyInterface = TODO()
+            }
+            """.trimIndent()
+        )
+        val javaSource = Source.java(
+            "foo.bar.Subject.java",
+            """
+            package foo.bar;
+            import java.lang.annotation.ElementType;
+            import java.lang.annotation.Target;
+            import java.lang.annotation.Repeatable;
+
+            interface MyInterface {}
+            class Base {}
+
+            @Target(ElementType.TYPE_USE)
+            @interface A {}
+
+            class Subject extends @A Base implements @A MyInterface {
+                Subject(@A MyInterface i) {}
+                @A MyInterface p;
+                @A MyInterface f(@A MyInterface a) {
+                    throw new RuntimeException();
+                }
+            }
+            """.trimIndent()
+        )
+
+        listOf(javaSource, kotlinSource).forEach { source ->
+            runTest(
+                sources = listOf(source)
+            ) { invocation ->
+                // We can't see type annotations from precompiled Java classes. Skipping it for now:
+                // https://github.com/google/ksp/issues/1296
+                if (source == javaSource && preCompiled) {
+                    return@runTest
+                }
+                val subject = invocation.processingEnv.requireTypeElement("foo.bar.Subject")
+                // There's an issue in KSP that prevents us from getting type annotations in
+                // places other than supertypes: https://github.com/google/ksp/issues/1325
+                val annotations = if (invocation.isKsp) {
+                    listOf(
+                        subject.superClass!!.getAllAnnotations().first(),
+                        subject.superInterfaces.first().getAllAnnotations().first(),
+                    )
+                } else {
+                    listOf(
+                        subject.superClass!!.getAllAnnotations().first(),
+                        subject.superInterfaces.first().getAllAnnotations().first(),
+                        subject.getDeclaredField("p").type.getAllAnnotations().first(),
+                        subject.getConstructors().first().parameters.first().type
+                            .getAllAnnotations().first(),
+                        subject.getMethodByJvmName("f").returnType
+                            .getAllAnnotations().first(),
+                        subject.getMethodByJvmName("f").parameters.first().type
+                            .getAllAnnotations().first()
+                    )
+                }
+                annotations.forEach { annotation ->
+                    assertThat(annotation.qualifiedName).isEqualTo("foo.bar.A")
+                }
+                assertThat(subject.superClass!!.hasAnnotationWithPackage("foo.bar")).isTrue()
+                subject.superInterfaces.forEach {
+                    assertThat(it.hasAnnotationWithPackage("foo.bar")).isTrue()
+                }
+            }
+        }
+    }
+
+    @Test
+    fun repeatedTypeAnnotations() {
+        val kotlinSource = Source.kotlin(
+            "foo.bar.Subject.kt",
+            """
+            package foo.bar
+
+            @Target(AnnotationTarget.TYPE)
+            @Repeatable
+            annotation class A(val value: Int)
+
+            open class Base
+
+            class Subject : @A(0) @A(1) Base()
+            """.trimIndent()
+        )
+        val javaSource = Source.java(
+            "foo.bar.Subject.java",
+            """
+            package foo.bar;
+            import java.lang.annotation.ElementType;
+            import java.lang.annotation.Target;
+            import java.lang.annotation.Repeatable;
+
+            class Base {}
+
+            @Repeatable(AContainer.class)
+            @Target(ElementType.TYPE_USE)
+            @interface A {
+                int value();
+            }
+
+            @Target(ElementType.TYPE_USE)
+            @interface AContainer {
+                A[] value();
+            }
+
+            class Subject extends @A(0) @A(1) Base {}
+            """.trimIndent()
+        )
+
+        listOf(javaSource, kotlinSource).forEach { source ->
+            runTest(
+                sources = listOf(source)
+            ) { invocation ->
+                // We can't see type annotations from precompiled Java classes. Skipping it for now:
+                // https://github.com/google/ksp/issues/1296
+                if (source == javaSource && preCompiled) {
+                    return@runTest
+                }
+                val subject = invocation.processingEnv.requireTypeElement("foo.bar.Subject")
+                val base = subject.superClass!!
+                assertThat(base.getAllAnnotations()[0].name)
+                    .isEqualTo("A")
+                assertThat(base.getAllAnnotations()[0].qualifiedName)
+                    .isEqualTo("foo.bar.A")
+                assertThat(base.getAllAnnotations()[0].annotationValues.first().asInt())
+                    .isEqualTo(0)
+                assertThat(base.getAllAnnotations()[1].name)
+                    .isEqualTo("A")
+                assertThat(base.getAllAnnotations()[1].qualifiedName)
+                    .isEqualTo("foo.bar.A")
+                assertThat(base.getAllAnnotations()[1].annotationValues.first().asInt())
+                    .isEqualTo(1)
+            }
+        }
+    }
+
     // helper function to read what we need
     private fun XAnnotated.getSuppressValues(): List<String>? {
         return this.findAnnotation<TestSuppressWarnings>()
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt
index 3d05e0b..0ca863f 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt
@@ -57,6 +57,7 @@
 class XAnnotationValueTest(
     private val isPreCompiled: Boolean,
     private val sourceKind: SourceKind,
+    private val isTypeAnnotation: Boolean,
 ) {
     private fun runTest(
         javaSource: Source.JavaSource,
@@ -104,34 +105,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     boolean booleanParam();
                     boolean[] booleanArrayParam();
                     boolean[] booleanVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     booleanParam = true,
                     booleanArrayParam = {true, false, true},
                     booleanVarArgsParam = {false, true, false}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    booleanParam = true,
+                    booleanArrayParam = {true, false, true},
+                    booleanVarArgsParam = {false, true, false}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val booleanParam: Boolean,
                     val booleanArrayParam: BooleanArray,
                     vararg val booleanVarArgsParam: Boolean,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     booleanParam = true,
                     booleanArrayParam = [true, false, true],
                     booleanVarArgsParam = [false, true, false],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    booleanParam = true,
+                    booleanArrayParam = [true, false, true],
+                    booleanVarArgsParam = [false, true, false],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -161,11 +180,7 @@
                     checkSingleValue(value, expectedValues[i])
                 }
             }
-
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -194,34 +209,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     int intParam();
                     int[] intArrayParam();
                     int[] intVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     intParam = (short) 1,
                     intArrayParam = {(byte) 3, (short) 5, 7},
                     intVarArgsParam = {(byte) 9, (short) 11, 13}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    intParam = (short) 1,
+                    intArrayParam = {(byte) 3, (short) 5, 7},
+                    intVarArgsParam = {(byte) 9, (short) 11, 13}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val intParam: Int,
                     val intArrayParam: IntArray,
                     vararg val intVarArgsParam: Int,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     intParam = 1,
                     intArrayParam = [3, 5, 7],
                     intVarArgsParam = [9, 11, 13],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    intParam = 1,
+                    intArrayParam = [3, 5, 7],
+                    intVarArgsParam = [9, 11, 13],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -252,10 +285,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -284,34 +314,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     short shortParam();
                     short[] shortArrayParam();
                     short[] shortVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     shortParam = (byte) 1,
                     shortArrayParam = {(byte) 3, (short) 5, 7},
                     shortVarArgsParam = {(byte) 9, (short) 11, 13}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    shortParam = (byte) 1,
+                    shortArrayParam = {(byte) 3, (short) 5, 7},
+                    shortVarArgsParam = {(byte) 9, (short) 11, 13}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val shortParam: Short,
                     val shortArrayParam: ShortArray,
                     vararg val shortVarArgsParam: Short,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     shortParam = 1,
                     shortArrayParam = [3, 5, 7],
                     shortVarArgsParam = [9, 11, 13],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    shortParam = 1,
+                    shortArrayParam = [3, 5, 7],
+                    shortVarArgsParam = [9, 11, 13],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -342,10 +390,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -374,34 +419,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     long longParam();
                     long[] longArrayParam();
                     long[] longVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     longParam = (byte) 1,
                     longArrayParam = {(short) 3, (int) 5, 7L},
                     longVarArgsParam = {(short) 9, (int) 11, 13L}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    longParam = (byte) 1,
+                    longArrayParam = {(short) 3, (int) 5, 7L},
+                    longVarArgsParam = {(short) 9, (int) 11, 13L}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val longParam: Long,
                     val longArrayParam: LongArray,
                     vararg val longVarArgsParam: Long,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     longParam = 1L,
                     longArrayParam = [3L, 5L, 7L],
                     longVarArgsParam = [9L, 11L, 13L],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    longParam = 1L,
+                    longArrayParam = [3L, 5L, 7L],
+                    longVarArgsParam = [9L, 11L, 13L],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -432,10 +495,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -464,34 +524,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     float floatParam();
                     float[] floatArrayParam();
                     float[] floatVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     floatParam = (byte) 1,
                     floatArrayParam = {(short) 3, 5.1F, 7.1F},
                     floatVarArgsParam = {9, 11.1F, 13.1F}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    floatParam = (byte) 1,
+                    floatArrayParam = {(short) 3, 5.1F, 7.1F},
+                    floatVarArgsParam = {9, 11.1F, 13.1F}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val floatParam: Float,
                     val floatArrayParam: FloatArray,
                     vararg val floatVarArgsParam: Float,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     floatParam = 1F,
                     floatArrayParam = [3F, 5.1F, 7.1F],
                     floatVarArgsParam = [9F, 11.1F, 13.1F],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    floatParam = 1F,
+                    floatArrayParam = [3F, 5.1F, 7.1F],
+                    floatVarArgsParam = [9F, 11.1F, 13.1F],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -522,10 +600,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -554,34 +629,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     double doubleParam();
                     double[] doubleArrayParam();
                     double[] doubleVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     doubleParam = (byte) 1,
                     doubleArrayParam = {(short) 3, 5.1F, 7.1},
                     doubleVarArgsParam = {9, 11.1F, 13.1}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    doubleParam = (byte) 1,
+                    doubleArrayParam = {(short) 3, 5.1F, 7.1},
+                    doubleVarArgsParam = {9, 11.1F, 13.1}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val doubleParam: Double,
                     val doubleArrayParam: DoubleArray,
                     vararg val doubleVarArgsParam: Double,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     doubleParam = 1.0,
                     doubleArrayParam = [3.0, 5.1, 7.1],
                     doubleVarArgsParam = [9.0, 11.1, 13.1],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    doubleParam = 1.0,
+                    doubleArrayParam = [3.0, 5.1, 7.1],
+                    doubleVarArgsParam = [9.0, 11.1, 13.1],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -612,9 +705,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
+            val annotation = getAnnotation(invocation)
             annotation.getAnnotationValue("doubleParam").value
             annotation.getAnnotationValue("doubleArrayParam").value
             annotation.getAnnotationValue("doubleVarArgsParam").value
@@ -676,34 +767,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     byte byteParam();
                     byte[] byteArrayParam();
                     byte[] byteVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     byteParam = (byte) 1,
                     byteArrayParam = {(byte) 3, (byte) 5, (byte) 7},
                     byteVarArgsParam = {(byte) 9, (byte) 11, (byte) 13}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    byteParam = (byte) 1,
+                    byteArrayParam = {(byte) 3, (byte) 5, (byte) 7},
+                    byteVarArgsParam = {(byte) 9, (byte) 11, (byte) 13}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val byteParam: Byte,
                     val byteArrayParam: ByteArray,
                     vararg val byteVarArgsParam: Byte,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     byteParam = 1,
                     byteArrayParam = [3, 5, 7],
                     byteVarArgsParam = [9, 11, 13],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    byteParam = 1,
+                    byteArrayParam = [3, 5, 7],
+                    byteVarArgsParam = [9, 11, 13],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -734,10 +843,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -766,34 +872,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     char charParam();
                     char[] charArrayParam();
                     char[] charVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     charParam = '1',
                     charArrayParam = {'2', '3', '4'},
                     charVarArgsParam = {'5', '6', '7'}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    charParam = '1',
+                    charArrayParam = {'2', '3', '4'},
+                    charVarArgsParam = {'5', '6', '7'}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val charParam: Char,
                     val charArrayParam: CharArray,
                     vararg val charVarArgsParam: Char,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     charParam = '1',
                     charArrayParam = ['2', '3', '4'],
                     charVarArgsParam = ['5', '6', '7'],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    charParam = '1',
+                    charArrayParam = ['2', '3', '4'],
+                    charVarArgsParam = ['5', '6', '7'],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -824,10 +948,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -856,34 +977,52 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     String stringParam();
                     String[] stringArrayParam();
                     String[] stringVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     stringParam = "1",
                     stringArrayParam = {"3", "5", "7"},
                     stringVarArgsParam = {"9", "11", "13"}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    stringParam = "1",
+                    stringArrayParam = {"3", "5", "7"},
+                    stringVarArgsParam = {"9", "11", "13"}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
                 "test.MyClass.kt",
                 """
                 package test
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val stringParam: String,
                     val stringArrayParam: Array<String>,
                     vararg val stringVarArgsParam: String,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     stringParam = "1",
                     stringArrayParam = ["3", "5", "7"],
                     stringVarArgsParam = ["9", "11", "13"],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    stringParam = "1",
+                    stringArrayParam = ["3", "5", "7"],
+                    stringVarArgsParam = ["9", "11", "13"],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -925,10 +1064,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -957,18 +1093,28 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
                 enum MyEnum {V1, V2, V3}
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     MyEnum enumParam();
                     MyEnum[] enumArrayParam();
                     MyEnum[] enumVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     enumParam = MyEnum.V1,
                     enumArrayParam = {MyEnum.V1, MyEnum.V2, MyEnum.V3},
                     enumVarArgsParam = {MyEnum.V3, MyEnum.V2, MyEnum.V1}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    enumParam = MyEnum.V1,
+                    enumArrayParam = {MyEnum.V1, MyEnum.V2, MyEnum.V3},
+                    enumVarArgsParam = {MyEnum.V3, MyEnum.V2, MyEnum.V1}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
@@ -976,17 +1122,25 @@
                 """
                 package test
                 enum class MyEnum {V1, V2, V3}
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val enumParam: MyEnum,
                     val enumArrayParam: Array<MyEnum>,
                     vararg val enumVarArgsParam: MyEnum,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     enumParam = MyEnum.V1,
                     enumArrayParam = [MyEnum.V1, MyEnum.V2, MyEnum.V3],
                     enumVarArgsParam = [MyEnum.V3, MyEnum.V2, MyEnum.V1],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    enumParam = MyEnum.V1,
+                    enumArrayParam = [MyEnum.V1, MyEnum.V2, MyEnum.V3],
+                    enumVarArgsParam = [MyEnum.V3, MyEnum.V2, MyEnum.V1],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -1031,10 +1185,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
                     @test.MyAnnotation(
@@ -1062,20 +1213,30 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
                 class C1 {}
                 class C2 {}
                 class C3 {}
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     Class<?> typeParam();
                     Class<?>[] typeArrayParam();
                     Class<?>[] typeVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     typeParam = C1.class,
                     typeArrayParam = {C1.class, C2.class, C3.class},
                     typeVarArgsParam = {C3.class, C2.class, C1.class}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    typeParam = C1.class,
+                    typeArrayParam = {C1.class, C2.class, C3.class},
+                    typeVarArgsParam = {C3.class, C2.class, C1.class}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
@@ -1085,17 +1246,25 @@
                 class C1
                 class C2
                 class C3
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val typeParam: kotlin.reflect.KClass<*>,
                     val typeArrayParam: Array<kotlin.reflect.KClass<*>>,
                     vararg val typeVarArgsParam: kotlin.reflect.KClass<*>,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     typeParam = C1::class,
                     typeArrayParam = [C1::class, C2::class, C3::class],
                     typeVarArgsParam = [C3::class, C2::class, C1::class],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    typeParam = C1::class,
+                    typeArrayParam = [C1::class, C2::class, C3::class],
+                    typeVarArgsParam = [C3::class, C2::class, C1::class],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -1154,10 +1323,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -1186,20 +1352,30 @@
                 "test.MyClass",
                 """
                 package test;
+                import java.lang.annotation.ElementType;
+                import java.lang.annotation.Target;
                 @interface A {
                     String value();
                 }
+                @Target({ElementType.TYPE, ElementType.TYPE_USE})
                 @interface MyAnnotation {
                     A annotationParam();
                     A[] annotationArrayParam();
                     A[] annotationVarArgsParam(); // There's no varargs in java so use array
                 }
+                interface MyInterface {}
                 @MyAnnotation(
                     annotationParam = @A("1"),
                     annotationArrayParam = {@A("3"), @A("5"), @A("7")},
                     annotationVarArgsParam = {@A("9"), @A("11"), @A("13")}
                 )
-                class MyClass {}
+                class MyClass implements
+                @MyAnnotation(
+                    annotationParam = @A("1"),
+                    annotationArrayParam = {@A("3"), @A("5"), @A("7")},
+                    annotationVarArgsParam = {@A("9"), @A("11"), @A("13")}
+                )
+                MyInterface {}
                 """.trimIndent()
             ) as Source.JavaSource,
             kotlinSource = Source.kotlin(
@@ -1207,17 +1383,25 @@
                 """
                 package test
                 annotation class A(val value: String)
+                @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
                 annotation class MyAnnotation(
                     val annotationParam: A,
                     val annotationArrayParam: Array<A>,
                     vararg val annotationVarArgsParam: A,
                 )
+                interface MyInterface
                 @MyAnnotation(
                     annotationParam = A("1"),
                     annotationArrayParam = [A("3"), A("5"), A("7")],
                     annotationVarArgsParam = [A("9"), A("11"), A("13")],
                 )
-                class MyClass
+                class MyClass :
+                @MyAnnotation(
+                    annotationParam = A("1"),
+                    annotationArrayParam = [A("3"), A("5"), A("7")],
+                    annotationVarArgsParam = [A("9"), A("11"), A("13")],
+                )
+                MyInterface
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
@@ -1263,10 +1447,7 @@
                 }
             }
 
-            val annotation = invocation.processingEnv.requireTypeElement("test.MyClass")
-                .getAllAnnotations()
-                .single { it.qualifiedName == "test.MyAnnotation" }
-
+            val annotation = getAnnotation(invocation)
             // Compare the AnnotationSpec string ignoring whitespace
             assertThat(annotation.toAnnotationSpec().toString().removeWhiteSpace())
                 .isEqualTo("""
@@ -1292,17 +1473,36 @@
         return this.replace("\\s+".toRegex(), "")
     }
 
+    private fun getAnnotation(invocation: XTestInvocation): XAnnotation {
+        val typeElement = invocation.processingEnv.requireTypeElement("test.MyClass")
+        return if (isTypeAnnotation) {
+            typeElement.superInterfaces.first().getAllAnnotations()
+                .single { it.qualifiedName == "test.MyAnnotation" }
+        } else {
+            typeElement.getAllAnnotations().single { it.qualifiedName == "test.MyAnnotation" }
+        }
+    }
+
     enum class SourceKind { JAVA, KOTLIN }
 
     companion object {
         @JvmStatic
-        @Parameterized.Parameters(name = "isPreCompiled_{0}_sourceKind_{1}")
+        @Parameterized.Parameters(name = "isPreCompiled_{0}_sourceKind_{1}_isTypeAnnotation_{2}")
         fun params(): List<Array<Any>> {
             val isPreCompiledValues = arrayOf(false, true)
             val sourceKindValues = arrayOf(SourceKind.JAVA, SourceKind.KOTLIN)
+            val isTypeAnnotation = arrayOf(false, true)
             return isPreCompiledValues.flatMap { isPreCompiled ->
-                sourceKindValues.map { sourceKind ->
-                    arrayOf(isPreCompiled, sourceKind)
+                sourceKindValues.flatMap { sourceKind ->
+                    isTypeAnnotation.mapNotNull { isTypeAnnotation ->
+                        // We can't see type annotations from precompiled Java classes. Skipping it
+                        // for now: https://github.com/google/ksp/issues/1296
+                        if (isPreCompiled && sourceKind == SourceKind.JAVA && isTypeAnnotation) {
+                            null
+                        } else {
+                            arrayOf(isPreCompiled, sourceKind, isTypeAnnotation)
+                        }
+                    }
                 }
             }
         }
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
index e44db5b..9036fa2 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
@@ -19,6 +19,7 @@
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
+import androidx.room.compiler.processing.javac.JavacType
 import androidx.room.compiler.processing.ksp.jvmDescriptor
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
@@ -255,6 +256,9 @@
                     assertThat(superInterface.typeArguments[0].asTypeName().kotlin)
                         .isEqualTo(KClassName("kotlin", "String"))
                 }
+                if (! invocation.isKsp) {
+                    assertThat((superInterface as JavacType).kotlinType).isNotNull()
+                }
             }
         }
     }
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
index 835cdfd..724c037 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
@@ -24,6 +24,7 @@
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.asJClassName
 import androidx.room.compiler.processing.util.asKClassName
+import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.dumpToString
 import androidx.room.compiler.processing.util.getDeclaredField
 import androidx.room.compiler.processing.util.getDeclaredMethodByJvmName
@@ -1525,4 +1526,115 @@
             it.assertCompilationResult { hasErrorContaining("Unresolved reference: MissingType") }
         }
     }
+
+    @Test
+    fun hasAnnotationWithPackage() {
+        val kotlinSrc = Source.kotlin(
+            "KotlinClass.kt",
+            """
+            package foo.bar
+            interface KotlinInterface
+            open class KotlinBase
+            @Target(AnnotationTarget.TYPE)
+            annotation class KotlinAnnotation {
+                @Target(AnnotationTarget.TYPE)
+                annotation class KotlinNestedAnnotation
+            }
+            class KotlinClass : @KotlinAnnotation.KotlinNestedAnnotation KotlinBase(),
+                    @KotlinAnnotation KotlinInterface {
+                inner class KotlinInner : @KotlinAnnotation KotlinInterface
+                class KotlinNested : @KotlinAnnotation KotlinInterface
+            }
+            """.trimIndent()
+        )
+        // KSP can't read nested annotations in Java sources if the filename does not match
+        // the outer class.
+        val javaAnnotationSource = Source.java(
+            "foo.bar.JavaAnnotation",
+            """
+            package foo.bar;
+            import java.lang.annotation.ElementType;
+            import java.lang.annotation.Target;
+            @Target(ElementType.TYPE_USE)
+            @interface JavaAnnotation {
+                @Target(ElementType.TYPE_USE)
+                @interface JavaNestedAnnotation {}
+            }
+            """.trimIndent()
+        )
+        val javaSrc = Source.java(
+            "foo.bar.JavaClass",
+            """
+            package foo.bar;
+            interface JavaInterface {}
+            class JavaBase {}
+            class JavaClass extends @JavaAnnotation.JavaNestedAnnotation JavaBase
+                implements @JavaAnnotation JavaInterface {}
+            """.trimIndent()
+        )
+        fun checkKotlin(invocation: XTestInvocation) {
+            val kotlinTypeElement = invocation.processingEnv.requireTypeElement(
+                "foo.bar.KotlinClass")
+            kotlinTypeElement.superInterfaces.single().let {
+                assertThat(it.getAllAnnotations().single().typeElement.packageName)
+                        .isEqualTo("foo.bar")
+                assertThat(it.getAllAnnotations().single().typeElement.qualifiedName)
+                    .isEqualTo("foo.bar.KotlinAnnotation")
+
+                assertThat(it.hasAnnotationWithPackage("foo.bar.KotlinAnnotation")).isFalse()
+                assertThat(it.hasAnnotationWithPackage("foo.bar")).isTrue()
+                assertThat(it.hasAnnotationWithPackage("foo")).isFalse()
+            }
+            kotlinTypeElement.superClass!!.let {
+                assertThat(it.getAllAnnotations().single().typeElement.packageName)
+                    .isEqualTo("foo.bar")
+                assertThat(it.getAllAnnotations().single().typeElement.qualifiedName)
+                    .isEqualTo("foo.bar.KotlinAnnotation.KotlinNestedAnnotation")
+
+                assertThat(it.getAllAnnotations().single().typeElement.packageName)
+                    .isEqualTo("foo.bar")
+                assertThat(it.getAllAnnotations().single().typeElement.qualifiedName)
+                    .isEqualTo("foo.bar.KotlinAnnotation.KotlinNestedAnnotation")
+            }
+        }
+        fun checkJava(invocation: XTestInvocation) {
+            val javaTypeElement = invocation.processingEnv.requireTypeElement(
+                "foo.bar.JavaClass")
+            javaTypeElement.superInterfaces.first().let {
+                assertThat(it.getAllAnnotations().single().typeElement.packageName)
+                    .isEqualTo("foo.bar")
+                assertThat(it.getAllAnnotations().single().typeElement.qualifiedName)
+                    .isEqualTo("foo.bar.JavaAnnotation")
+
+                assertThat(it.hasAnnotationWithPackage("foo.bar.JavaClass")).isFalse()
+                assertThat(it.hasAnnotationWithPackage("foo.bar")).isTrue()
+                assertThat(it.hasAnnotationWithPackage("foo")).isFalse()
+            }
+            javaTypeElement.superClass!!.let {
+                assertThat(it.getAllAnnotations().single().typeElement.packageName)
+                    .isEqualTo("foo.bar")
+                assertThat(it.getAllAnnotations().single().typeElement.qualifiedName)
+                    .isEqualTo("foo.bar.JavaAnnotation.JavaNestedAnnotation")
+
+                assertThat(it.hasAnnotationWithPackage("foo.bar.JavaClass")).isFalse()
+                assertThat(it.hasAnnotationWithPackage("foo.bar")).isTrue()
+                assertThat(it.hasAnnotationWithPackage("foo")).isFalse()
+            }
+        }
+        runProcessorTest(
+            sources = listOf(kotlinSrc, javaAnnotationSource, javaSrc),
+            handler = {
+                checkKotlin(it)
+                checkJava(it)
+            }
+        )
+        runProcessorTest(
+            classpath = compileFiles(listOf(kotlinSrc)),
+            handler = {
+                // We can't see type annotations from precompiled Java classes. Skipping it
+                // for now: https://github.com/google/ksp/issues/1296
+                checkKotlin(it)
+            }
+        )
+    }
 }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt
index 7d67afd..e5efa51 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt
@@ -141,14 +141,45 @@
         }
     }
 
+    @Test
+    fun interfaceDao_private() {
+        val source = Source.kotlin(
+            "Foo.kt",
+            """
+            import androidx.room.*
+            @Dao
+            interface SubjectDao {
+                private fun upsert() {
+                    TODO("")
+                }
+
+                private suspend fun suspendUpsert() {
+                    TODO("")
+                }
+            }
+            """.trimIndent()
+        )
+        compileInEachDefaultsMode(
+            source = source,
+            jvmTarget = "11" // private functions in interface require target jvm 9+
+        ) {}
+    }
+
     private fun compileInEachDefaultsMode(
         source: Source,
+        jvmTarget: String = "1.8",
         handler: (StringSubject) -> Unit
     ) {
         // TODO should run these with KSP as well. https://github.com/google/ksp/issues/627
         runKaptTest(
             sources = listOf(source, COMMON.COROUTINES_ROOM, COMMON.ROOM_DATABASE_KTX),
-            kotlincArguments = listOf("-Xjvm-default=${jvmDefaultMode.description}")
+            javacArguments = listOf(
+                "-source", jvmTarget
+            ),
+            kotlincArguments = listOf(
+                "-jvm-target=$jvmTarget",
+                "-Xjvm-default=${jvmDefaultMode.description}"
+            )
         ) { invocation ->
             invocation.roundEnv
                 .getElementsAnnotatedWith(
diff --git a/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt b/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt
index 57e13f0..4ddc81c 100644
--- a/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt
+++ b/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt
@@ -64,9 +64,7 @@
         }
         // If the call is within an SDK_INT check, then its OK
         if (
-            @Suppress("DEPRECATION") // b/262915639
             VersionChecks.isWithinVersionCheckConditional(context, node, 16) ||
-            @Suppress("DEPRECATION") // b/262915639
             VersionChecks.isPrecededByVersionCheckExit(context, node, 16)
         ) {
             return
diff --git a/room/room-runtime-lint/src/main/java/androidx/room/lint/RoomIssueRegistry.kt b/room/room-runtime-lint/src/main/java/androidx/room/lint/RoomIssueRegistry.kt
index daedba0..577b802 100644
--- a/room/room-runtime-lint/src/main/java/androidx/room/lint/RoomIssueRegistry.kt
+++ b/room/room-runtime-lint/src/main/java/androidx/room/lint/RoomIssueRegistry.kt
@@ -23,7 +23,7 @@
 
 class RoomIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues: List<Issue> = listOf(
         CursorKotlinUseIssueDetector.ISSUE,
     )
diff --git a/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java b/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java
index 9ecf09b..1a7bd69f 100644
--- a/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java
+++ b/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedFile.java
@@ -143,6 +143,10 @@
         /**
          * Builder for an EncryptedFile.
          *
+         * <p>If the <code>masterKeyAlias</code> used here is for a key that is not yet
+         * created, this method will not be thread safe. Use the alternate signature that is not
+         * deprecated for multi-threaded contexts.
+         *
          * @deprecated Use {@link #Builder(Context, File, MasterKey, FileEncryptionScheme)} instead.
          */
         @Deprecated
diff --git a/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedSharedPreferences.java b/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedSharedPreferences.java
index 2060e40..d974cd37 100644
--- a/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedSharedPreferences.java
+++ b/security/security-crypto/src/main/java/androidx/security/crypto/EncryptedSharedPreferences.java
@@ -134,6 +134,12 @@
     /**
      * Opens an instance of encrypted SharedPreferences
      *
+     * <p>If the <code>masterKeyAlias</code> used here is for a key that is not yet created, this
+     * method will not be thread safe. Use the alternate signature that is not deprecated for
+     * multi-threaded contexts.
+     *
+     * @deprecated Use {@link #create(Context, String, MasterKey,
+     * PrefKeyEncryptionScheme, PrefValueEncryptionScheme)} instead.
      * @param fileName                  The name of the file to open; can not contain path
      *                                  separators.
      * @param masterKeyAlias            The alias of the master key to use.
@@ -143,8 +149,6 @@
      * @return The SharedPreferences instance that encrypts all data.
      * @throws GeneralSecurityException when a bad master key or keyset has been attempted
      * @throws IOException              when fileName can not be used
-     * @deprecated Use {@link #create(Context, String, MasterKey,
-     * PrefKeyEncryptionScheme, PrefValueEncryptionScheme)} instead.
      */
     @Deprecated
     @NonNull
diff --git a/settings.gradle b/settings.gradle
index 2449093..e4063e7 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -985,20 +985,20 @@
 includeProject(":wear:watchface:watchface-style-old-api-test-stub", "wear/watchface/watchface-style/old-api-test-stub", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":webkit:integration-tests:testapp", [BuildType.MAIN])
 includeProject(":webkit:webkit", [BuildType.MAIN])
-includeProject(":window:window", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:window-samples", "window/window/samples", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:extensions:extensions", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:extensions:core:core", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:integration-tests:configuration-change-tests", [BuildType.MAIN])
-includeProject(":window:sidecar:sidecar", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:window-java", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:window-core", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:window-rxjava2", [BuildType.MAIN])
-includeProject(":window:window-rxjava3", [BuildType.MAIN])
-includeProject(":window:window-demos:demo", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:window-demos:demo-common", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:window-demos:demo-second-app", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
-includeProject(":window:window-testing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA])
+includeProject(":window:window", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:window-samples", "window/window/samples", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:extensions:extensions", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:extensions:core:core", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:integration-tests:configuration-change-tests", [BuildType.MAIN, BuildType.WINDOW])
+includeProject(":window:sidecar:sidecar", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:window-java", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:window-core", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:window-rxjava2", [BuildType.MAIN, BuildType.WINDOW])
+includeProject(":window:window-rxjava3", [BuildType.MAIN, BuildType.WINDOW])
+includeProject(":window:window-demos:demo", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:window-demos:demo-common", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:window-demos:demo-second-app", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
+includeProject(":window:window-testing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.CAMERA, BuildType.WINDOW])
 includeProject(":work:integration-tests:testapp", [BuildType.MAIN])
 includeProject(":work:work-benchmark", [BuildType.MAIN])
 includeProject(":work:work-gcm", [BuildType.MAIN])
@@ -1030,7 +1030,7 @@
 // Note: don't add new samples/ apps. Instead, Create
 // <module>/integration-tests/testapp in the "Libraries" section above.
 includeProject(":androidx-demos", new File(samplesRoot, "AndroidXDemos"), [BuildType.MAIN])
-includeProject(":media-routing-demo", new File(samplesRoot, "MediaRoutingDemo"), [BuildType.MAIN])
+includeProject(":media-routing-demo", new File(samplesRoot, "MediaRoutingDemo"), [BuildType.MAIN, BuildType.MEDIA])
 includeProject(":support-animation-demos", new File(samplesRoot, "SupportAnimationDemos"), [BuildType.MAIN])
 includeProject(":support-content-demos", new File(samplesRoot, "SupportContentDemos"), [BuildType.MAIN])
 includeProject(":support-emoji-demos", new File(samplesRoot, "SupportEmojiDemos"), [BuildType.MAIN])
diff --git a/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/StartupRuntimeIssueRegistry.kt b/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/StartupRuntimeIssueRegistry.kt
index fad6e87..84f5620 100644
--- a/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/StartupRuntimeIssueRegistry.kt
+++ b/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/StartupRuntimeIssueRegistry.kt
@@ -28,7 +28,7 @@
  */
 class StartupRuntimeIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues: List<Issue>
         get() = listOf(
             InitializerConstructorDetector.ISSUE,
diff --git a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt
index b255881..3a3c4f6 100644
--- a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt
+++ b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt
@@ -519,4 +519,36 @@
                 }
             }
     }
+
+    /**
+     * @deprecated You probably meant to call [containsNoneOf] instead.
+     */
+    @Deprecated(
+        message = "You probably meant to call containsNoneOf instead.",
+        replaceWith = ReplaceWith(expression = "containsNoneOf"),
+    )
+    override fun isNoneOf(first: Any?, second: Any?, vararg rest: Any?) {
+        super.isNoneOf(first, second, *rest)
+    }
+
+    @Deprecated(
+        message = "You probably meant to call containsNoneIn instead.",
+        replaceWith = ReplaceWith(expression = "containsNoneIn"),
+    )
+    override fun isNotIn(iterable: Iterable<*>?) {
+        super.isNotIn(iterable)
+
+        requireNonNull(iterable)
+
+        val nonIterables = iterable.filterNot { it is Iterable<*> }
+        if (nonIterables.isNotEmpty()) {
+            fail(
+                "The actual value is an Iterable, and you've written a test that compares it to " +
+                    "some objects that are not Iterables. Did you instead mean to check " +
+                    "whether its *contents* match any of the *contents* of the given values? " +
+                    "If so, call containsNoneOf(...)/containsNoneIn(...) instead. " +
+                    "Non-iterables: $nonIterables"
+            )
+        }
+    }
 }
diff --git a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Subject.kt b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Subject.kt
index 346a81d..8c5c948 100644
--- a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Subject.kt
+++ b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Subject.kt
@@ -18,6 +18,7 @@
 
 import kotlin.test.assertIs
 import kotlin.test.assertTrue
+import kotlin.test.fail
 
 // As opposed to Truth, which limits visibility on `actual` and the generic type, we purposely make
 // them visible in Kruth to allow for an easier time extending in Kotlin.
@@ -68,6 +69,30 @@
      * Fails if the subject is not an instance of the given class.
      */
     inline fun <reified V> isInstanceOf() = assertIs<V>(actual)
+
+    /** Fails unless the subject is equal to any element in the given [iterable]. */
+    open fun isIn(iterable: Iterable<*>?) {
+        if (actual !in requireNonNull(iterable)) {
+            fail("Expected $actual to be in $iterable, but was not")
+        }
+    }
+
+    /** Fails unless the subject is equal to any of the given elements. */
+    open fun isAnyOf(first: Any?, second: Any?, vararg rest: Any?) {
+        isIn(listOf(first, second, *rest))
+    }
+
+    /** Fails if the subject is equal to any element in the given [iterable]. */
+    open fun isNotIn(iterable: Iterable<*>?) {
+        if (actual in requireNonNull(iterable)) {
+            fail("Expected $actual not to be in $iterable, but it was")
+        }
+    }
+
+    /** Fails if the subject is equal to any of the given elements.  */
+    open fun isNoneOf(first: Any?, second: Any?, vararg rest: Any?) {
+        isNotIn(listOf(first, second, *rest))
+    }
 }
 
 private fun Any?.standardIsEqualTo(expected: Any?) {
diff --git a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/IterableSubjectTest.kt b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/IterableSubjectTest.kt
index e08ecda..fd3cd7e 100644
--- a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/IterableSubjectTest.kt
+++ b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/IterableSubjectTest.kt
@@ -1000,70 +1000,52 @@
         }
     }
 
-//
-//    private class Foo private constructor(val x: Int)
-//
-//    private class Bar(x: Int) : Foo(x)
-//
-//    private val FOO_COMPARATOR: Comparator<Foo> = object : Comparator<Foo?>() {
-//        fun compare(a: Foo, b: Foo): Int {
-//            return if (a.x < b.x) -1 else if (a.x > b.x) 1 else 0
-//        }
-//    }
-//
-//    @Test
-//    fun iterableOrderedByBaseClassComparator() {
-//        val targetList: Iterable<Bar> = listOf(Bar(1), Bar(2), Bar(3))
-//        assertThat(targetList).isInOrder(FOO_COMPARATOR)
-//        assertThat(targetList).isInStrictOrder(FOO_COMPARATOR)
-//    }
-//
-//    @Test
-//    fun isIn() {
-//        val actual: ImmutableList<String> = listOf("a")
-//        val expectedA: ImmutableList<String> = listOf("a")
-//        val expectedB: ImmutableList<String> = listOf("b")
-//        val expected: ImmutableList<ImmutableList<String>> = listOf(expectedA, expectedB)
-//        assertThat(actual).isIn(expected)
-//    }
-//
-//    @Test
-//    fun isNotIn() {
-//        val actual: ImmutableList<String> = listOf("a")
-//        assertThat(actual).isNotIn(listOf(listOf("b"), listOf("c")))
-//        expectFailureWhenTestingThat(actual).isNotIn(listOf("a", "b"))
-//        assertThat(expectFailure.getFailure())
-//            .hasMessageThat()
-//            .isEqualTo(
-//                "The actual value is an Iterable, and you've written a test that compares it to some "
-//                    + "objects that are not Iterables. Did you instead mean to check whether its "
-//                    + "*contents* match any of the *contents* of the given values? If so, call "
-//                    + "containsNoneOf(...)/containsNoneIn(...) instead. Non-iterables: [a, b]"
-//            )
-//    }
-//
-//    @Test
-//    fun isAnyOf() {
-//        val actual: ImmutableList<String> = listOf("a")
-//        val expectedA: ImmutableList<String> = listOf("a")
-//        val expectedB: ImmutableList<String> = listOf("b")
-//        assertThat(actual).isAnyOf(expectedA, expectedB)
-//    }
-//
-//    @Test
-//    fun isNoneOf() {
-//        val actual: ImmutableList<String> = listOf("a")
-//        assertThat(actual).isNoneOf(listOf("b"), listOf("c"))
-//        expectFailureWhenTestingThat(actual).isNoneOf("a", "b")
-//        assertThat(expectFailure.getFailure())
-//            .hasMessageThat()
-//            .isEqualTo(
-//                ("The actual value is an Iterable, and you've written a test that compares it to some "
-//                    + "objects that are not Iterables. Did you instead mean to check whether its "
-//                    + "*contents* match any of the *contents* of the given values? If so, call "
-//                    + "containsNoneOf(...)/containsNoneIn(...) instead. Non-iterables: [a, b]")
-//            )
-//    }
+    @Test
+    fun iterableOrderedByBaseClassComparator() {
+        val comparator = compareBy<Foo> { it.x }
+        val targetList: Iterable<Bar> = listOf(Bar(1), Bar(2), Bar(3))
+        assertThat(targetList).isInOrder(comparator)
+        assertThat(targetList).isInStrictOrder(comparator)
+    }
+
+    @Test
+    fun isIn() {
+        val actual = listOf("a")
+        val expectedA = listOf("a")
+        val expectedB = listOf("b")
+        val expected = listOf(expectedA, expectedB)
+        assertThat(actual).isIn(expected)
+    }
+
+    @Suppress("DEPRECATION") // Testing a deprecated method
+    @Test
+    fun isNotIn() {
+        val actual = listOf("a")
+        assertThat(actual).isNotIn(listOf(listOf("b"), listOf("c")))
+
+        assertFailsWith<AssertionError> {
+            assertThat(actual).isNotIn(listOf("a", "b"))
+        }
+    }
+
+    @Test
+    fun isAnyOf() {
+        val actual = listOf("a")
+        val expectedA = listOf("a")
+        val expectedB = listOf("b")
+        assertThat(actual).isAnyOf(expectedA, expectedB)
+    }
+
+    @Suppress("DEPRECATION") // Testing a deprecated method
+    @Test
+    fun isNoneOf() {
+        val actual = listOf("a")
+        assertThat(actual).isNoneOf(listOf("b"), listOf("c"))
+
+        assertFailsWith<AssertionError> {
+            assertThat(actual).isNoneOf("a", "b")
+        }
+    }
 
     private companion object {
         private val COMPARE_AS_DECIMAL: Comparator<String?> =
@@ -1088,4 +1070,8 @@
 
         override fun toString(): String = "HCT"
     }
+
+    private open class Foo(val x: Int)
+
+    private class Bar(x: Int) : Foo(x)
 }
diff --git a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/SubjectTest.kt b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/SubjectTest.kt
index fed8784..c2d784c 100644
--- a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/SubjectTest.kt
+++ b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/SubjectTest.kt
@@ -153,6 +153,142 @@
             assertThat(StringBuilder("foo")).isEqualTo(StringBuilder("foo"))
         }
     }
+
+    @Test
+    fun isIn() {
+        assertThat("b").isIn(oneShotIterable("a", "b", "c"))
+    }
+
+    @Test
+    fun isInJustTwo() {
+        assertThat("b").isIn(oneShotIterable("a", "b"))
+    }
+
+    @Test
+    fun isInFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat("x").isIn(oneShotIterable("a", "b", "c"))
+        }
+    }
+
+    @Test
+    fun isInNullInListWithNull() {
+        assertThat(null as String?).isIn(oneShotIterable("a", "b", null as String?))
+    }
+
+    @Test
+    fun isInNonnullInListWithNull() {
+        assertThat("b").isIn(oneShotIterable("a", "b", null as String?))
+    }
+
+    @Test
+    fun isInNullFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat(null as String?).isIn(oneShotIterable("a", "b", "c"))
+        }
+    }
+
+    @Test
+    fun isInEmptyFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat("b").isIn(emptyList<String>())
+        }
+    }
+
+    @Test
+    fun isAnyOf() {
+        assertThat("b").isAnyOf("a", "b", "c")
+    }
+
+    @Test
+    fun isAnyOfJustTwo() {
+        assertThat("b").isAnyOf("a", "b")
+    }
+
+    @Test
+    fun isAnyOfFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat("x").isAnyOf("a", "b", "c")
+        }
+    }
+
+    @Test
+    fun isAnyOfNullInListWithNull() {
+        assertThat(null as String?).isAnyOf("a", "b", null as String?)
+    }
+
+    @Test
+    fun isAnyOfNonnullInListWithNull() {
+        assertThat("b").isAnyOf("a", "b", null as String?)
+    }
+
+    @Test
+    fun isAnyOfNullFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat(null as String?).isAnyOf("a", "b", "c")
+        }
+    }
+
+    @Test
+    fun isNotIn() {
+        assertThat("x").isNotIn(oneShotIterable("a", "b", "c"))
+    }
+
+    @Test
+    fun isNotInFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat("b").isNotIn(oneShotIterable("a", "b", "c"))
+        }
+    }
+
+    @Test
+    fun isNotInNull() {
+        assertThat(null as String?).isNotIn(oneShotIterable("a", "b", "c"))
+    }
+
+    @Test
+    fun isNotInNullFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat(null as String?).isNotIn(oneShotIterable("a", "b", null as String?))
+        }
+    }
+
+    @Test
+    fun isNotInEmpty() {
+        assertThat("b").isNotIn(emptyList<String>())
+    }
+
+    @Test
+    fun isNoneOf() {
+        assertThat("x").isNoneOf("a", "b", "c")
+    }
+
+    @Test
+    fun isNoneOfFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat("b").isNoneOf("a", "b", "c")
+        }
+    }
+
+    @Test
+    fun isNoneOfNull() {
+        assertThat(null as String?).isNoneOf("a", "b", "c")
+    }
+
+    @Test
+    fun isNoneOfNullFailure() {
+        assertFailsWith<AssertionError> {
+            assertThat(null as String?).isNoneOf("a", "b", null as String?)
+        }
+    }
+
+    private fun <T> oneShotIterable(vararg values: T): Iterable<T> =
+        object : Iterable<T> {
+            private val iterator = values.iterator()
+
+            override fun iterator(): Iterator<T> = iterator
+            override fun toString(): String = values.contentToString()
+        }
 }
 
 @Suppress("EqualsOrHashCode")
diff --git a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
index 72776fc..e634a06 100644
--- a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
+++ b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
@@ -25,7 +25,7 @@
 // Concept of version useful e.g. for human-readable error messages, and stable once released.
 // Does not replace the need for a binary verification mechanism (e.g. checksum check).
 // TODO: populate using CMake
-#define VERSION "1.0.0-alpha10"
+#define VERSION "1.0.0-alpha11"
 
 namespace tracing_perfetto {
     void RegisterWithPerfetto() {
diff --git a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
index 7178a50..753b9d8 100644
--- a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
+++ b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
@@ -30,7 +30,7 @@
         init {
             PerfettoNative.loadLib()
         }
-        const val libraryVersion = "1.0.0-alpha10" // TODO: get using reflection
+        const val libraryVersion = "1.0.0-alpha11" // TODO: get using reflection
     }
 
     @Test
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
index 5278ec7..a328d3b 100644
--- a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
@@ -25,12 +25,12 @@
 
     // TODO(224510255): load from a file produced at build time
     object Metadata {
-        const val version = "1.0.0-alpha10"
+        const val version = "1.0.0-alpha11"
         val checksums = mapOf(
-            "arm64-v8a" to "189348f277f588ff41f51b4284bf0568bf3d0eab786f6664f8d66847694e0674",
-            "armeabi-v7a" to "9550b32340d790d58fe069b3882815e3d2b20474aa634f01e448392e898cc95b",
-            "x86" to "07967aaad711d16f35f509783f56139903f28f661ebb0415522c10fc0453810f",
-            "x86_64" to "6b2f4129cb1e52d9c9dca5b89d575c7b2a905670da2e0474917d37223f0c8bf5",
+            "arm64-v8a" to "7b593d218cd0d2938b527779f2797e87ddb7d6c042cc5bf1f12543f103a9c291",
+            "armeabi-v7a" to "5c19ff0e61035b7dbdc450642e16761a8948f588ee523adfc329e10f854499b4",
+            "x86" to "2544cdb37d037b5c9976a55d032712c4642a92d1eab22210f9e2831a5df6531a",
+            "x86_64" to "5214e2a413835b2b7328055f50399aa8ae1be28b63a030193003406bf441ac61",
         )
     }
 
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPinnableContainerTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPinnableContainerTest.kt
index 98ba1e9..53c3a19 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPinnableContainerTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPinnableContainerTest.kt
@@ -38,6 +38,7 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.runBlocking
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 
@@ -250,6 +251,7 @@
             .assertIsNotPlaced()
     }
 
+    @Ignore // b/268720713
     @Test
     fun pinnedItemIsStillPinnedWhenReorderedAndNotVisibleAnymore() {
         val state = TvLazyListState()
diff --git a/viewpager2/integration-tests/testapp/OWNERS b/viewpager2/integration-tests/testapp/OWNERS
index b0972b6c..859a7b9 100644
--- a/viewpager2/integration-tests/testapp/OWNERS
+++ b/viewpager2/integration-tests/testapp/OWNERS
@@ -1,2 +1,2 @@
-# Bug components: 607924
+# Bug component: 607924
 [email protected]
\ No newline at end of file
diff --git a/wear/compose/compose-material/api/current.txt b/wear/compose/compose-material/api/current.txt
index fca0d12..7a338f6 100644
--- a/wear/compose/compose-material/api/current.txt
+++ b/wear/compose/compose-material/api/current.txt
@@ -280,7 +280,7 @@
   }
 
   public final class PickerGroupKt {
-    method @androidx.compose.runtime.Composable public static void PickerGroup(androidx.wear.compose.material.PickerGroupItem![] pickers, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material.PickerGroupState pickerGroupState, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onSelected, optional boolean autoCenter, optional androidx.wear.compose.material.TouchExplorationStateProvider touchExplorationStateProvider, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? separator);
+    method @androidx.compose.runtime.Composable public static void PickerGroup(androidx.wear.compose.material.PickerGroupItem![] pickers, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material.PickerGroupState pickerGroupState, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onSelected, optional boolean autoCenter, optional boolean propagateMinConstraints, optional androidx.wear.compose.material.TouchExplorationStateProvider touchExplorationStateProvider, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? separator);
     method @androidx.compose.runtime.Composable public static androidx.wear.compose.material.PickerGroupState rememberPickerGroupState(optional int initiallySelectedIndex);
   }
 
diff --git a/wear/compose/compose-material/api/public_plus_experimental_current.txt b/wear/compose/compose-material/api/public_plus_experimental_current.txt
index 863b8a2..0c19e30 100644
--- a/wear/compose/compose-material/api/public_plus_experimental_current.txt
+++ b/wear/compose/compose-material/api/public_plus_experimental_current.txt
@@ -296,7 +296,7 @@
   }
 
   public final class PickerGroupKt {
-    method @androidx.compose.runtime.Composable public static void PickerGroup(androidx.wear.compose.material.PickerGroupItem![] pickers, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material.PickerGroupState pickerGroupState, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onSelected, optional boolean autoCenter, optional androidx.wear.compose.material.TouchExplorationStateProvider touchExplorationStateProvider, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? separator);
+    method @androidx.compose.runtime.Composable public static void PickerGroup(androidx.wear.compose.material.PickerGroupItem![] pickers, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material.PickerGroupState pickerGroupState, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onSelected, optional boolean autoCenter, optional boolean propagateMinConstraints, optional androidx.wear.compose.material.TouchExplorationStateProvider touchExplorationStateProvider, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? separator);
     method @androidx.compose.runtime.Composable public static androidx.wear.compose.material.PickerGroupState rememberPickerGroupState(optional int initiallySelectedIndex);
   }
 
diff --git a/wear/compose/compose-material/api/restricted_current.txt b/wear/compose/compose-material/api/restricted_current.txt
index fca0d12..7a338f6 100644
--- a/wear/compose/compose-material/api/restricted_current.txt
+++ b/wear/compose/compose-material/api/restricted_current.txt
@@ -280,7 +280,7 @@
   }
 
   public final class PickerGroupKt {
-    method @androidx.compose.runtime.Composable public static void PickerGroup(androidx.wear.compose.material.PickerGroupItem![] pickers, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material.PickerGroupState pickerGroupState, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onSelected, optional boolean autoCenter, optional androidx.wear.compose.material.TouchExplorationStateProvider touchExplorationStateProvider, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? separator);
+    method @androidx.compose.runtime.Composable public static void PickerGroup(androidx.wear.compose.material.PickerGroupItem![] pickers, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material.PickerGroupState pickerGroupState, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onSelected, optional boolean autoCenter, optional boolean propagateMinConstraints, optional androidx.wear.compose.material.TouchExplorationStateProvider touchExplorationStateProvider, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? separator);
     method @androidx.compose.runtime.Composable public static androidx.wear.compose.material.PickerGroupState rememberPickerGroupState(optional int initiallySelectedIndex);
   }
 
diff --git a/wear/compose/compose-material/samples/build.gradle b/wear/compose/compose-material/samples/build.gradle
index fc8c8f3..4eddd5f 100644
--- a/wear/compose/compose-material/samples/build.gradle
+++ b/wear/compose/compose-material/samples/build.gradle
@@ -60,3 +60,13 @@
     inceptionYear = "2021"
     description = "Contains the sample code for the Android Wear Compose Material Classes"
 }
+
+// Workaround for https://github.com/gradle/gradle/issues/19882
+configurations.all {
+    resolutionStrategy.dependencySubstitution {
+        substitute(module("androidx.lifecycle:lifecycle-viewmodel-ktx:")).
+                using project(":lifecycle:lifecycle-viewmodel-ktx")
+        substitute(module("androidx.lifecycle:lifecycle-runtime-ktx:")).
+                using project(":lifecycle:lifecycle-runtime-ktx")
+    }
+}
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/HorizontalPageIndicator.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/HorizontalPageIndicator.kt
index f73c371..08dd5cc 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/HorizontalPageIndicator.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/HorizontalPageIndicator.kt
@@ -272,9 +272,7 @@
         modifier = modifier,
         // 90 degrees equals to 6 o'clock position, at the bottom of the screen
         anchor = 90f,
-        // Since Swipe to dismiss is always LtR, we want to follow the same direction when
-        // navigating amongst pages, so the first page is always on the left.
-        angularDirection = CurvedDirection.Angular.CounterClockwise
+        angularDirection = CurvedDirection.Angular.Reversed
     ) {
         // drawing 1 extra spacer for transition
         curvedComposable {
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt
index a6f1306..845c4685 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt
@@ -37,6 +37,7 @@
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.ParentDataModifier
 import androidx.compose.ui.layout.Placeable
+import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.wear.compose.foundation.HierarchicalFocusCoordinator
 import androidx.wear.compose.foundation.rememberActiveFocusRequester
@@ -64,6 +65,7 @@
  * recommended to set this as true when all the pickers cannot be fit into the screen. Or provide a
  * mechanism to navigate to pickers which are not visible on screen. If false, the whole row
  * containing pickers would be centered.
+ * @param propagateMinConstraints Whether the incoming min constraints should be passed to content.
  * @param touchExplorationStateProvider A [TouchExplorationStateProvider] to provide the current
  * state of touch exploration service. This will be used to determine how the PickerGroup and
  * talkback focus behaves/reacts to click and scroll events.
@@ -78,18 +80,21 @@
     pickerGroupState: PickerGroupState = rememberPickerGroupState(),
     onSelected: (selectedIndex: Int) -> Unit = {},
     autoCenter: Boolean = true,
+    propagateMinConstraints: Boolean = false,
     touchExplorationStateProvider: TouchExplorationStateProvider =
         DefaultTouchExplorationStateProvider(),
     separator: (@Composable (Int) -> Unit)? = null
 ) {
     val touchExplorationServicesEnabled by touchExplorationStateProvider.touchExplorationState()
+
     AutoCenteringRow(
         modifier = modifier
             .then(
                 // When touch exploration services are enabled, send the scroll events on the parent
                 // composable to selected picker
                 if (touchExplorationServicesEnabled &&
-                    pickerGroupState.selectedIndex in pickers.indices) {
+                    pickerGroupState.selectedIndex in pickers.indices
+                ) {
                     Modifier.scrollablePicker(
                         pickers[pickerGroupState.selectedIndex].pickerState
                     )
@@ -97,6 +102,7 @@
                     Modifier
                 }
             ),
+        propagateMinConstraints = propagateMinConstraints
     ) {
         pickers.forEachIndexed { index, pickerData ->
             val pickerSelected = index == pickerGroupState.selectedIndex
@@ -235,17 +241,23 @@
 @Composable
 private fun AutoCenteringRow(
     modifier: Modifier = Modifier,
+    propagateMinConstraints: Boolean,
     content: @Composable () -> Unit
 ) {
-    Layout(modifier = modifier, content = content) { measurables, constraints ->
+    Layout(modifier = modifier, content = content) { measurables, parentConstraints ->
+        // Reset the min width and height of the constraints used to measure child composables
+        // if min constraints are not supposed to propagated.
+        val constraints = if (propagateMinConstraints) {
+            parentConstraints
+        } else {
+            parentConstraints.copy(minWidth = 0, minHeight = 0)
+        }
         val placeables = measurables.map { it.measure(constraints) }
         val centeringOffset = computeCenteringOffset(placeables)
         val rowWidth =
             if (constraints.hasBoundedWidth) constraints.maxWidth
             else constraints.minWidth
-        val rowHeight =
-            if (constraints.hasBoundedHeight) constraints.maxHeight
-            else constraints.minHeight
+        val rowHeight = calculateHeight(constraints, placeables)
         layout(width = rowWidth, height = rowHeight) {
             var x = rowWidth / 2f - centeringOffset
             placeables.forEach {
@@ -290,6 +302,16 @@
     return sumWidth / 2
 }
 
+/**
+ * Calculates the height of the [AutoCenteringRow] from the given [Placeable]s and [Constraints]. It
+ * is calculated based on the max height of all the [Placeable]s and the height passed from the
+ * [Constraints].
+ */
+private fun calculateHeight(constraints: Constraints, placeables: List<Placeable>): Int {
+    val maxChildrenHeight = placeables.maxOf { it.height }
+    return maxChildrenHeight.coerceIn(constraints.minHeight, constraints.maxHeight)
+}
+
 @Suppress("ModifierInspectorInfo")
 internal fun Modifier.autoCenteringTarget() = this.then(
     object : ParentDataModifier {
diff --git a/wear/compose/compose-material3/samples/build.gradle b/wear/compose/compose-material3/samples/build.gradle
index 8f54238..10c22e1 100644
--- a/wear/compose/compose-material3/samples/build.gradle
+++ b/wear/compose/compose-material3/samples/build.gradle
@@ -59,3 +59,13 @@
     inceptionYear = "2022"
     description = "Contains the sample code for the Android Wear Compose Material 3 Classes"
 }
+
+// Workaround for https://github.com/gradle/gradle/issues/19882
+configurations.all {
+    resolutionStrategy.dependencySubstitution {
+        substitute(module("androidx.lifecycle:lifecycle-viewmodel-ktx:")).
+                using project(":lifecycle:lifecycle-viewmodel-ktx")
+        substitute(module("androidx.lifecycle:lifecycle-runtime-ktx:")).
+                using project(":lifecycle:lifecycle-runtime-ktx")
+    }
+}
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
index 9e68e8f..def1922 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
@@ -135,9 +135,9 @@
         // When the time picker loads, none of the individual pickers are selected in talkback mode,
         // otherwise hours picker should be focused.
         val pickerGroupState = if (touchExplorationServicesEnabled) {
-            rememberPickerGroupState(-1)
+            rememberPickerGroupState(FocusableElementsTimePicker.NONE.index)
         } else {
-            rememberPickerGroupState(0)
+            rememberPickerGroupState(FocusableElementsTimePicker.HOURS.index)
         }
         val textStyle = MaterialTheme.typography.display3
         val optionColor = MaterialTheme.colors.secondary
@@ -159,13 +159,14 @@
                 createDescription(pickerGroupState, secondState.selectedOption, "seconds")
             }
         }
-        val onPickerSelected = { selectedPicker: Int ->
-            if (pickerGroupState.selectedIndex != selectedPicker) {
-                pickerGroupState.selectedIndex = selectedPicker
-            } else if (selectedPicker > 2) {
+        val onPickerSelected = { curr: FocusableElementsTimePicker,
+            next: FocusableElementsTimePicker ->
+            if (pickerGroupState.selectedIndex != curr.index) {
+                pickerGroupState.selectedIndex = curr.index
+            } else if (next == FocusableElementsTimePicker.CONFIRM_BUTTON) {
                 focusRequesterConfirmButton.requestFocus()
             } else {
-                pickerGroupState.selectedIndex += 1
+                pickerGroupState.selectedIndex = next.index
             }
         }
 
@@ -176,10 +177,10 @@
             ) {
                 Spacer(Modifier.height(12.dp))
                 Text(
-                    text = when (pickerGroupState.selectedIndex) {
-                        0 -> "Hour"
-                        1 -> "Minute"
-                        2 -> "Second"
+                    text = when (FocusableElementsTimePicker[pickerGroupState.selectedIndex]) {
+                        FocusableElementsTimePicker.HOURS -> "Hour"
+                        FocusableElementsTimePicker.MINUTES -> "Minute"
+                        FocusableElementsTimePicker.SECONDS -> "Second"
                         else -> ""
                     },
                     color = optionColor,
@@ -202,7 +203,12 @@
                             pickerState = hourState,
                             modifier = Modifier.size(40.dp, 100.dp),
                             focusRequester = remember { FocusRequester() },
-                            onSelected = { onPickerSelected(0) },
+                            onSelected = {
+                                onPickerSelected(
+                                    FocusableElementsTimePicker.HOURS,
+                                    FocusableElementsTimePicker.MINUTES
+                                )
+                            },
                             contentDescription = hourContentDescription,
                             option = pickerOption
                         ),
@@ -210,7 +216,12 @@
                             pickerState = minuteState,
                             modifier = Modifier.size(40.dp, 100.dp),
                             focusRequester = remember { FocusRequester() },
-                            onSelected = { onPickerSelected(1) },
+                            onSelected = {
+                                onPickerSelected(
+                                    FocusableElementsTimePicker.MINUTES,
+                                    FocusableElementsTimePicker.SECONDS
+                                )
+                            },
                             contentDescription = minuteContentDescription,
                             option = pickerOption
                         ),
@@ -218,7 +229,12 @@
                             pickerState = secondState,
                             modifier = Modifier.size(40.dp, 100.dp),
                             focusRequester = remember { FocusRequester() },
-                            onSelected = { onPickerSelected(2) },
+                            onSelected = {
+                                onPickerSelected(
+                                    FocusableElementsTimePicker.SECONDS,
+                                    FocusableElementsTimePicker.CONFIRM_BUTTON
+                                )
+                            },
                             contentDescription = secondContentDescription,
                             option = pickerOption
                         ),
@@ -304,23 +320,21 @@
         .touchExplorationState()
 
     MaterialTheme(typography = typography) {
-        var focusedElement by remember {
-            mutableStateOf(
-                if (touchExplorationServicesEnabled) FocusableElement12Hour.NONE
-                else FocusableElement12Hour.HOURS
-            )
-        }
+        val pickerGroupState =
+            if (touchExplorationServicesEnabled) {
+                rememberPickerGroupState(FocusableElement12Hour.NONE.index)
+            } else {
+                rememberPickerGroupState(FocusableElement12Hour.HOURS.index)
+            }
         val textStyle = MaterialTheme.typography.display3
-        val focusRequesterHours = remember { FocusRequester() }
-        val focusRequesterMinutes = remember { FocusRequester() }
-        val focusRequesterPeriod = remember { FocusRequester() }
+        val pickerOption = pickerTextOption(textStyle) { "%02d".format(it) }
         val focusRequesterConfirmButton = remember { FocusRequester() }
 
         val hoursContentDescription by remember { derivedStateOf {
-                createDescription12Hour(focusedElement, hourState.selectedOption + 1, "hours")
+                createDescription12Hour(pickerGroupState, hourState.selectedOption + 1, "hours")
             } }
         val minutesContentDescription by remember { derivedStateOf {
-                createDescription12Hour(focusedElement, minuteState.selectedOption, "minutes")
+                createDescription12Hour(pickerGroupState, minuteState.selectedOption, "minutes")
             } }
 
         val amString = remember {
@@ -330,28 +344,13 @@
             LocalTime.of(18, 0).format(DateTimeFormatter.ofPattern("a"))
         }
         val periodContentDescription by remember { derivedStateOf {
-                if (focusedElement == FocusableElement12Hour.NONE)
-                    createDescription12Hour(focusedElement, periodState.selectedOption, "period")
+                if (pickerGroupState.selectedIndex == FocusableElement12Hour.NONE.index)
+                    createDescription12Hour(pickerGroupState, periodState.selectedOption, "period")
                 else if (periodState.selectedOption == 0)
-                    createDescription12Hour(focusedElement, periodState.selectedOption, amString)
-                else createDescription12Hour(focusedElement, periodState.selectedOption, pmString)
+                    createDescription12Hour(pickerGroupState, periodState.selectedOption, amString)
+                else createDescription12Hour(pickerGroupState, periodState.selectedOption, pmString)
             } }
-        Box(
-            modifier = modifier
-                .fillMaxSize()
-                .then(
-                    if (touchExplorationServicesEnabled) {
-                        when (focusedElement) {
-                            FocusableElement12Hour.HOURS -> Modifier.scrollablePicker(hourState)
-                            FocusableElement12Hour.MINUTES -> Modifier.scrollablePicker(minuteState)
-                            FocusableElement12Hour.PERIOD -> Modifier.scrollablePicker(periodState)
-                            else -> Modifier
-                        }
-                    } else {
-                        Modifier
-                    }
-                )
-        ) {
+        Box(modifier = modifier.fillMaxSize()) {
             Column(
                 modifier = modifier.fillMaxSize(),
                 verticalArrangement = Arrangement.Center,
@@ -359,7 +358,7 @@
             ) {
                 Spacer(Modifier.height(12.dp))
                 Text(
-                    text = when (focusedElement) {
+                    text = when (FocusableElement12Hour[pickerGroupState.selectedIndex]) {
                         FocusableElement12Hour.HOURS -> "Hour"
                         FocusableElement12Hour.MINUTES -> "Minute"
                         else -> ""
@@ -368,10 +367,11 @@
                     style = MaterialTheme.typography.button,
                     maxLines = 1,
                 )
+                val weightsToCenterVertically = 0.5f
                 Spacer(
                     Modifier
                         .fillMaxWidth()
-                        .weight(0.5f)
+                        .weight(weightsToCenterVertically)
                 )
                 Row(
                     modifier = Modifier.fillMaxWidth(),
@@ -380,104 +380,79 @@
 
                     ) {
                     val doubleTapToNext =
-                        { position: FocusableElement12Hour, next: FocusableElement12Hour ->
-                            focusedElement = when (focusedElement) {
-                                position -> next
-                                else -> position
+                        { current: FocusableElement12Hour, next: FocusableElement12Hour ->
+                            if (pickerGroupState.selectedIndex != current.index) {
+                                focusRequesterConfirmButton.requestFocus()
+                            } else if (next == FocusableElement12Hour.CONFIRM_BUTTON) {
+                                pickerGroupState.selectedIndex = current.index
+                            } else {
+                                pickerGroupState.selectedIndex = next.index
                             }
                         }
-                    Spacer(Modifier.width(8.dp))
-                    PickerWithRSB(
-                        readOnly = focusedElement != FocusableElement12Hour.HOURS,
-                        state = hourState,
-                        focusRequester = focusRequesterHours,
-                        modifier = Modifier.size(48.dp, 100.dp),
-                        onSelected = {
-                            doubleTapToNext(
-                                FocusableElement12Hour.HOURS,
-                                FocusableElement12Hour.MINUTES
-                            )
-                        },
-                        contentDescription = hoursContentDescription,
-                        userScrollEnabled = !touchExplorationServicesEnabled ||
-                            focusedElement == FocusableElement12Hour.HOURS
-                    ) { hour: Int ->
-                        TimePiece(
-                            selected = focusedElement == FocusableElement12Hour.HOURS,
+                    PickerGroup(
+                        PickerGroupItem(
+                            pickerState = hourState,
+                            modifier = Modifier.size(40.dp, 100.dp),
+                            focusRequester = remember { FocusRequester() },
                             onSelected = {
                                 doubleTapToNext(
                                     FocusableElement12Hour.HOURS,
                                     FocusableElement12Hour.MINUTES
                                 )
                             },
-                            text = "%02d".format(hour + 1),
-                            style = textStyle,
-                            touchExplorationServicesEnabled = touchExplorationServicesEnabled
-                        )
-                    }
-                    Separator(2.dp, textStyle)
-                    PickerWithRSB(
-                        readOnly = focusedElement != FocusableElement12Hour.MINUTES,
-                        state = minuteState,
-                        focusRequester = focusRequesterMinutes,
-                        modifier = Modifier.size(48.dp, 100.dp),
-                        onSelected = {
-                            doubleTapToNext(
-                                FocusableElement12Hour.MINUTES,
-                                FocusableElement12Hour.PERIOD
-                            )
-                        },
-                        contentDescription = minutesContentDescription,
-                        userScrollEnabled = !touchExplorationServicesEnabled ||
-                            focusedElement == FocusableElement12Hour.MINUTES
-                    ) { minute: Int ->
-                        TimePiece(
-                            selected = focusedElement == FocusableElement12Hour.MINUTES,
+                            contentDescription = hoursContentDescription,
+                            option = pickerOption
+                        ),
+                        PickerGroupItem(
+                            pickerState = minuteState,
+                            modifier = Modifier.size(48.dp, 100.dp),
+                            focusRequester = remember { FocusRequester() },
+
                             onSelected = {
                                 doubleTapToNext(
                                     FocusableElement12Hour.MINUTES,
                                     FocusableElement12Hour.PERIOD
                                 )
                             },
-                            text = "%02d".format(minute),
-                            style = textStyle,
-                            touchExplorationServicesEnabled = touchExplorationServicesEnabled
-                        )
-                    }
-                    Spacer(Modifier.width(6.dp))
-                    PickerWithRSB(
-                        readOnly = focusedElement != FocusableElement12Hour.PERIOD,
-                        state = periodState,
-                        focusRequester = focusRequesterPeriod,
-                        modifier = Modifier.size(64.dp, 100.dp),
-                        onSelected = {
-                            doubleTapToNext(
-                                FocusableElement12Hour.PERIOD,
-                                FocusableElement12Hour.CONFIRM_BUTTON
-                            )
-                        },
-                        contentDescription = periodContentDescription,
-                        userScrollEnabled = !touchExplorationServicesEnabled ||
-                            focusedElement == FocusableElement12Hour.PERIOD
-                    ) { period: Int ->
-                        TimePiece(
-                            selected = focusedElement == FocusableElement12Hour.PERIOD,
+                            contentDescription = minutesContentDescription,
+                            option = pickerOption
+                        ),
+                        PickerGroupItem(
+                            pickerState = periodState,
+                            modifier = Modifier.size(64.dp, 100.dp),
+                            focusRequester = remember { FocusRequester() },
+                            contentDescription = periodContentDescription,
                             onSelected = {
                                 doubleTapToNext(
                                     FocusableElement12Hour.PERIOD,
                                     FocusableElement12Hour.CONFIRM_BUTTON
                                 )
                             },
-                            text = if (period == 0) amString else pmString,
-                            style = textStyle,
-                            touchExplorationServicesEnabled = touchExplorationServicesEnabled
-                        )
-                    }
+                            option = { optionIndex: Int, pickerSelected: Boolean ->
+                                Box(modifier = Modifier.fillMaxSize()) {
+                                    Text(
+                                        text = if (optionIndex == 0) amString else pmString,
+                                        maxLines = 1,
+                                        style = textStyle,
+                                        color =
+                                        if (pickerSelected) MaterialTheme.colors.secondary
+                                        else MaterialTheme.colors.onBackground,
+                                        modifier = Modifier
+                                            .align(Alignment.Center)
+                                            .wrapContentSize()
+                                    )
+                                }
+                            }
+                        ),
+                        autoCenter = false,
+                        pickerGroupState = pickerGroupState,
+                        separator = { Separator(6.dp, textStyle) },
+                    )
                 }
                 Spacer(
                     Modifier
                         .fillMaxWidth()
-                        .weight(0.5f)
+                        .weight(weightsToCenterVertically)
                 )
                 Button(onClick = {
                     val confirmedTime = LocalTime.of(
@@ -489,7 +464,8 @@
                 },
                     modifier = Modifier
                         .semantics {
-                            focused = focusedElement == FocusableElement12Hour.CONFIRM_BUTTON
+                            focused = pickerGroupState.selectedIndex ==
+                                FocusableElement12Hour.CONFIRM_BUTTON.index
                         }
                         .focusRequester(focusRequesterConfirmButton)
 
@@ -503,14 +479,6 @@
                     )
                 }
                 Spacer(Modifier.height(8.dp))
-                LaunchedEffect(focusedElement) {
-                    if (focusedElement != FocusableElement12Hour.NONE) {
-                        listOf(
-                            focusRequesterHours, focusRequesterMinutes, focusRequesterPeriod,
-                            focusRequesterConfirmButton
-                        )[focusedElement.index].requestFocus()
-                    }
-                }
             }
         }
     }
@@ -785,14 +753,6 @@
                 }
                 Spacer(Modifier.height(12.dp))
             }
-            LaunchedEffect(focusedElement) {
-                if (focusedElement != FocusableElementDatePicker.NONE) {
-                    listOf(
-                        focusRequesterDay, focusRequesterMonth, focusRequesterYear,
-                        focusRequesterConfirmButton
-                    )[focusedElement.index].requestFocus()
-                }
-            }
         }
     }
 }
@@ -828,6 +788,8 @@
     }
 }
 
+// This is a demo file, suppressing the annotation group error.
+@SuppressLint("NullAnnotationGroup")
 @OptIn(ExperimentalComposeUiApi::class)
 @Composable
 internal fun TimePiece(
@@ -959,21 +921,21 @@
     label: String
 ): String {
     return when (pickerGroupState.selectedIndex) {
-        -1 -> label
+        FocusableElementsTimePicker.NONE.index -> label
         else -> "$selectedValue" + label
     }
 }
 
 private fun createDescription12Hour(
-    focusedElement: FocusableElement12Hour,
+    pickerGroupState: PickerGroupState,
     selectedValue: Int,
     label: String
 ): String {
-    return when (focusedElement) {
-        FocusableElement12Hour.HOURS -> {
+    return when (pickerGroupState.selectedIndex) {
+        FocusableElement12Hour.HOURS.index -> {
             "$selectedValue" + label
         }
-        FocusableElement12Hour.MINUTES -> {
+        FocusableElement12Hour.MINUTES.index -> {
             "$selectedValue" + label
         }
         else -> label
@@ -1161,12 +1123,29 @@
     }
 }
 
+enum class FocusableElementsTimePicker(val index: Int) {
+    HOURS(0),
+    MINUTES(1),
+    SECONDS(2),
+    CONFIRM_BUTTON(3),
+    NONE(-1);
+
+    companion object {
+        private val map = FocusableElementsTimePicker.values().associateBy { it.index }
+        operator fun get(value: Int) = map[value]
+    }
+}
+
 enum class FocusableElement12Hour(val index: Int) {
     HOURS(0),
     MINUTES(1),
     PERIOD(2),
     CONFIRM_BUTTON(3),
-    NONE(-1)
+    NONE(-1);
+    companion object {
+        private val map = FocusableElement12Hour.values().associateBy { it.index }
+        operator fun get(value: Int) = map[value]
+    }
 }
 
 enum class FocusableElementDatePicker(val index: Int) {
@@ -1174,5 +1153,9 @@
     MONTH(1),
     YEAR(2),
     CONFIRM_BUTTON(3),
-    NONE(-1)
+    NONE(-1);
+    companion object {
+        private val map = FocusableElementDatePicker.values().associateBy { it.index }
+        operator fun get(value: Int) = map[value]
+    }
 }
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/current.txt b/wear/protolayout/protolayout-expression-pipeline/api/current.txt
index 6f6c05a..5cd07fa 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/current.txt
@@ -12,6 +12,8 @@
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Float!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Duration!>);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Instant!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Boolean!>);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public void close();
     method @UiThread public void disablePlatformDataSources();
@@ -42,7 +44,7 @@
     method @UiThread public void registerSensorGatewayConsumer(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
     method @UiThread public void registerSensorGatewayConsumer(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
     method @UiThread public void unregisterSensorGatewayConsumer(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
+    field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
     field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
     field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
   }
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
index 6f6c05a..5cd07fa 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
@@ -12,6 +12,8 @@
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Float!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Duration!>);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Instant!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Boolean!>);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public void close();
     method @UiThread public void disablePlatformDataSources();
@@ -42,7 +44,7 @@
     method @UiThread public void registerSensorGatewayConsumer(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
     method @UiThread public void registerSensorGatewayConsumer(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
     method @UiThread public void unregisterSensorGatewayConsumer(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
+    field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
     field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
     field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
   }
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt b/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
index 25399f3..3a48704 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
@@ -12,6 +12,8 @@
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Float!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Duration!>);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Instant!>);
     method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Boolean!>);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public void close();
     method @UiThread public void disablePlatformDataSources();
@@ -46,7 +48,7 @@
     method @UiThread public void registerSensorGatewayConsumer(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
     method @UiThread public void registerSensorGatewayConsumer(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
     method @UiThread public void unregisterSensorGatewayConsumer(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
+    field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
     field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
     field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
   }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
index 54cbc77..1ef366a 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
@@ -101,7 +101,7 @@
                     ValueAnimator.ofArgb(mProtoNode.getFromArgb(), mProtoNode.getToArgb());
             animator.addUpdateListener(a -> mDownstream.onData((Integer) a.getAnimatedValue()));
 
-            applyAnimationSpecToAnimator(animator, mProtoNode.getSpec());
+            applyAnimationSpecToAnimator(animator, mProtoNode.getAnimationSpec());
 
             mQuotaAwareAnimator.updateAnimator(animator);
             startOrSkipAnimator();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DurationNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DurationNodes.java
new file mode 100644
index 0000000..3813bd8
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DurationNodes.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2023 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 androidx.wear.protolayout.expression.pipeline;
+
+import java.time.Duration;
+import java.time.Instant;
+
+/** Dynamic data nodes which yield durations. */
+class DurationNodes {
+    private DurationNodes() {}
+
+    /** Dynamic duration node that gets the duration between two time instants. */
+    static class BetweenInstancesNode
+            extends DynamicDataBiTransformNode<Instant, Instant, Duration> {
+
+        BetweenInstancesNode(DynamicTypeValueReceiver<Duration> downstream) {
+            super(downstream, Duration::between);
+        }
+    }
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
index 2468ae7..2080180 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
@@ -37,6 +37,7 @@
 import androidx.wear.protolayout.expression.pipeline.ColorNodes.DynamicAnimatedColorNode;
 import androidx.wear.protolayout.expression.pipeline.ColorNodes.FixedColorNode;
 import androidx.wear.protolayout.expression.pipeline.ColorNodes.StateColorSourceNode;
+import androidx.wear.protolayout.expression.pipeline.DurationNodes.BetweenInstancesNode;
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.AnimatableFixedFloatNode;
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.ArithmeticFloatNode;
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.DynamicAnimatedFloatNode;
@@ -44,13 +45,15 @@
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.Int32ToFloatNode;
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.StateFloatNode;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.AnimatableFixedInt32Node;
+import androidx.wear.protolayout.expression.pipeline.InstantNodes.FixedInstantNode;
+import androidx.wear.protolayout.expression.pipeline.InstantNodes.PlatformTimeSourceNode;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.ArithmeticInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.DynamicAnimatedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FixedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FloatToInt32Node;
+import androidx.wear.protolayout.expression.pipeline.Int32Nodes.GetDurationPartOpNode;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.PlatformInt32SourceNode;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.StateInt32SourceNode;
-import androidx.wear.protolayout.expression.pipeline.PlatformDataSources.EpochTimePlatformDataSource;
 import androidx.wear.protolayout.expression.pipeline.PlatformDataSources.SensorGatewayPlatformDataSource;
 import androidx.wear.protolayout.expression.pipeline.StringNodes.FixedStringNode;
 import androidx.wear.protolayout.expression.pipeline.StringNodes.FloatFormatNode;
@@ -66,13 +69,17 @@
 import androidx.wear.protolayout.expression.proto.DynamicProto.ConditionalStringOp;
 import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicBool;
 import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicColor;
+import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicDuration;
 import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicFloat;
+import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicInstant;
 import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicInt32;
 import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicString;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedColor;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
 
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
@@ -276,12 +283,6 @@
      * Adds dynamic type from the given {@link DynamicBuilders.DynamicString} for evaluation.
      * Evaluation will start immediately.
      *
-     * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
-     *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param stringSource The given String dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -303,10 +304,6 @@
      *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param stringSource The given String dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -329,12 +326,6 @@
      * Adds dynamic type from the given {@link DynamicBuilders.DynamicInt32} for evaluation.
      * Evaluation will start immediately.
      *
-     * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
-     *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param int32Source The given integer dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -355,10 +346,6 @@
      *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param int32Source The given integer dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -378,10 +365,6 @@
     /**
      * Adds pending expression from the given {@link DynamicInt32} for future evaluation.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with{@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param int32Source The given integer dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -405,12 +388,6 @@
      * Adds dynamic type from the given {@link DynamicBuilders.DynamicFloat} for evaluation.
      * Evaluation will start immediately.
      *
-     * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
-     *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param floatSource The given float dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -431,10 +408,6 @@
      *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param floatSource The given float dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -459,10 +432,6 @@
      *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param floatSource The given float dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -482,12 +451,6 @@
      * Adds dynamic type from the given {@link DynamicBuilders.DynamicColor} for evaluation.
      * Evaluation will start immediately.
      *
-     * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
-     *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param colorSource The given color dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -508,10 +471,6 @@
      *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param colorSource The given color dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -533,10 +492,6 @@
      *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param colorSource The given color dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -557,14 +512,86 @@
     }
 
     /**
-     * Adds dynamic type from the given {@link DynamicBuilders.DynamicBool} for evaluation.
+     * Adds dynamic type from the given {@link DynamicBuilders.DynamicDuration} for evaluation.
      * Evaluation will start immediately.
      *
+     * @param durationSource The given duration dynamic type that should be evaluated.
+     * @param consumer The registered consumer for results of the evaluation. It will be called from
+     * UI thread.
+     */
+    @NonNull
+    public BoundDynamicType bind(
+        @NonNull DynamicBuilders.DynamicDuration durationSource,
+        @NonNull DynamicTypeValueReceiver<Duration> consumer) {
+        List<DynamicDataNode<?>> resultBuilder = new ArrayList<>();
+        bindRecursively(durationSource.toDynamicDurationProto(), consumer, resultBuilder);
+        processBindings(resultBuilder);
+        return new BoundDynamicTypeImpl(resultBuilder);
+    }
+
+    /**
+     * Adds pending dynamic type from the given {@link DynamicDuration} for future evaluation.
+     *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
+     * @param durationSource The given durations dynamic type that should be evaluated.
+     * @param consumer The registered consumer for results of the evaluation. It will be called from
+     * UI thread.
+     * @hide
+     */
+    @NonNull
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    public BoundDynamicType bind(
+        @NonNull DynamicDuration durationSource,
+        @NonNull DynamicTypeValueReceiver<Duration> consumer) {
+        List<DynamicDataNode<?>> resultBuilder = new ArrayList<>();
+        bindRecursively(durationSource, consumer, resultBuilder);
+        mDynamicTypeNodes.addAll(resultBuilder);
+        return new BoundDynamicTypeImpl(resultBuilder);
+    }
+
+    /**
+     * Adds dynamic type from the given {@link DynamicBuilders.DynamicInstant} for evaluation.
+     * Evaluation will start immediately.
+     *
+     * @param instantSource The given instant dynamic type that should be evaluated.
+     * @param consumer The registered consumer for results of the evaluation. It will be called from
+     * UI thread.
+     */
+    @NonNull
+    public BoundDynamicType bind(
+        @NonNull DynamicBuilders.DynamicInstant instantSource,
+        @NonNull DynamicTypeValueReceiver<Instant> consumer) {
+        List<DynamicDataNode<?>> resultBuilder = new ArrayList<>();
+        bindRecursively(instantSource.toDynamicInstantProto(), consumer, resultBuilder);
+        processBindings(resultBuilder);
+        return new BoundDynamicTypeImpl(resultBuilder);
+    }
+
+    /**
+     * Adds pending dynamic type from the given {@link DynamicInstant} for future evaluation.
+     *
+     * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
+     *
+     * @param instantSource The given instant dynamic type that should be evaluated.
+     * @param consumer The registered consumer for results of the evaluation. It will be called from
+     * UI thread.
+     * @hide
+     */
+    @NonNull
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    public BoundDynamicType bind(
+        @NonNull DynamicInstant instantSource,
+        @NonNull DynamicTypeValueReceiver<Instant> consumer) {
+        List<DynamicDataNode<?>> resultBuilder = new ArrayList<>();
+        bindRecursively(instantSource, consumer, resultBuilder);
+        mDynamicTypeNodes.addAll(resultBuilder);
+        return new BoundDynamicTypeImpl(resultBuilder);
+    }
+
+    /**
+     * Adds dynamic type from the given {@link DynamicBuilders.DynamicBool} for evaluation.
+     * Evaluation will start immediately.
      *
      * @param boolSource The given boolean dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
@@ -585,10 +612,6 @@
      *
      * <p>Evaluation of this dynamic type will start when {@link #processPendingBindings} is called.
      *
-     * <p>While the {@link BoundDynamicType} is not destroyed with {@link BoundDynamicType#close()}
-     * by caller, results of evaluation will be sent through the given {@link
-     * DynamicTypeValueReceiver}.
-     *
      * @param boolSource The given boolean dynamic type that should be evaluated.
      * @param consumer The registered consumer for results of the evaluation. It will be called from
      *     UI thread.
@@ -720,7 +743,6 @@
             case PLATFORM_SOURCE:
                 node = new PlatformInt32SourceNode(
                                 int32Source.getPlatformSource(),
-                                mTimeDataSource,
                                 mSensorGatewayDataSource,
                                 consumer);
                 break;
@@ -786,6 +808,18 @@
                             Optional.empty());
                     break;
                 }
+            case DURATION_PART:
+            {
+                GetDurationPartOpNode durationPartOpNode =
+                    new GetDurationPartOpNode(int32Source.getDurationPart(), consumer);
+                node = durationPartOpNode;
+
+                bindRecursively(
+                    int32Source.getDurationPart().getInput(),
+                    durationPartOpNode.getIncomingCallback(),
+                    resultBuilder);
+                break;
+            }
             case ANIMATABLE_FIXED:
                 if (!mEnableAnimations && animationFallbackValue.isPresent()) {
                     // Just assign static value if animations are disabled.
@@ -822,7 +856,7 @@
                     // animations won't be played and they would jump to the end value.
                     AnimatableDynamicInt32 dynamicNode = int32Source.getAnimatableDynamic();
                     DynamicAnimatedInt32Node animationNode =
-                            new DynamicAnimatedInt32Node(consumer, dynamicNode.getSpec(),
+                            new DynamicAnimatedInt32Node(consumer, dynamicNode.getAnimationSpec(),
                                     mAnimationQuotaManager);
                     node = animationNode;
 
@@ -843,6 +877,67 @@
     }
 
     /**
+     * Same as {@link #bind(DynamicBuilders.DynamicDuration, DynamicTypeValueReceiver)}, but instead
+     * of returning one {@link BoundDynamicType}, all {@link DynamicDataNode} produced by evaluating
+     * given dynamic type are added to the given list.
+     */
+    private void bindRecursively(
+        @NonNull DynamicDuration durationSource,
+        @NonNull DynamicTypeValueReceiver<Duration> consumer,
+        @NonNull List<DynamicDataNode<?>> resultBuilder) {
+        DynamicDataNode<?> node;
+
+        switch (durationSource.getInnerCase()) {
+            case BETWEEN:
+                BetweenInstancesNode betweenInstancesNode = new BetweenInstancesNode(consumer);
+                node = betweenInstancesNode;
+                bindRecursively(
+                    durationSource.getBetween().getStartInclusive(),
+                    betweenInstancesNode.getLhsIncomingCallback(),
+                    resultBuilder);
+                bindRecursively(
+                    durationSource.getBetween().getEndExclusive(),
+                    betweenInstancesNode.getRhsIncomingCallback(),
+                    resultBuilder);
+                break;
+            case INNER_NOT_SET:
+                throw new IllegalArgumentException("DynamicDuration has no inner source set");
+            default:
+                throw new IllegalArgumentException("Unknown DynamicDuration source type");
+        }
+
+        resultBuilder.add(node);
+    }
+
+    /**
+     * Same as {@link #bind(DynamicBuilders.DynamicInstant, DynamicTypeValueReceiver)}, but instead
+     * of returning one {@link BoundDynamicType}, all {@link DynamicDataNode} produced by evaluating
+     * given dynamic type are added to the given list.
+     */
+    private void bindRecursively(
+        @NonNull DynamicInstant instantSource,
+        @NonNull DynamicTypeValueReceiver<Instant> consumer,
+        @NonNull List<DynamicDataNode<?>> resultBuilder) {
+        DynamicDataNode<?> node;
+
+        switch (instantSource.getInnerCase()) {
+            case FIXED:
+                node = new FixedInstantNode(instantSource.getFixed(), consumer);
+                break;
+            case PLATFORM_SOURCE:
+                node = new PlatformTimeSourceNode(mTimeDataSource, consumer);
+                break;
+
+            case INNER_NOT_SET:
+                throw new IllegalArgumentException("DynamicInstant has no inner source set");
+            default:
+                throw new IllegalArgumentException("Unknown DynamicInstant source type");
+        }
+
+        resultBuilder.add(node);
+    }
+
+    /**
      * Same as {@link #bind(DynamicBuilders.DynamicFloat, DynamicTypeValueReceiver)}, but instead of
      * returning one {@link BoundDynamicType}, all {@link DynamicDataNode} produced by evaluating
      * given dynamic type are added to the given list.
@@ -956,7 +1051,10 @@
                     AnimatableDynamicFloat dynamicNode = floatSource.getAnimatableDynamic();
                     DynamicAnimatedFloatNode animationNode =
                             new DynamicAnimatedFloatNode(
-                                    consumer, dynamicNode.getSpec(), mAnimationQuotaManager);
+                                    consumer,
+                                    dynamicNode.getAnimationSpec(),
+                                    mAnimationQuotaManager
+                            );
                     node = animationNode;
 
                     bindRecursively(
@@ -1037,7 +1135,10 @@
                     AnimatableDynamicColor dynamicNode = colorSource.getAnimatableDynamic();
                     DynamicAnimatedColorNode animationNode =
                             new DynamicAnimatedColorNode(
-                                    consumer, dynamicNode.getSpec(), mAnimationQuotaManager);
+                                    consumer,
+                                    dynamicNode.getAnimationSpec(),
+                                    mAnimationQuotaManager
+                            );
                     node = animationNode;
 
                     bindRecursively(
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/EpochTimePlatformDataSource.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/EpochTimePlatformDataSource.java
new file mode 100644
index 0000000..37c858e
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/EpochTimePlatformDataSource.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2023 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 androidx.wear.protolayout.expression.pipeline;
+
+import androidx.collection.SimpleArrayMap;
+import androidx.wear.protolayout.expression.pipeline.TimeGateway.TimeCallback;
+
+import java.time.Instant;
+import java.util.concurrent.Executor;
+
+/** Utility for time data source. */
+class EpochTimePlatformDataSource {
+    private final Executor mUiExecutor;
+    private final TimeGateway mGateway;
+    private final SimpleArrayMap<DynamicTypeValueReceiver<Instant>, TimeCallback>
+            mConsumerToTimeCallback = new SimpleArrayMap<>();
+
+    EpochTimePlatformDataSource(Executor uiExecutor, TimeGateway gateway) {
+        mUiExecutor = uiExecutor;
+        mGateway = gateway;
+    }
+
+    public void registerForData(DynamicTypeValueReceiver<Instant> consumer) {
+        TimeCallback timeCallback =
+                new TimeCallback() {
+                    @Override
+                    public void onPreUpdate() {
+                        consumer.onPreUpdate();
+                    }
+
+                    @Override
+                    public void onData() {
+                        consumer.onData(Instant.now());
+                    }
+                };
+        mGateway.registerForUpdates(mUiExecutor, timeCallback);
+        mConsumerToTimeCallback.put(consumer, timeCallback);
+    }
+
+    public void unregisterForData(DynamicTypeValueReceiver<Instant> consumer) {
+        TimeCallback timeCallback = mConsumerToTimeCallback.remove(consumer);
+        if (timeCallback != null) {
+            mGateway.unregisterForUpdates(timeCallback);
+        }
+    }
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
index 73727de..4c1027b 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
@@ -145,7 +145,7 @@
                     ValueAnimator.ofFloat(mProtoNode.getFromValue(), mProtoNode.getToValue());
             animator.addUpdateListener(a -> mDownstream.onData((float) a.getAnimatedValue()));
 
-            applyAnimationSpecToAnimator(animator, mProtoNode.getSpec());
+            applyAnimationSpecToAnimator(animator, mProtoNode.getAnimationSpec());
 
             mQuotaAwareAnimator.updateAnimator(animator);
             startOrSkipAnimator();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/InstantNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/InstantNodes.java
new file mode 100644
index 0000000..012469c
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/InstantNodes.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2023 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 androidx.wear.protolayout.expression.pipeline;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.proto.FixedProto.FixedInstant;
+
+import java.time.Instant;
+
+/** Dynamic data nodes which yield instants. */
+class InstantNodes {
+    private InstantNodes() {}
+    /** Dynamic instant node that has a fixed value. */
+    static class FixedInstantNode implements DynamicDataSourceNode<Integer> {
+        private final Instant mValue;
+        private final DynamicTypeValueReceiver<Instant> mDownstream;
+
+        FixedInstantNode(FixedInstant protoNode, DynamicTypeValueReceiver<Instant> downstream) {
+            this.mValue = Instant.ofEpochSecond(protoNode.getEpochSeconds());
+            this.mDownstream = downstream;
+        }
+
+        @Override
+        @UiThread
+        public void preInit() {
+            mDownstream.onPreUpdate();
+        }
+
+        @Override
+        @UiThread
+        public void init() {
+            mDownstream.onData(mValue);
+        }
+
+        @Override
+        public void destroy() {}
+    }
+    /** Dynamic Instant node that gets value from the platform source. */
+    static class PlatformTimeSourceNode implements DynamicDataSourceNode<Integer> {
+        @Nullable private final EpochTimePlatformDataSource mEpochTimePlatformDataSource;
+        private final DynamicTypeValueReceiver<Instant> mDownstream;
+
+        PlatformTimeSourceNode(
+                @Nullable EpochTimePlatformDataSource epochTimePlatformDataSource,
+                DynamicTypeValueReceiver<Instant> downstream) {
+            this.mEpochTimePlatformDataSource = epochTimePlatformDataSource;
+            this.mDownstream = downstream;
+        }
+
+        @Override
+        @UiThread
+        public void preInit() {}
+
+        @Override
+        @UiThread
+        public void init() {
+            if (mEpochTimePlatformDataSource != null) {
+                mEpochTimePlatformDataSource.registerForData(mDownstream);
+            } else {
+                mDownstream.onInvalidated();
+            }
+        }
+
+        @Override
+        @UiThread
+        public void destroy() {
+            if (mEpochTimePlatformDataSource != null) {
+                mEpochTimePlatformDataSource.unregisterForData(mDownstream);
+            }
+        }
+    }
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
index 4fc75c6..a2c9a94 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
@@ -17,24 +17,26 @@
 package androidx.wear.protolayout.expression.pipeline;
 
 import static androidx.wear.protolayout.expression.pipeline.AnimationsHelper.applyAnimationSpecToAnimator;
+import static java.lang.Math.abs;
 
 import android.animation.ValueAnimator;
 import android.util.Log;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
-import androidx.wear.protolayout.expression.pipeline.PlatformDataSources.EpochTimePlatformDataSource;
 import androidx.wear.protolayout.expression.pipeline.PlatformDataSources.PlatformDataSource;
 import androidx.wear.protolayout.expression.pipeline.PlatformDataSources.SensorGatewayPlatformDataSource;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
 import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedInt32;
 import androidx.wear.protolayout.expression.proto.DynamicProto.ArithmeticInt32Op;
+import androidx.wear.protolayout.expression.proto.DynamicProto.DurationPartType;
 import androidx.wear.protolayout.expression.proto.DynamicProto.FloatToInt32Op;
 import androidx.wear.protolayout.expression.proto.DynamicProto.PlatformInt32Source;
 import androidx.wear.protolayout.expression.proto.DynamicProto.PlatformInt32SourceType;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateInt32Source;
+import androidx.wear.protolayout.expression.proto.DynamicProto.GetDurationPartOp;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
+import java.time.Duration;
 
 /** Dynamic data nodes which yield integers. */
 class Int32Nodes {
@@ -72,17 +74,14 @@
         private static final String TAG = "PlatformInt32SourceNode";
 
         @Nullable private final SensorGatewayPlatformDataSource mSensorGatewaySource;
-        @Nullable private final EpochTimePlatformDataSource mEpochTimePlatformDataSource;
         private final PlatformInt32Source mProtoNode;
         private final DynamicTypeValueReceiver<Integer> mDownstream;
 
         PlatformInt32SourceNode(
                 PlatformInt32Source protoNode,
-                @Nullable EpochTimePlatformDataSource epochTimePlatformDataSource,
                 @Nullable SensorGatewayPlatformDataSource sensorGatewaySource,
                 DynamicTypeValueReceiver<Integer> downstream) {
             this.mProtoNode = protoNode;
-            this.mEpochTimePlatformDataSource = epochTimePlatformDataSource;
             this.mSensorGatewaySource = sensorGatewaySource;
             this.mDownstream = downstream;
         }
@@ -128,8 +127,6 @@
                 case PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE:
                 case PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT:
                     return mSensorGatewaySource;
-                case PLATFORM_INT32_SOURCE_TYPE_EPOCH_TIME_SECONDS:
-                    return mEpochTimePlatformDataSource;
             }
             Log.w(TAG, "Unknown PlatformInt32SourceType");
             return null;
@@ -210,6 +207,44 @@
         }
     }
 
+    /** Dynamic integer node that gets duration part from a duration. */
+    static class GetDurationPartOpNode extends DynamicDataTransformNode<Duration, Integer> {
+
+        private static final String TAG = "GetDurationPartOpNode";
+
+        GetDurationPartOpNode(
+            GetDurationPartOp protoNode, DynamicTypeValueReceiver<Integer> downstream) {
+            super(downstream,
+                duration -> (int) getDurationPart(duration, protoNode.getDurationPart()));
+        }
+
+        private static long getDurationPart(Duration duration, DurationPartType durationPartType) {
+            switch (durationPartType) {
+                case DURATION_PART_TYPE_UNDEFINED:
+                case UNRECOGNIZED:
+                    Log.e(TAG, "Unknown duration part type in GetDurationPartOpNode");
+                    return 0;
+                case DURATION_PART_TYPE_DAYS:
+                    return abs(duration.getSeconds() / (3600 * 24));
+                case DURATION_PART_TYPE_HOURS:
+                    return abs((duration.getSeconds() / 3600) % 24);
+                case DURATION_PART_TYPE_MINUTES:
+                    return abs((duration.getSeconds() / 60) % 60);
+                case DURATION_PART_TYPE_SECONDS:
+                    return abs(duration.getSeconds() % 60);
+                case DURATION_PART_TYPE_TOTAL_DAYS:
+                    return duration.toDays();
+                case DURATION_PART_TYPE_TOTAL_HOURS:
+                    return duration.toHours();
+                case DURATION_PART_TYPE_TOTAL_MINUTES:
+                    return duration.toMinutes();
+                case DURATION_PART_TYPE_TOTAL_SECONDS:
+                    return duration.getSeconds();
+            }
+            throw new IllegalArgumentException("Unknown duration part");
+        }
+    }
+
     /** Dynamic int32 node that gets animatable value from fixed source. */
     static class AnimatableFixedInt32Node extends AnimatableNode
             implements DynamicDataSourceNode<Integer> {
@@ -237,7 +272,7 @@
         public void init() {
             ValueAnimator animator =
                     ValueAnimator.ofInt(mProtoNode.getFromValue(), mProtoNode.getToValue());
-            applyAnimationSpecToAnimator(animator, mProtoNode.getSpec());
+            applyAnimationSpecToAnimator(animator, mProtoNode.getAnimationSpec());
             animator.addUpdateListener(a -> mDownstream.onData((Integer) a.getAnimatedValue()));
             mQuotaAwareAnimator.updateAnimator(animator);
             startOrSkipAnimator();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataSources.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataSources.java
index 0f86713..b3a2ee2 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataSources.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataSources.java
@@ -22,8 +22,6 @@
 import androidx.annotation.DoNotInline;
 import androidx.annotation.RequiresApi;
 import androidx.collection.ArrayMap;
-import androidx.collection.SimpleArrayMap;
-import androidx.wear.protolayout.expression.pipeline.TimeGateway.TimeCallback;
 import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
 import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.SensorDataType;
 import androidx.wear.protolayout.expression.proto.DynamicProto.PlatformInt32SourceType;
@@ -43,48 +41,6 @@
                 PlatformInt32SourceType sourceType, DynamicTypeValueReceiver<Integer> consumer);
     }
 
-    /** Utility for time data source. */
-    static class EpochTimePlatformDataSource implements PlatformDataSource {
-        private final Executor mUiExecutor;
-        private final TimeGateway mGateway;
-        private final SimpleArrayMap<DynamicTypeValueReceiver<Integer>, TimeCallback>
-                mConsumerToTimeCallback = new SimpleArrayMap<>();
-
-        EpochTimePlatformDataSource(Executor uiExecutor, TimeGateway gateway) {
-            mUiExecutor = uiExecutor;
-            mGateway = gateway;
-        }
-
-        @Override
-        public void registerForData(
-                PlatformInt32SourceType sourceType, DynamicTypeValueReceiver<Integer> consumer) {
-            TimeCallback timeCallback =
-                    new TimeCallback() {
-                        @Override
-                        public void onPreUpdate() {
-                            consumer.onPreUpdate();
-                        }
-
-                        @Override
-                        public void onData() {
-                            long currentEpochTimeSeconds = System.currentTimeMillis() / 1000;
-                            consumer.onData((int) currentEpochTimeSeconds);
-                        }
-                    };
-            mGateway.registerForUpdates(mUiExecutor, timeCallback);
-            mConsumerToTimeCallback.put(consumer, timeCallback);
-        }
-
-        @Override
-        public void unregisterForData(
-                PlatformInt32SourceType sourceType, DynamicTypeValueReceiver<Integer> consumer) {
-            TimeCallback timeCallback = mConsumerToTimeCallback.remove(consumer);
-            if (timeCallback != null) {
-                mGateway.unregisterForUpdates(timeCallback);
-            }
-        }
-    }
-
     /** Utility for sensor data source. */
     static class SensorGatewayPlatformDataSource implements PlatformDataSource {
         private static final String TAG = "SensorGtwPltDataSource";
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
index 513f38d..1f16396 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
@@ -17,10 +17,12 @@
 package androidx.wear.protolayout.expression.pipeline.sensor;
 
 import android.Manifest;
+import android.os.Build.VERSION_CODES;
 
 import androidx.annotation.AnyThread;
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
 import androidx.annotation.RequiresPermission;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
@@ -54,6 +56,7 @@
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
     @Retention(RetentionPolicy.SOURCE)
+    @RequiresApi(VERSION_CODES.Q)
     @IntDef({
         SENSOR_DATA_TYPE_INVALID,
         SENSOR_DATA_TYPE_HEART_RATE,
@@ -77,6 +80,7 @@
      * each day, and any subscriptions to this data type will log the number of steps the user has
      * done since 12:00AM local time.
      */
+    @RequiresApi(VERSION_CODES.Q)
     @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
     int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1;
 
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java
index 7f9e3cb..d2ab0198 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java
@@ -27,8 +27,10 @@
 
 import androidx.annotation.NonNull;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
@@ -45,6 +47,8 @@
 import org.junit.runner.RunWith;
 import org.robolectric.ParameterizedRobolectricTestRunner;
 
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.BiConsumer;
@@ -151,6 +155,33 @@
                 test(DynamicInt32.constant(10).gte(11), false),
                 test(DynamicInt32.constant(10).gte(10), true),
                 test(DynamicInt32.constant(10).gte(5), true),
+                // Instant maximum value
+                test(DynamicInstant.withSecondsPrecision(Instant.MAX),
+                    Instant.MAX.truncatedTo(ChronoUnit.SECONDS)),
+                // Duration Int overflow
+                test(
+                    DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+                        .durationUntil(DynamicInstant.withSecondsPrecision(Instant.MAX))
+                        .toIntSeconds(),
+                    (int) Instant.MAX.getEpochSecond()),
+                // Positive duration
+                test(durationOfSeconds(123456L).toIntDays(), 1),
+                test(durationOfSeconds(123456L).toIntHours(), 34),
+                test(durationOfSeconds(123456L).toIntMinutes(), 2057),
+                test(durationOfSeconds(123456L).toIntSeconds(), 123456),
+                test(durationOfSeconds(123456L).getIntDaysPart(), 1),
+                test(durationOfSeconds(123456L).getHoursPart(), 10),
+                test(durationOfSeconds(123456L).getMinutesPart(), 17),
+                test(durationOfSeconds(123456L).getSecondsPart(), 36),
+                // Negative duration
+                test(durationOfSeconds(-123456L).toIntDays(), -1),
+                test(durationOfSeconds(-123456L).toIntHours(), -34),
+                test(durationOfSeconds(-123456L).toIntMinutes(), -2057),
+                test(durationOfSeconds(-123456L).toIntSeconds(), -123456),
+                test(durationOfSeconds(-123456L).getIntDaysPart(), 1),
+                test(durationOfSeconds(-123456L).getHoursPart(), 10),
+                test(durationOfSeconds(-123456L).getMinutesPart(), 17),
+                test(durationOfSeconds(-123456L).getSecondsPart(), 36),
                 test(
                         DynamicString.onCondition(DynamicBool.constant(true))
                                 .use(constant("Hello"))
@@ -271,6 +302,17 @@
                 expectedValue);
     }
 
+    private static DynamicTypeEvaluatorTest.TestCase<Instant> test(
+        DynamicInstant bindUnderTest, Instant instant) {
+      return new DynamicTypeEvaluatorTest.TestCase<>(
+          bindUnderTest.toDynamicInstantProto().toString(),
+          (evaluator, cb) -> {
+            evaluator.bind(bindUnderTest, cb);
+            evaluator.processPendingBindings();
+          },
+          instant);
+    }
+
     private static DynamicTypeEvaluatorTest.TestCase<Float> test(
             DynamicFloat bindUnderTest, Float expectedValue) {
         return new DynamicTypeEvaluatorTest.TestCase<>(
@@ -341,6 +383,12 @@
         }
     }
 
+    private static DynamicDuration durationOfSeconds(long seconds) {
+      Instant now = Instant.now();
+      return DynamicInstant.withSecondsPrecision(now)
+          .durationUntil(DynamicInstant.withSecondsPrecision(now.plusSeconds(seconds)));
+    }
+
     private static ImmutableMap<String, StateEntryValue> generateExampleState() {
         return ImmutableMap.of(
                 "state_hello_world",
diff --git a/wear/protolayout/protolayout-expression/api/current.txt b/wear/protolayout/protolayout-expression/api/current.txt
index 49d68e38..1e3c3ea 100644
--- a/wear/protolayout/protolayout-expression/api/current.txt
+++ b/wear/protolayout/protolayout-expression/api/current.txt
@@ -104,6 +104,19 @@
     method public default byte[] toDynamicColorByteArray();
   }
 
+  public static interface DynamicBuilders.DynamicDuration extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[]);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
+    method public default byte[] toDynamicDurationByteArray();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
+  }
+
   public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
@@ -156,6 +169,14 @@
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter with();
   }
 
+  public static interface DynamicBuilders.DynamicInstant extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
+    method public default byte[] toDynamicInstantByteArray();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
+  }
+
   public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
diff --git a/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
index 5ab6ba0..3c2d79b 100644
--- a/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
@@ -104,6 +104,19 @@
     method public default byte[] toDynamicColorByteArray();
   }
 
+  public static interface DynamicBuilders.DynamicDuration extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[]);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
+    method public default byte[] toDynamicDurationByteArray();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
+  }
+
   public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
@@ -156,6 +169,14 @@
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter with();
   }
 
+  public static interface DynamicBuilders.DynamicInstant extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
+    method public default byte[] toDynamicInstantByteArray();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
+  }
+
   public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
diff --git a/wear/protolayout/protolayout-expression/api/restricted_current.txt b/wear/protolayout/protolayout-expression/api/restricted_current.txt
index 49d68e38..1e3c3ea 100644
--- a/wear/protolayout/protolayout-expression/api/restricted_current.txt
+++ b/wear/protolayout/protolayout-expression/api/restricted_current.txt
@@ -104,6 +104,19 @@
     method public default byte[] toDynamicColorByteArray();
   }
 
+  public static interface DynamicBuilders.DynamicDuration extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[]);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
+    method public default byte[] toDynamicDurationByteArray();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
+  }
+
   public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
@@ -156,6 +169,14 @@
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter with();
   }
 
+  public static interface DynamicBuilders.DynamicInstant extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
+    method public default byte[] toDynamicInstantByteArray();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
+  }
+
   public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
diff --git a/wear/protolayout/protolayout-expression/build.gradle b/wear/protolayout/protolayout-expression/build.gradle
index eb396f8..7bb1001 100644
--- a/wear/protolayout/protolayout-expression/build.gradle
+++ b/wear/protolayout/protolayout-expression/build.gradle
@@ -40,7 +40,7 @@
     namespace "androidx.wear.protolayout.expression"
 
     defaultConfig {
-        minSdkVersion 25
+        minSdkVersion 26
     }
     buildTypes.all {
         consumerProguardFiles "proguard-rules.pro"
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
index 110f68a..68edcea 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
@@ -31,15 +31,16 @@
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedBool;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedColor;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedFloat;
+import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInstant;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInt32;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedString;
 import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
 import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.protobuf.ExtensionRegistryLite;
 import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.Instant;
 
 /** Builders for dynamic primitive types used by layout elements. */
 public final class DynamicBuilders {
@@ -249,6 +250,101 @@
   static final int LOGICAL_OP_TYPE_OR = 2;
 
   /**
+   * The duration part to retrieve using {@link GetDurationPartOp}.
+   *
+   * @since 1.2
+   * @hide
+   */
+  @RestrictTo(RestrictTo.Scope.LIBRARY)
+  @IntDef({
+    DURATION_PART_TYPE_UNDEFINED,
+    DURATION_PART_TYPE_TOTAL_DAYS,
+    DURATION_PART_TYPE_TOTAL_HOURS,
+    DURATION_PART_TYPE_TOTAL_MINUTES,
+    DURATION_PART_TYPE_TOTAL_SECONDS,
+    DURATION_PART_TYPE_DAYS,
+    DURATION_PART_TYPE_HOURS,
+    DURATION_PART_TYPE_MINUTES,
+    DURATION_PART_TYPE_SECONDS
+  })
+  @Retention(RetentionPolicy.SOURCE)
+  @interface DurationPartType {}
+
+  /**
+   * Undefined duration part type.
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_UNDEFINED = 0;
+
+  /**
+   * Total number of days in a duration. The fraction part of the result will be truncated. This is
+   * based on the standard definition of a day as 24 hours. Notice that the duration can be
+   * negative, in which case total number of days will be also negative.
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_TOTAL_DAYS = 1;
+
+  /**
+   * Total number of hours in a duration. The fraction part of the result will be truncated. Notice
+   * that the duration can be negative, in which case total number of hours will be also negative.
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_TOTAL_HOURS = 2;
+
+  /**
+   * Total number of minutes in a duration. The fraction part of the result will be truncated.
+   * Notice that the duration can be negative, in which case total number of minutes will be also
+   * negative.
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_TOTAL_MINUTES = 3;
+
+  /**
+   * Total number of seconds in a duration. Notice that the duration can be negative, in which case
+   * total number of seconds will be also negative.
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_TOTAL_SECONDS = 4;
+
+  /**
+   * Number of days part in the duration. This represents the absolute value of the total number of
+   * days in the duration based on the 24 hours day definition. The fraction part of the result will
+   * be truncated.
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_DAYS = 5;
+
+  /**
+   * Number of hours part in the duration. This represents the absolute value of remaining hours
+   * when dividing total hours by hours in a day (24 hours).
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_HOURS = 6;
+
+  /**
+   * Number of minutes part in the duration. This represents the absolute value of remaining minutes
+   * when dividing total minutes by minutes in an hour (60 minutes).
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_MINUTES = 7;
+
+  /**
+   * Number of seconds part in the duration. This represents the absolute value of remaining seconds
+   * when dividing total seconds by seconds in a minute (60 seconds).
+   *
+   * @since 1.2
+   */
+  static final int DURATION_PART_TYPE_SECONDS = 8;
+
+  /**
    * An arithmetic operation, operating on two Int32 instances. This implements simple binary
    * operations of the form "result = LHS <op> RHS", where the available operation types are
    * described in {@code ArithmeticOpType}.
@@ -922,9 +1018,9 @@
      * @since 1.2
      */
     @Nullable
-    public AnimationSpec getSpec() {
-      if (mImpl.hasSpec()) {
-        return AnimationSpec.fromProto(mImpl.getSpec());
+    public AnimationSpec getAnimationSpec() {
+      if (mImpl.hasAnimationSpec()) {
+        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
       } else {
         return null;
       }
@@ -981,8 +1077,8 @@
               + getFromValue()
               + ", toValue="
               + getToValue()
-              + ", spec="
-              + getSpec()
+              + ", animationSpec="
+              + getAnimationSpec()
               + "}";
     }
 
@@ -1024,10 +1120,10 @@
        * @since 1.2
        */
       @NonNull
-      public AnimatableFixedInt32.Builder setSpec(@NonNull AnimationSpec spec) {
-        mImpl.setSpec(spec.toProto());
+      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+        mImpl.setAnimationSpec(animationSpec.toProto());
         mFingerprint.recordPropertyUpdate(
-                3, checkNotNull(spec.getFingerprint()).aggregateValueAsInt());
+            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
         return this;
       }
 
@@ -1080,9 +1176,9 @@
      * @since 1.2
      */
     @Nullable
-    public AnimationSpec getSpec() {
-      if (mImpl.hasSpec()) {
-        return AnimationSpec.fromProto(mImpl.getSpec());
+    public AnimationSpec getAnimationSpec() {
+      if (mImpl.hasAnimationSpec()) {
+        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
       } else {
         return null;
       }
@@ -1134,7 +1230,12 @@
     @Override
     @NonNull
     public String toString() {
-      return "AnimatableDynamicInt32{" + "input=" + getInput() + ", spec=" + getSpec() + "}";
+      return "AnimatableDynamicInt32{"
+          + "input="
+          + getInput()
+          + ", animationSpec="
+          + getAnimationSpec()
+          + "}";
     }
 
     /** Builder for {@link AnimatableDynamicInt32}. */
@@ -1164,10 +1265,10 @@
        * @since 1.2
        */
       @NonNull
-      public AnimatableDynamicInt32.Builder setSpec(@NonNull AnimationSpec spec) {
-        mImpl.setSpec(spec.toProto());
+      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+        mImpl.setAnimationSpec(animationSpec.toProto());
         mFingerprint.recordPropertyUpdate(
-                2, checkNotNull(spec.getFingerprint()).aggregateValueAsInt());
+            2, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
         return this;
       }
 
@@ -1189,18 +1290,16 @@
    *
    * <p>For example the following expression is equivalent to {@code result = ((a + b)*c)/d }:
    *
-   * <pre>
+   * <pre>{@code
    * a.plus(b).times(c).div(d);
-   * </pre>
+   * }</pre>
    *
    * More complex expressions can be created by nesting expressions. For example the following
    * expression is equivalent to {@code result = (a + b)*(c - d) }:
    *
-   * <pre>
+   * <pre>{@code
    * (a.plus(b)).times(c.minus(d));
-   * </pre>
-   *
-   * .
+   * }</pre>
    *
    * @since 1.2
    */
@@ -1269,15 +1368,15 @@
      *
      * @param start The start value of the range.
      * @param end The end value of the range.
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    static DynamicInt32 animate(int start, int end, @NonNull AnimationSpec spec) {
+    static DynamicInt32 animate(int start, int end, @NonNull AnimationSpec animationSpec) {
       return new AnimatableFixedInt32.Builder()
-              .setFromValue(start)
-              .setToValue(end)
-              .setSpec(spec)
-              .build();
+          .setFromValue(start)
+          .setToValue(end)
+          .setAnimationSpec(animationSpec)
+          .build();
     }
 
     /**
@@ -1300,25 +1399,28 @@
      *
      * @param stateKey The key to a {@link StateEntryValue} with an int value from the provider's
      *     state.
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    static DynamicInt32 animate(@NonNull String stateKey, @NonNull AnimationSpec spec) {
+    static DynamicInt32 animate(@NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
       return new AnimatableDynamicInt32.Builder()
-              .setInput(fromState(stateKey))
-              .setSpec(spec)
-              .build();
+          .setInput(fromState(stateKey))
+          .setAnimationSpec(animationSpec)
+          .build();
     }
 
     /**
      * Returns a {@link DynamicInt32} that is bound to the value of this {@link DynamicInt32} and
      * every time its value is changing, it animates from its current value to the new value.
      *
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    default DynamicInt32 animate(@NonNull AnimationSpec spec) {
-      return new AnimatableDynamicInt32.Builder().setInput(this).setSpec(spec).build();
+    default DynamicInt32 animate(@NonNull AnimationSpec animationSpec) {
+      return new AnimatableDynamicInt32.Builder()
+          .setInput(this)
+          .setAnimationSpec(animationSpec)
+          .build();
     }
 
     /**
@@ -1838,7 +1940,7 @@
     @NonNull
     default DynamicFloat rem(float other) {
       return new ArithmeticFloatOp.Builder()
-          .setInputLhs( this.asFloat())
+          .setInputLhs(this.asFloat())
           .setInputRhs(DynamicFloat.constant(other))
           .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
           .build();
@@ -2115,6 +2217,9 @@
     if (proto.hasFloatToInt()) {
       return FloatToInt32Op.fromProto(proto.getFloatToInt());
     }
+    if (proto.hasDurationPart()) {
+      return GetDurationPartOp.fromProto(proto.getDurationPart());
+    }
     if (proto.hasAnimatableFixed()) {
       return AnimatableFixedInt32.fromProto(proto.getAnimatableFixed());
     }
@@ -3325,9 +3430,9 @@
      * @since 1.2
      */
     @Nullable
-    public AnimationSpec getSpec() {
-      if (mImpl.hasSpec()) {
-        return AnimationSpec.fromProto(mImpl.getSpec());
+    public AnimationSpec getAnimationSpec() {
+      if (mImpl.hasAnimationSpec()) {
+        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
       } else {
         return null;
       }
@@ -3367,8 +3472,8 @@
           + getFromValue()
           + ", toValue="
           + getToValue()
-          + ", spec="
-          + getSpec()
+          + ", animationSpec="
+          + getAnimationSpec()
           + "}";
     }
 
@@ -3410,10 +3515,10 @@
        * @since 1.2
        */
       @NonNull
-      public Builder setSpec(@NonNull AnimationSpec spec) {
-        mImpl.setSpec(spec.toProto());
+      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+        mImpl.setAnimationSpec(animationSpec.toProto());
         mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(spec.getFingerprint()).aggregateValueAsInt());
+            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
         return this;
       }
 
@@ -3466,9 +3571,9 @@
      * @since 1.2
      */
     @Nullable
-    public AnimationSpec getSpec() {
-      if (mImpl.hasSpec()) {
-        return AnimationSpec.fromProto(mImpl.getSpec());
+    public AnimationSpec getAnimationSpec() {
+      if (mImpl.hasAnimationSpec()) {
+        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
       } else {
         return null;
       }
@@ -3503,7 +3608,12 @@
     @Override
     @NonNull
     public String toString() {
-      return "AnimatableDynamicFloat{" + "input=" + getInput() + ", spec=" + getSpec() + "}";
+      return "AnimatableDynamicFloat{"
+          + "input="
+          + getInput()
+          + ", animationSpec="
+          + getAnimationSpec()
+          + "}";
     }
 
     /** Builder for {@link AnimatableDynamicFloat}. */
@@ -3533,10 +3643,10 @@
        * @since 1.2
        */
       @NonNull
-      public Builder setSpec(@NonNull AnimationSpec spec) {
-        mImpl.setSpec(spec.toProto());
+      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+        mImpl.setAnimationSpec(animationSpec.toProto());
         mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(spec.getFingerprint()).aggregateValueAsInt());
+            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
         return this;
       }
 
@@ -3558,18 +3668,16 @@
    *
    * <p>For example the following expression is equivalent to {@code result = ((a + b)*c)/d }:
    *
-   * <pre>
+   * <pre>{@code
    * a.plus(b).times(c).div(d);
-   * </pre>
+   * }</pre>
    *
    * More complex expressions can be created by nesting expressions. For example the following
    * expression is equivalent to {@code result = (a + b)*(c - d) }:
    *
-   * <pre>
+   * <pre>{@code
    * (a.plus(b)).times(c.minus(d));
-   * </pre>
-   *
-   * .
+   * }</pre>
    *
    * @since 1.2
    */
@@ -3639,14 +3747,14 @@
      *
      * @param start The start value of the range.
      * @param end The end value of the range.
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    static DynamicFloat animate(float start, float end, @NonNull AnimationSpec spec) {
+    static DynamicFloat animate(float start, float end, @NonNull AnimationSpec animationSpec) {
       return new AnimatableFixedFloat.Builder()
           .setFromValue(start)
           .setToValue(end)
-          .setSpec(spec)
+          .setAnimationSpec(animationSpec)
           .build();
     }
 
@@ -3670,13 +3778,13 @@
      *
      * @param stateKey The key to a {@link StateEntryValue} with a float value from the providers
      *     state.
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    static DynamicFloat animate(@NonNull String stateKey, @NonNull AnimationSpec spec) {
+    static DynamicFloat animate(@NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
       return new AnimatableDynamicFloat.Builder()
           .setInput(fromState(stateKey))
-          .setSpec(spec)
+          .setAnimationSpec(animationSpec)
           .build();
     }
 
@@ -3684,11 +3792,14 @@
      * Returns a {@link DynamicFloat} that is bound to the value of this {@link DynamicFloat} and
      * every time its value is changing, it animates from its current value to the new value.
      *
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    default DynamicFloat animate(@NonNull AnimationSpec spec) {
-      return new AnimatableDynamicFloat.Builder().setInput(this).setSpec(spec).build();
+    default DynamicFloat animate(@NonNull AnimationSpec animationSpec) {
+      return new AnimatableDynamicFloat.Builder()
+          .setInput(this)
+          .setAnimationSpec(animationSpec)
+          .build();
     }
 
     /**
@@ -3730,8 +3841,6 @@
     @SuppressWarnings("KotlinOperator")
     @NonNull
     default DynamicFloat plus(@NonNull DynamicFloat other) {
-
-      // overloaded operators.
       return new ArithmeticFloatOp.Builder()
           .setInputLhs(this)
           .setInputRhs(other)
@@ -4036,7 +4145,7 @@
     }
 
     /**
-     * reates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicFloat}
+     * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicFloat}
      * by a float; As an example, the following is equal to {@code DynamicFloat.constant(1.5f)}
      *
      * <pre>
@@ -4060,7 +4169,7 @@
     }
 
     /**
-     * reates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicFloat}
+     * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicFloat}
      * by a {@link DynamicInt32}; As an example, the following is equal to {@code
      * DynamicFloat.constant(2f)}
      *
@@ -5286,9 +5395,9 @@
      * @since 1.2
      */
     @Nullable
-    public AnimationSpec getSpec() {
-      if (mImpl.hasSpec()) {
-        return AnimationSpec.fromProto(mImpl.getSpec());
+    public AnimationSpec getAnimationSpec() {
+      if (mImpl.hasAnimationSpec()) {
+        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
       } else {
         return null;
       }
@@ -5328,8 +5437,8 @@
           + getFromArgb()
           + ", toArgb="
           + getToArgb()
-          + ", spec="
-          + getSpec()
+          + ", animationSpec="
+          + getAnimationSpec()
           + "}";
     }
 
@@ -5371,10 +5480,10 @@
        * @since 1.2
        */
       @NonNull
-      public Builder setSpec(@NonNull AnimationSpec spec) {
-        mImpl.setSpec(spec.toProto());
+      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+        mImpl.setAnimationSpec(animationSpec.toProto());
         mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(spec.getFingerprint()).aggregateValueAsInt());
+            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
         return this;
       }
 
@@ -5427,9 +5536,9 @@
      * @since 1.2
      */
     @Nullable
-    public AnimationSpec getSpec() {
-      if (mImpl.hasSpec()) {
-        return AnimationSpec.fromProto(mImpl.getSpec());
+    public AnimationSpec getAnimationSpec() {
+      if (mImpl.hasAnimationSpec()) {
+        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
       } else {
         return null;
       }
@@ -5464,7 +5573,12 @@
     @Override
     @NonNull
     public String toString() {
-      return "AnimatableDynamicColor{" + "input=" + getInput() + ", spec=" + getSpec() + "}";
+      return "AnimatableDynamicColor{"
+          + "input="
+          + getInput()
+          + ", animationSpec="
+          + getAnimationSpec()
+          + "}";
     }
 
     /** Builder for {@link AnimatableDynamicColor}. */
@@ -5494,10 +5608,10 @@
        * @since 1.2
        */
       @NonNull
-      public Builder setSpec(@NonNull AnimationSpec spec) {
-        mImpl.setSpec(spec.toProto());
+      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+        mImpl.setAnimationSpec(animationSpec.toProto());
         mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(spec.getFingerprint()).aggregateValueAsInt());
+            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
         return this;
       }
 
@@ -5580,15 +5694,15 @@
      *
      * @param start The start value of the range.
      * @param end The end value of the range.
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
     static DynamicColor animate(
-        @ColorInt int start, @ColorInt int end, @NonNull AnimationSpec spec) {
+        @ColorInt int start, @ColorInt int end, @NonNull AnimationSpec animationSpec) {
       return new AnimatableFixedColor.Builder()
           .setFromArgb(start)
           .setToArgb(end)
-          .setSpec(spec)
+          .setAnimationSpec(animationSpec)
           .build();
     }
 
@@ -5597,7 +5711,7 @@
      * the state value changes, this {@link DynamicColor} will animate from its current value to the
      * new value (from the state).
      *
-     * @param stateKey The key to a {@link StateEntryValue} with a color value from the providers
+     * @param stateKey The key to a {@link StateEntryValue} with a color value from the provider's
      *     state.
      */
     @NonNull
@@ -5610,15 +5724,15 @@
      * the state value changes, this {@link DynamicColor} will animate from its current value to the
      * new value (from the state).
      *
-     * @param stateKey The key to a {@link StateEntryValue} with a color value from the providers
+     * @param stateKey The key to a {@link StateEntryValue} with a color value from the provider's
      *     state.
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    static DynamicColor animate(@NonNull String stateKey, @NonNull AnimationSpec spec) {
+    static DynamicColor animate(@NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
       return new AnimatableDynamicColor.Builder()
           .setInput(fromState(stateKey))
-          .setSpec(spec)
+          .setAnimationSpec(animationSpec)
           .build();
     }
 
@@ -5626,11 +5740,14 @@
      * Returns a {@link DynamicColor} that is bound to the value of this {@link DynamicColor} and
      * every time its value is changing, it animates from its current value to the new value.
      *
-     * @param spec The animation parameters.
+     * @param animationSpec The animation parameters.
      */
     @NonNull
-    default DynamicColor animate(@NonNull AnimationSpec spec) {
-      return new AnimatableDynamicColor.Builder().setInput(this).setSpec(spec).build();
+    default DynamicColor animate(@NonNull AnimationSpec animationSpec) {
+      return new AnimatableDynamicColor.Builder()
+          .setInput(this)
+          .setAnimationSpec(animationSpec)
+          .build();
     }
 
     /**
@@ -5690,6 +5807,677 @@
   }
 
   /**
+   * A dynamic time instant that sources its value from the platform.
+   *
+   * @since 1.2
+   */
+  static final class PlatformTimeSource implements DynamicInstant {
+    private final DynamicProto.PlatformTimeSource mImpl;
+    @Nullable private final Fingerprint mFingerprint;
+
+    PlatformTimeSource(DynamicProto.PlatformTimeSource impl, @Nullable Fingerprint fingerprint) {
+      this.mImpl = impl;
+      this.mFingerprint = fingerprint;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    public Fingerprint getFingerprint() {
+      return mFingerprint;
+    }
+
+    @NonNull
+    static PlatformTimeSource fromProto(@NonNull DynamicProto.PlatformTimeSource proto) {
+      return new PlatformTimeSource(proto, null);
+    }
+
+    @NonNull
+    DynamicProto.PlatformTimeSource toProto() {
+      return mImpl;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public DynamicProto.DynamicInstant toDynamicInstantProto() {
+      return DynamicProto.DynamicInstant.newBuilder().setPlatformSource(mImpl).build();
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+      return "PlatformTimeSource";
+    }
+
+    /** Builder for {@link PlatformTimeSource}. */
+    public static final class Builder implements DynamicInstant.Builder {
+      private final DynamicProto.PlatformTimeSource.Builder mImpl =
+          DynamicProto.PlatformTimeSource.newBuilder();
+      private final Fingerprint mFingerprint = new Fingerprint(-1895976938);
+
+      public Builder() {}
+
+      @Override
+      @NonNull
+      public PlatformTimeSource build() {
+        return new PlatformTimeSource(mImpl.build(), mFingerprint);
+      }
+    }
+  }
+
+  /**
+   * Interface defining a dynamic time instant type.
+   *
+   * <p> {@link DynamicInstant} precision is seconds. Thus, any time or duration operation will
+   * operate on that precision level.
+   *
+   * @since 1.2
+   */
+  public interface DynamicInstant extends DynamicType {
+    /**
+     * Get the protocol buffer representation of this object.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    DynamicProto.DynamicInstant toDynamicInstantProto();
+
+    /**
+     * Creates a {@link DynamicInstant} from a byte array generated by {@link
+     * #toDynamicInstantByteArray()}.
+     */
+    @NonNull
+    static DynamicInstant fromByteArray(@NonNull byte[] byteArray) {
+      try {
+        return dynamicInstantFromProto(
+            DynamicProto.DynamicInstant.parseFrom(
+                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+      } catch (InvalidProtocolBufferException e) {
+        throw new IllegalArgumentException("Byte array could not be parsed into DynamicInstant", e);
+      }
+    }
+
+    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+    @NonNull
+    default byte[] toDynamicInstantByteArray() {
+      return toDynamicInstantProto().toByteArray();
+    }
+
+
+    /**
+     * Creates a constant-valued {@link DynamicInstant} from an {@link Instant}. If {@link Instant}
+     * precision is greater than seconds, then any excess precision information will be dropped.
+     */
+    @NonNull
+    static DynamicInstant withSecondsPrecision(@NonNull Instant instant) {
+      return new FixedInstant.Builder().setEpochSeconds(instant.getEpochSecond()).build();
+    }
+
+    /**
+     * Creates a {@link DynamicInstant} that updates its value periodically from the system time.
+     */
+    @NonNull
+    static DynamicInstant platformTimeWithSecondsPrecision() {
+      return new PlatformTimeSource.Builder().build();
+    }
+
+    /**
+     * Returns duration between the two {@link DynamicInstant} instances as a {@link
+     * DynamicDuration}. The resulted duration is inclusive of the start instant and exclusive of
+     * the end; As an example, the following expression yields a duration object representing 10
+     * seconds:
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(10L))
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(20L)));
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicDuration} containing the result of the operation.
+     */
+    @NonNull
+    default DynamicDuration durationUntil(@NonNull DynamicInstant to) {
+      return new BetweenDuration.Builder().setStartInclusive(this).setEndExclusive(to).build();
+    }
+
+    /**
+     * Get the fingerprint for this object or null if unknown.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    Fingerprint getFingerprint();
+
+    /**
+     * Builder to create {@link DynamicInstant} objects.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    interface Builder {
+
+      /** Builds an instance with values accumulated in this Builder. */
+      @NonNull
+      DynamicInstant build();
+    }
+  }
+
+  /**
+   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+   * created using this method can't be added to any other wrapper.
+   *
+   * @hide
+   */
+  @RestrictTo(Scope.LIBRARY_GROUP)
+  @NonNull
+  public static DynamicInstant dynamicInstantFromProto(@NonNull DynamicProto.DynamicInstant proto) {
+    if (proto.hasFixed()) {
+      return FixedInstant.fromProto(proto.getFixed());
+    }
+    if (proto.hasPlatformSource()) {
+      return PlatformTimeSource.fromProto(proto.getPlatformSource());
+    }
+    throw new IllegalStateException("Proto was not a recognised instance of DynamicInstant");
+  }
+
+  /**
+   * A dynamic duration type that represents the duration between two dynamic time instants.
+   *
+   * @since 1.2
+   */
+  static final class BetweenDuration implements DynamicDuration {
+    private final DynamicProto.BetweenDuration mImpl;
+    @Nullable private final Fingerprint mFingerprint;
+
+    BetweenDuration(DynamicProto.BetweenDuration impl, @Nullable Fingerprint fingerprint) {
+      this.mImpl = impl;
+      this.mFingerprint = fingerprint;
+    }
+
+    /**
+     * Gets the time instant value marking the start of the duration.
+     *
+     * @since 1.2
+     */
+    @Nullable
+    public DynamicInstant getStartInclusive() {
+      if (mImpl.hasStartInclusive()) {
+        return DynamicBuilders.dynamicInstantFromProto(mImpl.getStartInclusive());
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Gets the time instant value marking the end of the duration.
+     *
+     * @since 1.2
+     */
+    @Nullable
+    public DynamicInstant getEndExclusive() {
+      if (mImpl.hasEndExclusive()) {
+        return DynamicBuilders.dynamicInstantFromProto(mImpl.getEndExclusive());
+      } else {
+        return null;
+      }
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    public Fingerprint getFingerprint() {
+      return mFingerprint;
+    }
+
+    @NonNull
+    static BetweenDuration fromProto(@NonNull DynamicProto.BetweenDuration proto) {
+      return new BetweenDuration(proto, null);
+    }
+
+    @NonNull
+    DynamicProto.BetweenDuration toProto() {
+      return mImpl;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public DynamicProto.DynamicDuration toDynamicDurationProto() {
+      return DynamicProto.DynamicDuration.newBuilder().setBetween(mImpl).build();
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+      return "BetweenDuration{"
+          + "startInclusive="
+          + getStartInclusive()
+          + ", endExclusive="
+          + getEndExclusive()
+          + "}";
+    }
+
+    /** Builder for {@link BetweenDuration}. */
+    public static final class Builder implements DynamicDuration.Builder {
+      private final DynamicProto.BetweenDuration.Builder mImpl =
+          DynamicProto.BetweenDuration.newBuilder();
+      private final Fingerprint mFingerprint = new Fingerprint(-1615230958);
+
+      public Builder() {}
+
+      /**
+       * Sets the time instant value marking the start of the duration.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setStartInclusive(@NonNull DynamicInstant startInclusive) {
+        mImpl.setStartInclusive(startInclusive.toDynamicInstantProto());
+        mFingerprint.recordPropertyUpdate(
+            1, checkNotNull(startInclusive.getFingerprint()).aggregateValueAsInt());
+        return this;
+      }
+
+      /**
+       * Sets the time instant value marking the end of the duration.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setEndExclusive(@NonNull DynamicInstant endExclusive) {
+        mImpl.setEndExclusive(endExclusive.toDynamicInstantProto());
+        mFingerprint.recordPropertyUpdate(
+            2, checkNotNull(endExclusive.getFingerprint()).aggregateValueAsInt());
+        return this;
+      }
+
+      @Override
+      @NonNull
+      public BetweenDuration build() {
+        return new BetweenDuration(mImpl.build(), mFingerprint);
+      }
+    }
+  }
+
+  /**
+   * Interface defining a dynamic duration type.
+   *
+   * @since 1.2
+   */
+  public interface DynamicDuration extends DynamicType {
+    /**
+     * Get the protocol buffer representation of this object.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    DynamicProto.DynamicDuration toDynamicDurationProto();
+
+    /**
+     * Creates a {@link DynamicDuration} from a byte array generated by {@link
+     * #toDynamicDurationByteArray()}.
+     */
+    @NonNull
+    static DynamicDuration fromByteArray(@NonNull byte[] byteArray) {
+      try {
+        return dynamicDurationFromProto(
+            DynamicProto.DynamicDuration.parseFrom(
+                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+      } catch (InvalidProtocolBufferException e) {
+        throw new IllegalArgumentException(
+            "Byte array could not be parsed into DynamicDuration", e);
+      }
+    }
+
+    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+    @NonNull
+    default byte[] toDynamicDurationByteArray() {
+      return toDynamicDurationProto().toByteArray();
+    }
+
+
+    /**
+     * Returns the total number of days in a {@link DynamicDuration} as a {@link DynamicInt32}. The
+     * fraction part of the result will be truncated. This is based on the standard definition of a
+     * day as 24 hours. As an example, the following is equal to {@code DynamicInt32.constant(1)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .toIntDays();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     *     Integer overflow can occur if the result of the operation is larger than {@link
+     *     Integer#MAX_VALUE}.
+     */
+    @NonNull
+    default DynamicInt32 toIntDays() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_TOTAL_DAYS)
+          .build();
+    }
+
+    /**
+     * Returns the total number of hours in a {@link DynamicDuration} as a {@link DynamicInt32}. The
+     * fraction part of the result will be truncated. As an example, the following is equal to
+     * {@code DynamicInt32.constant(34)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .toIntHours();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     *     Integer overflow can occur if the result of the operation is larger than {@link
+     *     Integer#MAX_VALUE}.
+     */
+    @NonNull
+    default DynamicInt32 toIntHours() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_TOTAL_HOURS)
+          .build();
+    }
+
+    /**
+     * Returns the total number of minutes in a {@link DynamicDuration} as a {@link DynamicInt32}.
+     * The fraction part of the result will be truncated. As an example, the following is equal to
+     * {@code DynamicInt32.constant(2057)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .toIntMinutes();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     *     Integer overflow can occur if the result of the operation is larger than {@link
+     *     Integer#MAX_VALUE}.
+     */
+    @NonNull
+    default DynamicInt32 toIntMinutes() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_TOTAL_MINUTES)
+          .build();
+    }
+
+    /**
+     * Returns the total number of seconds in a {@link DynamicDuration} as a {@link DynamicInt32}.
+     * As an example, the following is equal to {@code DynamicInt32.constant(123456)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .toIntSeconds();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     *     Integer overflow can occur if the result of the operation is larger than {@link
+     *     Integer#MAX_VALUE}.
+     */
+    @NonNull
+    default DynamicInt32 toIntSeconds() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_TOTAL_SECONDS)
+          .build();
+    }
+
+    /**
+     * Returns the total number of days in a duration as a {@link DynamicInt32}. This represents the
+     * absolute value of the total number of days in the duration based on the 24 hours day
+     * definition. The fraction part of the result will be truncated; As an example, the following
+     * is equal to {@code DynamicInt32.constant(1)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .getIntDaysPart();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     *     Integer overflow can occur if the result of the operation is larger than {@link
+     *     Integer#MAX_VALUE}.
+     */
+    @NonNull
+    default DynamicInt32 getIntDaysPart() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_DAYS)
+          .build();
+    }
+
+    /**
+     * Returns the number of hours part in the duration as a {@link DynamicInt32}. This represents
+     * the absolute value of remaining hours when dividing total hours by hours in a day (24 hours);
+     * As an example, the following is equal to {@code DynamicInt32.constant(10)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .getHoursPart();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     */
+    @NonNull
+    default DynamicInt32 getHoursPart() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_HOURS)
+          .build();
+    }
+
+    /**
+     * Returns the number of minutes part in the duration as a {@link DynamicInt32}. This represents
+     * the absolute value of remaining minutes when dividing total minutes by minutes in an hour (60
+     * minutes). As an example, the following is equal to {@code DynamicInt32.constant(17)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .getMinutesPart();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     */
+    @NonNull
+    default DynamicInt32 getMinutesPart() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_MINUTES)
+          .build();
+    }
+
+    /**
+     * Returns the number of seconds part in the duration as a {@link DynamicInt32}. This represents
+     * the absolute value of remaining seconds when dividing total seconds by seconds in a minute
+     * (60 seconds); As an example, the following is equal to {@code DynamicInt32.constant(36)}
+     *
+     * <pre>
+     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+     *      .getSecondsPart();
+     * </pre>
+     *
+     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+     */
+    @NonNull
+    default DynamicInt32 getSecondsPart() {
+      return new GetDurationPartOp.Builder()
+          .setInput(this)
+          .setDurationPart(DURATION_PART_TYPE_SECONDS)
+          .build();
+    }
+
+    /**
+     * Get the fingerprint for this object or null if unknown.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    Fingerprint getFingerprint();
+
+    /**
+     * Builder to create {@link DynamicDuration} objects.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    interface Builder {
+
+      /** Builds an instance with values accumulated in this Builder. */
+      @NonNull
+      DynamicDuration build();
+    }
+  }
+
+  /**
+   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+   * created using this method can't be added to any other wrapper.
+   *
+   * @hide
+   */
+  @RestrictTo(Scope.LIBRARY_GROUP)
+  @NonNull
+  public static DynamicDuration dynamicDurationFromProto(
+      @NonNull DynamicProto.DynamicDuration proto) {
+    if (proto.hasBetween()) {
+      return BetweenDuration.fromProto(proto.getBetween());
+    }
+    throw new IllegalStateException("Proto was not a recognised instance of DynamicDuration");
+  }
+
+  /**
+   * Retrieve the specified duration part of a {@link DynamicDuration} instance as a {@link
+   * DynamicInt32}.
+   *
+   * @since 1.2
+   */
+  static final class GetDurationPartOp implements DynamicInt32 {
+    private final DynamicProto.GetDurationPartOp mImpl;
+    @Nullable private final Fingerprint mFingerprint;
+
+    GetDurationPartOp(DynamicProto.GetDurationPartOp impl, @Nullable Fingerprint fingerprint) {
+      this.mImpl = impl;
+      this.mFingerprint = fingerprint;
+    }
+
+    /**
+     * Gets the duration input.
+     *
+     * @since 1.2
+     */
+    @Nullable
+    public DynamicDuration getInput() {
+      if (mImpl.hasInput()) {
+        return DynamicBuilders.dynamicDurationFromProto(mImpl.getInput());
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Gets the duration part to retrieve.
+     *
+     * @since 1.2
+     */
+    @DurationPartType
+    public int getDurationPart() {
+      return mImpl.getDurationPart().getNumber();
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    public Fingerprint getFingerprint() {
+      return mFingerprint;
+    }
+
+    @NonNull
+    static GetDurationPartOp fromProto(@NonNull DynamicProto.GetDurationPartOp proto) {
+      return new GetDurationPartOp(proto, null);
+    }
+
+    @NonNull
+    DynamicProto.GetDurationPartOp toProto() {
+      return mImpl;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+      return DynamicProto.DynamicInt32.newBuilder().setDurationPart(mImpl).build();
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+      return "GetDurationPartOp{"
+          + "input="
+          + getInput()
+          + ", durationPart="
+          + getDurationPart()
+          + "}";
+    }
+
+    /** Builder for {@link GetDurationPartOp}. */
+    public static final class Builder implements DynamicInt32.Builder {
+      private final DynamicProto.GetDurationPartOp.Builder mImpl =
+          DynamicProto.GetDurationPartOp.newBuilder();
+      private final Fingerprint mFingerprint = new Fingerprint(-225941123);
+
+      public Builder() {}
+
+      /**
+       * Sets the duration input.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setInput(@NonNull DynamicDuration input) {
+        mImpl.setInput(input.toDynamicDurationProto());
+        mFingerprint.recordPropertyUpdate(
+            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+        return this;
+      }
+
+      /**
+       * Sets the duration part to retrieve.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setDurationPart(@DurationPartType int durationPart) {
+        mImpl.setDurationPart(DynamicProto.DurationPartType.forNumber(durationPart));
+        mFingerprint.recordPropertyUpdate(2, durationPart);
+        return this;
+      }
+
+      @Override
+      @NonNull
+      public GetDurationPartOp build() {
+        return new GetDurationPartOp(mImpl.build(), mFingerprint);
+      }
+    }
+  }
+
+  /**
    * Interface to be used as a base type for all other dynamic types. This is not consumed by any
    * Tile elements, it exists just as a marker interface for use internally in the Tiles library.
    */
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
index 4ca0ed2..7320b75 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
@@ -49,7 +49,7 @@
     }
 
     /**
-     * Gets the value. Intended for testing purposes only.
+     * Gets the value.
      *
      * @since 1.2
      */
@@ -499,4 +499,86 @@
       }
     }
   }
+
+  /**
+   * A fixed time instant type.
+   *
+   * @since 1.2
+   */
+  static final class FixedInstant implements DynamicBuilders.DynamicInstant {
+    private final FixedProto.FixedInstant mImpl;
+    @Nullable private final Fingerprint mFingerprint;
+
+    FixedInstant(FixedProto.FixedInstant impl, @Nullable Fingerprint fingerprint) {
+      this.mImpl = impl;
+      this.mFingerprint = fingerprint;
+    }
+
+    /**
+     * Gets the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970.
+     *
+     * @since 1.2
+     */
+    public long getEpochSeconds() {
+      return mImpl.getEpochSeconds();
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    public Fingerprint getFingerprint() {
+      return mFingerprint;
+    }
+
+    @NonNull
+    static FixedInstant fromProto(@NonNull FixedProto.FixedInstant proto) {
+      return new FixedInstant(proto, null);
+    }
+
+    @NonNull
+    FixedProto.FixedInstant toProto() {
+      return mImpl;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public DynamicProto.DynamicInstant toDynamicInstantProto() {
+      return DynamicProto.DynamicInstant.newBuilder().setFixed(mImpl).build();
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+      return "FixedInstant{" + "epochSeconds=" + getEpochSeconds() + "}";
+    }
+
+    /** Builder for {@link FixedInstant}. */
+    public static final class Builder implements DynamicBuilders.DynamicInstant.Builder {
+      private final FixedProto.FixedInstant.Builder mImpl = FixedProto.FixedInstant.newBuilder();
+      private final Fingerprint mFingerprint = new Fingerprint(-1986552556);
+
+      public Builder() {}
+
+      /**
+       * Sets the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setEpochSeconds(long epochSeconds) {
+        mImpl.setEpochSeconds(epochSeconds);
+        mFingerprint.recordPropertyUpdate(1, Long.hashCode(epochSeconds));
+        return this;
+      }
+
+      @Override
+      @NonNull
+      public FixedInstant build() {
+        return new FixedInstant(mImpl.build(), mFingerprint);
+      }
+    }
+  }
 }
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
index b3d3eda..34e1e00 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
@@ -74,12 +74,13 @@
     DynamicColor animatedColor = DynamicColor.animate(startColor, endColor);
     DynamicColor animatedColorWithSpec = DynamicColor.animate(startColor, endColor, SPEC);
 
-    assertThat(animatedColor.toDynamicColorProto().getAnimatableFixed().hasSpec()).isFalse();
+    assertThat(animatedColor.toDynamicColorProto().getAnimatableFixed().hasAnimationSpec())
+         .isFalse();
     assertThat(animatedColorWithSpec.toDynamicColorProto().getAnimatableFixed().getFromArgb())
         .isEqualTo(startColor);
     assertThat(animatedColorWithSpec.toDynamicColorProto().getAnimatableFixed().getToArgb())
         .isEqualTo(endColor);
-    assertThat(animatedColorWithSpec.toDynamicColorProto().getAnimatableFixed().getSpec())
+    assertThat(animatedColorWithSpec.toDynamicColorProto().getAnimatableFixed().getAnimationSpec())
         .isEqualTo(SPEC.toProto());
   }
 
@@ -93,7 +94,7 @@
                 .toString())
         .isEqualTo(
             "AnimatableFixedColor{"
-                + "fromArgb=1, toArgb=2, spec=AnimationSpec{"
+                + "fromArgb=1, toArgb=2, animationSpec=AnimationSpec{"
                 + "durationMillis=0, delayMillis=0, easing=null, repeatable=null}}");
   }
 
@@ -104,11 +105,13 @@
     DynamicColor animatedColor = DynamicColor.animate(STATE_KEY);
     DynamicColor animatedColorWithSpec = DynamicColor.animate(STATE_KEY, SPEC);
 
-    assertThat(animatedColor.toDynamicColorProto().getAnimatableDynamic().hasSpec()).isFalse();
+    assertThat(animatedColor.toDynamicColorProto().getAnimatableDynamic().hasAnimationSpec())
+        .isFalse();
     assertThat(animatedColorWithSpec.toDynamicColorProto().getAnimatableDynamic().getInput())
         .isEqualTo(stateColor.toDynamicColorProto());
-    assertThat(animatedColorWithSpec.toDynamicColorProto().getAnimatableDynamic().getSpec())
-        .isEqualTo(SPEC.toProto());
+    assertThat(
+            animatedColorWithSpec.toDynamicColorProto().getAnimatableDynamic().getAnimationSpec()
+    ).isEqualTo(SPEC.toProto());
     assertThat(animatedColor.toDynamicColorProto())
         .isEqualTo(stateColor.animate().toDynamicColorProto());
   }
@@ -121,7 +124,7 @@
                 .toString())
         .isEqualTo(
             "AnimatableDynamicColor{"
-                + "input=StateColorSource{sourceKey=key}, spec=AnimationSpec{"
+                + "input=StateColorSource{sourceKey=key}, animationSpec=AnimationSpec{"
                 + "durationMillis=0, delayMillis=1, easing=null, repeatable=null}}");
   }
 
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
index 731406e..dc0344e 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
@@ -153,12 +153,13 @@
     DynamicFloat animatedFloat = DynamicFloat.animate(startFloat, endFloat);
     DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(startFloat, endFloat, SPEC);
 
-    assertThat(animatedFloat.toDynamicFloatProto().getAnimatableFixed().hasSpec()).isFalse();
+    assertThat(animatedFloat.toDynamicFloatProto().getAnimatableFixed().hasAnimationSpec())
+        .isFalse();
     assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableFixed().getFromValue())
         .isEqualTo(startFloat);
     assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableFixed().getToValue())
         .isEqualTo(endFloat);
-    assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableFixed().getSpec())
+    assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableFixed().getAnimationSpec())
         .isEqualTo(SPEC.toProto());
   }
 
@@ -171,7 +172,7 @@
                     new AnimationSpec.Builder().setDelayMillis(0).build())
                 .toString())
         .isEqualTo(
-            "AnimatableFixedFloat{fromValue=1.0, toValue=2.0, spec=AnimationSpec{"
+            "AnimatableFixedFloat{fromValue=1.0, toValue=2.0, animationSpec=AnimationSpec{"
                 + "durationMillis=0, delayMillis=0, easing=null, repeatable=null}}");
   }
 
@@ -182,11 +183,13 @@
     DynamicFloat animatedFloat = DynamicFloat.animate(STATE_KEY);
     DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(STATE_KEY, SPEC);
 
-    assertThat(animatedFloat.toDynamicFloatProto().getAnimatableDynamic().hasSpec()).isFalse();
+    assertThat(animatedFloat.toDynamicFloatProto().getAnimatableDynamic().hasAnimationSpec())
+        .isFalse();
     assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableDynamic().getInput())
         .isEqualTo(stateFloat.toDynamicFloatProto());
-    assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableDynamic().getSpec())
-        .isEqualTo(SPEC.toProto());
+    assertThat(
+            animatedFloatWithSpec.toDynamicFloatProto().getAnimatableDynamic().getAnimationSpec()
+    ).isEqualTo(SPEC.toProto());
     assertThat(animatedFloat.toDynamicFloatProto())
         .isEqualTo(stateFloat.animate().toDynamicFloatProto());
   }
@@ -199,7 +202,7 @@
                 .toString())
         .isEqualTo(
             "AnimatableDynamicFloat{"
-                + "input=StateFloatSource{sourceKey=key}, spec=AnimationSpec{"
+                + "input=StateFloatSource{sourceKey=key}, animationSpec=AnimationSpec{"
                 + "durationMillis=0, delayMillis=1, easing=null, repeatable=null}}");
   }
 
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto b/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
index 52dfa35..67d6ff8 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
@@ -26,9 +26,6 @@
   // "ACTIVITY_RECOGNITION" permission granted to it. If this permission is not
   // present, this source type will never yield any data.
   PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT = 2;
-
-  // The current epoch time in seconds.
-  PLATFORM_INT32_SOURCE_TYPE_EPOCH_TIME_SECONDS = 3;
 }
 
 // A dynamic Int32 which sources its data from some platform data source, e.g.
@@ -141,7 +138,7 @@
   int32 to_value = 2;
 
   // The animation parameters for duration, delay, etc.
-  AnimationSpec spec = 3;
+  AnimationSpec animation_spec = 3;
 }
 
 // A dynamic interpolation node. This will watch the value of its input and,
@@ -157,7 +154,7 @@
   DynamicInt32 input = 1;
 
   // The animation parameters for duration, delay, etc.
-  AnimationSpec spec = 2;
+  AnimationSpec animation_spec = 2;
 }
 
 // A dynamic int32 type.
@@ -189,6 +186,7 @@
     StateInt32Source state_source = 4;
     ConditionalInt32Op conditional_op = 5;
     FloatToInt32Op float_to_int = 6;
+    GetDurationPartOp duration_part = 7;
     AnimatableFixedInt32 animatable_fixed = 8;
     AnimatableDynamicInt32 animatable_dynamic = 9;
   }
@@ -319,7 +317,7 @@
   float to_value = 2;
 
   // The animation parameters for duration, delay, etc.
-  AnimationSpec spec = 3;
+  AnimationSpec animation_spec = 3;
 }
 
 // A dynamic interpolation node. This will watch the value of its input and,
@@ -335,7 +333,7 @@
   DynamicFloat input = 1;
 
   // The animation parameters for duration, delay, etc.
-  AnimationSpec spec = 3;
+  AnimationSpec animation_spec = 3;
 }
 
 // A dynamic float type.
@@ -490,7 +488,7 @@
   uint32 to_argb = 2;
 
   // The animation parameters for duration, delay, etc.
-  AnimationSpec spec = 3;
+  AnimationSpec animation_spec = 3;
 }
 
 // A dynamic interpolation node. This will watch the value of its input and,
@@ -506,7 +504,7 @@
   DynamicColor input = 1;
 
   // The animation parameters for duration, delay, etc.
-  AnimationSpec spec = 3;
+  AnimationSpec animation_spec = 3;
 }
 
 // A dynamic color type.
@@ -518,3 +516,86 @@
     AnimatableDynamicColor animatable_dynamic = 4;
   }
 }
+
+// A dynamic time instant that sources its value from the platform.
+message PlatformTimeSource {}
+
+// A dynamic time instant type.
+message DynamicInstant {
+  oneof inner {
+    FixedInstant fixed = 1;
+    PlatformTimeSource platform_source = 2;
+  }
+}
+
+// A dynamic duration type that represents the duration between two dynamic time
+// instants.
+message BetweenDuration {
+  // The time instant value marking the start of the duration.
+  DynamicInstant start_inclusive = 1;
+
+  // The time instant value marking the end of the duration.
+  DynamicInstant end_exclusive = 2;
+}
+
+// A dynamic duration type.
+message DynamicDuration {
+  oneof inner {
+    BetweenDuration between = 1;
+  }
+}
+
+// The duration part to retrieve using GetDurationPartOp.
+enum DurationPartType {
+  // Undefined duration part type.
+  DURATION_PART_TYPE_UNDEFINED = 0;
+
+  // Total number of days in a duration. The fraction part of the result will be
+  // truncated. This is based on the standard definition of a day as 24 hours.
+  // Notice that the duration can be negative, in which case total number of
+  // days will be also negative.
+  DURATION_PART_TYPE_TOTAL_DAYS = 1;
+
+  // Total number of hours in a duration. The fraction part of the result will
+  // be truncated. Notice that the duration can be negative, in which case total
+  // number of hours will be also negative.
+  DURATION_PART_TYPE_TOTAL_HOURS = 2;
+
+  // Total number of minutes in a duration. The fraction part of the result will
+  // be truncated. Notice that the duration can be negative, in which case total
+  // number of minutes will be also negative.
+  DURATION_PART_TYPE_TOTAL_MINUTES = 3;
+
+  // Total number of seconds in a duration. Notice that the duration can be
+  // negative, in which case total number of seconds will be also negative.
+  DURATION_PART_TYPE_TOTAL_SECONDS = 4;
+
+  // Number of days part in the duration. This represents the absolute value of
+  // the total number of days in the duration based on the 24 hours day
+  // definition. The fraction part of the result will be truncated.
+  DURATION_PART_TYPE_DAYS = 5;
+
+  // Number of hours part in the duration. This represents the absolute value of
+  // remaining hours when dividing total hours by hours in a day (24 hours).
+  DURATION_PART_TYPE_HOURS = 6;
+
+  // Number of minutes part in the duration. This represents the absolute value
+  // of remaining minutes when dividing total minutes by minutes in an hour (60
+  // minutes).
+  DURATION_PART_TYPE_MINUTES = 7;
+
+  // Number of seconds part in the duration. This represents the absolute value
+  // of remaining seconds when dividing total seconds by seconds in a minute (60
+  // seconds).
+  DURATION_PART_TYPE_SECONDS = 8;
+}
+
+// Retrieve the specified duration part of a DynamicDuration instance as a
+// DynamicInt32.
+message GetDurationPartOp {
+  // The duration input.
+  DynamicDuration input = 1;
+
+  // The duration part to retrieve.
+  DurationPartType duration_part = 2;
+}
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/fixed.proto b/wear/protolayout/protolayout-proto/src/main/proto/fixed.proto
index f09c002..bc87d47 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/fixed.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/fixed.proto
@@ -36,3 +36,10 @@
   // The color value, in ARGB format.
   uint32 argb = 1;
 }
+
+// A fixed time instant type.
+message FixedInstant {
+  // The number of seconds that have elapsed since 00:00:00 UTC on 1 January
+  // 1970.
+  int64 epoch_seconds = 1;
+}
diff --git a/wear/protolayout/protolayout/api/current.txt b/wear/protolayout/protolayout/api/current.txt
index 708d1ef..497290d 100644
--- a/wear/protolayout/protolayout/api/current.txt
+++ b/wear/protolayout/protolayout/api/current.txt
@@ -177,9 +177,7 @@
     method public static androidx.wear.protolayout.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
     method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(int);
     method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(float);
-    method public static androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp expand();
     method public static androidx.wear.protolayout.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
-    method public static androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp wrap();
   }
 
   public static interface DimensionBuilders.ContainerDimension {
@@ -219,14 +217,6 @@
     method public androidx.wear.protolayout.DimensionBuilders.EmProp.Builder setValue(float);
   }
 
-  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension {
-  }
-
-  public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension.Builder androidx.wear.protolayout.DimensionBuilders.ImageDimension.Builder {
-    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
-    method public androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp build();
-  }
-
   public static interface DimensionBuilders.ImageDimension {
   }
 
@@ -263,14 +253,6 @@
     method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension build();
   }
 
-  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension {
-  }
-
-  public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension.Builder {
-    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
-    method public androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp build();
-  }
-
   public final class LayoutElementBuilders {
     field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
     field public static final int ARC_ANCHOR_END = 3; // 0x3
@@ -857,10 +839,26 @@
   }
 
   public final class ResourceBuilders {
+    field public static final int ANIMATED_IMAGE_FORMAT_AVD = 1; // 0x1
+    field public static final int ANIMATED_IMAGE_FORMAT_UNDEFINED = 0; // 0x0
     field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
     field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
   }
 
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method @DrawableRes public int getResourceId();
+    method public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
+  }
+
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setStartTrigger(androidx.wear.protolayout.TriggerBuilders.Trigger);
+  }
+
   public static final class ResourceBuilders.AndroidImageResourceByResId {
     method @DrawableRes public int getResourceId();
   }
@@ -871,15 +869,33 @@
     method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
   }
 
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setProgress(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
   public static final class ResourceBuilders.ImageResource {
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
     method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
     method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
   }
 
   public static final class ResourceBuilders.ImageResource.Builder {
     ctor public ResourceBuilders.ImageResource.Builder();
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource build();
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId);
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId);
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidSeekableAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId);
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.protolayout.ResourceBuilders.InlineImageResource);
   }
 
@@ -964,6 +980,32 @@
     method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.protolayout.TimelineBuilders.TimeInterval);
   }
 
+  public final class TriggerBuilders {
+    method public static androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.TriggerBuilders.OnLoadTrigger createOnLoadTrigger();
+  }
+
+  public static final class TriggerBuilders.OnConditionMetTrigger implements androidx.wear.protolayout.TriggerBuilders.Trigger {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool? getTrigger();
+  }
+
+  public static final class TriggerBuilders.OnConditionMetTrigger.Builder {
+    ctor public TriggerBuilders.OnConditionMetTrigger.Builder();
+    method public androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger build();
+    method public androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger.Builder setTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+  }
+
+  public static final class TriggerBuilders.OnLoadTrigger implements androidx.wear.protolayout.TriggerBuilders.Trigger {
+  }
+
+  public static final class TriggerBuilders.OnLoadTrigger.Builder {
+    ctor public TriggerBuilders.OnLoadTrigger.Builder();
+    method public androidx.wear.protolayout.TriggerBuilders.OnLoadTrigger build();
+  }
+
+  public static interface TriggerBuilders.Trigger {
+  }
+
   public final class TypeBuilders {
   }
 
diff --git a/wear/protolayout/protolayout/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
index 07b1006..0d15cce 100644
--- a/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
@@ -189,9 +189,7 @@
     method public static androidx.wear.protolayout.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
     method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(int);
     method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(float);
-    method public static androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp expand();
     method public static androidx.wear.protolayout.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
-    method public static androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp wrap();
   }
 
   public static interface DimensionBuilders.ContainerDimension {
@@ -231,14 +229,6 @@
     method public androidx.wear.protolayout.DimensionBuilders.EmProp.Builder setValue(float);
   }
 
-  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension {
-  }
-
-  public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension.Builder androidx.wear.protolayout.DimensionBuilders.ImageDimension.Builder {
-    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
-    method public androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp build();
-  }
-
   public static interface DimensionBuilders.ImageDimension {
   }
 
@@ -275,14 +265,6 @@
     method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension build();
   }
 
-  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension {
-  }
-
-  public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension.Builder {
-    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
-    method public androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp build();
-  }
-
   public final class LayoutElementBuilders {
     field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
     field public static final int ARC_ANCHOR_END = 3; // 0x3
@@ -885,10 +867,26 @@
   }
 
   public final class ResourceBuilders {
+    field public static final int ANIMATED_IMAGE_FORMAT_AVD = 1; // 0x1
+    field public static final int ANIMATED_IMAGE_FORMAT_UNDEFINED = 0; // 0x0
     field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
     field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
   }
 
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method @DrawableRes public int getResourceId();
+    method public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
+  }
+
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setStartTrigger(androidx.wear.protolayout.TriggerBuilders.Trigger);
+  }
+
   public static final class ResourceBuilders.AndroidImageResourceByResId {
     method @DrawableRes public int getResourceId();
   }
@@ -899,15 +897,33 @@
     method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
   }
 
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setProgress(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
   public static final class ResourceBuilders.ImageResource {
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
     method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
     method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
   }
 
   public static final class ResourceBuilders.ImageResource.Builder {
     ctor public ResourceBuilders.ImageResource.Builder();
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource build();
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId);
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId);
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidSeekableAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId);
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.protolayout.ResourceBuilders.InlineImageResource);
   }
 
@@ -928,10 +944,8 @@
   }
 
   public static final class ResourceBuilders.Resources {
-    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.ResourceBuilders.Resources? fromByteArray(byte[]);
     method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ResourceBuilders.ImageResource!> getIdToImageMapping();
     method public String getVersion();
-    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public byte[] toByteArray();
   }
 
   public static final class ResourceBuilders.Resources.Builder {
@@ -994,6 +1008,32 @@
     method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.protolayout.TimelineBuilders.TimeInterval);
   }
 
+  public final class TriggerBuilders {
+    method public static androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.TriggerBuilders.OnLoadTrigger createOnLoadTrigger();
+  }
+
+  public static final class TriggerBuilders.OnConditionMetTrigger implements androidx.wear.protolayout.TriggerBuilders.Trigger {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool? getTrigger();
+  }
+
+  public static final class TriggerBuilders.OnConditionMetTrigger.Builder {
+    ctor public TriggerBuilders.OnConditionMetTrigger.Builder();
+    method public androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger build();
+    method public androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger.Builder setTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+  }
+
+  public static final class TriggerBuilders.OnLoadTrigger implements androidx.wear.protolayout.TriggerBuilders.Trigger {
+  }
+
+  public static final class TriggerBuilders.OnLoadTrigger.Builder {
+    ctor public TriggerBuilders.OnLoadTrigger.Builder();
+    method public androidx.wear.protolayout.TriggerBuilders.OnLoadTrigger build();
+  }
+
+  public static interface TriggerBuilders.Trigger {
+  }
+
   public final class TypeBuilders {
   }
 
diff --git a/wear/protolayout/protolayout/api/restricted_current.txt b/wear/protolayout/protolayout/api/restricted_current.txt
index 708d1ef..497290d 100644
--- a/wear/protolayout/protolayout/api/restricted_current.txt
+++ b/wear/protolayout/protolayout/api/restricted_current.txt
@@ -177,9 +177,7 @@
     method public static androidx.wear.protolayout.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
     method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(int);
     method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(float);
-    method public static androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp expand();
     method public static androidx.wear.protolayout.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
-    method public static androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp wrap();
   }
 
   public static interface DimensionBuilders.ContainerDimension {
@@ -219,14 +217,6 @@
     method public androidx.wear.protolayout.DimensionBuilders.EmProp.Builder setValue(float);
   }
 
-  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension {
-  }
-
-  public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension.Builder androidx.wear.protolayout.DimensionBuilders.ImageDimension.Builder {
-    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
-    method public androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp build();
-  }
-
   public static interface DimensionBuilders.ImageDimension {
   }
 
@@ -263,14 +253,6 @@
     method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension build();
   }
 
-  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension {
-  }
-
-  public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension.Builder {
-    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
-    method public androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp build();
-  }
-
   public final class LayoutElementBuilders {
     field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
     field public static final int ARC_ANCHOR_END = 3; // 0x3
@@ -857,10 +839,26 @@
   }
 
   public final class ResourceBuilders {
+    field public static final int ANIMATED_IMAGE_FORMAT_AVD = 1; // 0x1
+    field public static final int ANIMATED_IMAGE_FORMAT_UNDEFINED = 0; // 0x0
     field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
     field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
   }
 
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method @DrawableRes public int getResourceId();
+    method public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
+  }
+
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setStartTrigger(androidx.wear.protolayout.TriggerBuilders.Trigger);
+  }
+
   public static final class ResourceBuilders.AndroidImageResourceByResId {
     method @DrawableRes public int getResourceId();
   }
@@ -871,15 +869,33 @@
     method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
   }
 
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setProgress(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
   public static final class ResourceBuilders.ImageResource {
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
     method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
     method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
   }
 
   public static final class ResourceBuilders.ImageResource.Builder {
     ctor public ResourceBuilders.ImageResource.Builder();
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource build();
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId);
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId);
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidSeekableAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId);
     method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.protolayout.ResourceBuilders.InlineImageResource);
   }
 
@@ -964,6 +980,32 @@
     method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.protolayout.TimelineBuilders.TimeInterval);
   }
 
+  public final class TriggerBuilders {
+    method public static androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.TriggerBuilders.OnLoadTrigger createOnLoadTrigger();
+  }
+
+  public static final class TriggerBuilders.OnConditionMetTrigger implements androidx.wear.protolayout.TriggerBuilders.Trigger {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool? getTrigger();
+  }
+
+  public static final class TriggerBuilders.OnConditionMetTrigger.Builder {
+    ctor public TriggerBuilders.OnConditionMetTrigger.Builder();
+    method public androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger build();
+    method public androidx.wear.protolayout.TriggerBuilders.OnConditionMetTrigger.Builder setTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+  }
+
+  public static final class TriggerBuilders.OnLoadTrigger implements androidx.wear.protolayout.TriggerBuilders.Trigger {
+  }
+
+  public static final class TriggerBuilders.OnLoadTrigger.Builder {
+    ctor public TriggerBuilders.OnLoadTrigger.Builder();
+    method public androidx.wear.protolayout.TriggerBuilders.OnLoadTrigger build();
+  }
+
+  public static interface TriggerBuilders.Trigger {
+  }
+
   public final class TypeBuilders {
   }
 
diff --git a/wear/protolayout/protolayout/build.gradle b/wear/protolayout/protolayout/build.gradle
index e622d23..0cc935b 100644
--- a/wear/protolayout/protolayout/build.gradle
+++ b/wear/protolayout/protolayout/build.gradle
@@ -41,7 +41,7 @@
     namespace "androidx.wear.protolayout"
 
     defaultConfig {
-        minSdkVersion 25
+        minSdkVersion 26
     }
     buildTypes.all {
         consumerProguardFiles "proguard-rules.pro"
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java
index e900f65..0a6f3b0 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021-2022 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,8 +20,6 @@
 import static androidx.annotation.Dimension.SP;
 
 import android.annotation.SuppressLint;
-import android.content.Context;
-import android.util.DisplayMetrics;
 import androidx.annotation.Dimension;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
@@ -30,14 +28,12 @@
 import androidx.annotation.RestrictTo.Scope;
 import androidx.wear.protolayout.expression.Fingerprint;
 import androidx.wear.protolayout.proto.DimensionProto;
+import androidx.wear.protolayout.proto.TypesProto;
 
 /** Builders for dimensions for layout elements. */
 public final class DimensionBuilders {
   private DimensionBuilders() {}
 
-  private static final ExpandedDimensionProp EXPAND = new ExpandedDimensionProp.Builder().build();
-  private static final WrappedDimensionProp WRAP = new WrappedDimensionProp.Builder().build();
-
   /** Shortcut for building a {@link DpProp} using a measurement in DP. */
   @NonNull
   public static DpProp dp(@Dimension(unit = DP) float valueDp) {
@@ -68,25 +64,10 @@
     return new DegreesProp.Builder().setValue(valueDegrees).build();
   }
 
-  /**
-   * Shortcut for building an {@link ExpandedDimensionProp} that will expand to the size of its
-   * parent.
+  /** A type for linear dimensions, measured in dp.
+   *
+   * @since 1.0
    */
-  @NonNull
-  public static ExpandedDimensionProp expand() {
-    return EXPAND;
-  }
-
-  /**
-   * Shortcut for building an {@link WrappedDimensionProp} that will shrink to the size of its
-   * children.
-   */
-  @NonNull
-  public static WrappedDimensionProp wrap() {
-    return WRAP;
-  }
-
-  /** A type for linear dimensions, measured in dp. */
   public static final class DpProp implements ContainerDimension, ImageDimension, SpacerDimension {
     private final DimensionProto.DpProp mImpl;
     @Nullable private final Fingerprint mFingerprint;
@@ -96,7 +77,11 @@
       this.mFingerprint = fingerprint;
     }
 
-    /** Gets the value, in dp. Intended for testing purposes only. */
+    /**
+     * Gets the value, in dp.
+     *
+     * @since 1.0
+     */
     @Dimension(unit = DP)
     public float getValue() {
       return mImpl.getValue();
@@ -148,11 +133,15 @@
     public static final class Builder
         implements ContainerDimension.Builder, ImageDimension.Builder, SpacerDimension.Builder {
       private final DimensionProto.DpProp.Builder mImpl = DimensionProto.DpProp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(752970309);
+      private final Fingerprint mFingerprint = new Fingerprint(756413087);
 
       public Builder() {}
 
-      /** Sets the value, in dp. */
+      /**
+       * Sets the value, in dp.
+       *
+       * @since 1.0
+       */
       @NonNull
       public Builder setValue(@Dimension(unit = DP) float value) {
         mImpl.setValue(value);
@@ -168,7 +157,11 @@
     }
   }
 
-  /** A type for font sizes, measured in sp. */
+  /**
+   * A type for font sizes, measured in sp.
+   *
+   * @since 1.0
+   */
   public static final class SpProp {
     private final DimensionProto.SpProp mImpl;
     @Nullable private final Fingerprint mFingerprint;
@@ -178,7 +171,11 @@
       this.mFingerprint = fingerprint;
     }
 
-    /** Gets the value, in sp. Intended for testing purposes only. */
+    /**
+     * Gets the value, in sp.
+     *
+     * @since 1.0
+     */
     @Dimension(unit = SP)
     public float getValue() {
       return mImpl.getValue();
@@ -208,11 +205,15 @@
     /** Builder for {@link SpProp} */
     public static final class Builder {
       private final DimensionProto.SpProp.Builder mImpl = DimensionProto.SpProp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-2144685857);
+      private final Fingerprint mFingerprint = new Fingerprint(631793260);
 
       public Builder() {}
 
-      /** Sets the value, in sp. */
+      /**
+       * Sets the value, in sp.
+       *
+       * @since 1.0
+       */
       @NonNull
       public Builder setValue(@Dimension(unit = SP) float value) {
         mImpl.setValue(value);
@@ -228,7 +229,11 @@
     }
   }
 
-  /** A type for font spacing, measured in em. */
+  /**
+   * A type for font spacing, measured in em.
+   *
+   * @since 1.0
+   */
   public static final class EmProp {
     private final DimensionProto.EmProp mImpl;
     @Nullable private final Fingerprint mFingerprint;
@@ -238,7 +243,11 @@
       this.mFingerprint = fingerprint;
     }
 
-    /** Gets the value, in em. Intended for testing purposes only. */
+    /**
+     * Gets the value, in em.
+     *
+     * @since 1.0
+     */
     public float getValue() {
       return mImpl.getValue();
     }
@@ -267,11 +276,15 @@
     /** Builder for {@link EmProp} */
     public static final class Builder {
       private final DimensionProto.EmProp.Builder mImpl = DimensionProto.EmProp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1628313311);
+      private final Fingerprint mFingerprint = new Fingerprint(-659639046);
 
       public Builder() {}
 
-      /** Sets the value, in em. */
+      /**
+       * Sets the value, in em.
+       *
+       * @since 1.0
+       */
       @NonNull
       public Builder setValue(float value) {
         mImpl.setValue(value);
@@ -287,7 +300,11 @@
     }
   }
 
-  /** A type for angular dimensions, measured in degrees. */
+  /**
+   * A type for angular dimensions, measured in degrees.
+   *
+   * @since 1.0
+   */
   public static final class DegreesProp {
     private final DimensionProto.DegreesProp mImpl;
     @Nullable private final Fingerprint mFingerprint;
@@ -297,7 +314,11 @@
       this.mFingerprint = fingerprint;
     }
 
-    /** Gets the value, in degrees. Intended for testing purposes only. */
+    /**
+     * Gets the value, in degrees.
+     *
+     * @since 1.0
+     */
     public float getValue() {
       return mImpl.getValue();
     }
@@ -327,11 +348,15 @@
     public static final class Builder {
       private final DimensionProto.DegreesProp.Builder mImpl =
           DimensionProto.DegreesProp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(405060347);
+      private final Fingerprint mFingerprint = new Fingerprint(-1927567665);
 
       public Builder() {}
 
-      /** Sets the value, in degrees. */
+      /**
+       * Sets the value, in degrees.
+       *
+       * @since 1.0
+       */
       @NonNull
       public Builder setValue(float value) {
         mImpl.setValue(value);
@@ -349,7 +374,11 @@
 
   /**
    * A type for a dimension that fills all the space it can (i.e. MATCH_PARENT in Android parlance).
+   *
+   * @since 1.0
+   * @hide
    */
+  @RestrictTo(Scope.LIBRARY_GROUP)
   public static final class ExpandedDimensionProp implements ContainerDimension, ImageDimension {
     private final DimensionProto.ExpandedDimensionProp mImpl;
     @Nullable private final Fingerprint mFingerprint;
@@ -360,6 +389,19 @@
       this.mFingerprint = fingerprint;
     }
 
+    /**
+     * Gets the layout weight (a dimensionless scalar value) for this element. This will only affect
+     * the width of children of a {@link androidx.wear.protolayout.LayoutElementBuilders.Row} or the
+     * height of children of a {@link androidx.wear.protolayout.LayoutElementBuilders.Column}. By
+     * default, all children have equal weight. Where applicable, the width or height of the element
+     * is proportional to the sum of the weights of its siblings.
+     *
+     * @since 1.2
+     */
+    public float getLayoutWeight() {
+      return mImpl.getLayoutWeight().getValue();
+    }
+
     /** @hide */
     @Override
     @RestrictTo(Scope.LIBRARY_GROUP)
@@ -399,10 +441,27 @@
         implements ContainerDimension.Builder, ImageDimension.Builder {
       private final DimensionProto.ExpandedDimensionProp.Builder mImpl =
           DimensionProto.ExpandedDimensionProp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1053378170);
+      private final Fingerprint mFingerprint = new Fingerprint(-997720604);
 
       public Builder() {}
 
+      /**
+       * Sets the layout weight (a dimensionless scalar value) for this element. This will only
+       * affect the width of children of a {@link
+       * androidx.wear.protolayout.LayoutElementBuilders.Row} or the height of children of a {@link
+       * androidx.wear.protolayout.LayoutElementBuilders.Column}. By default, all children have
+       * equal weight. Where applicable, the width or height of the element is proportional to the
+       * sum of the weights of its siblings.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setLayoutWeight(float layoutWeight) {
+        mImpl.setLayoutWeight(TypesProto.FloatProp.newBuilder().setValue(layoutWeight));
+        mFingerprint.recordPropertyUpdate(1, Float.floatToIntBits(layoutWeight));
+        return this;
+      }
+
       @Override
       @NonNull
       public ExpandedDimensionProp build() {
@@ -414,7 +473,11 @@
   /**
    * A type for a dimension that sizes itself to the size of its children (i.e. WRAP_CONTENT in
    * Android parlance).
+   *
+   * @since 1.0
+   * @hide
    */
+  @RestrictTo(Scope.LIBRARY_GROUP)
   public static final class WrappedDimensionProp implements ContainerDimension {
     private final DimensionProto.WrappedDimensionProp mImpl;
     @Nullable private final Fingerprint mFingerprint;
@@ -425,6 +488,16 @@
       this.mFingerprint = fingerprint;
     }
 
+    /**
+     * Gets the minimum size of this dimension. If not set, then there is no minimum size.
+     *
+     * @since 1.2
+     */
+    @Dimension(unit = DP)
+    public float getMinimumSizeDp() {
+      return mImpl.getMinimumSize().getValue();
+    }
+
     /** @hide */
     @Override
     @RestrictTo(Scope.LIBRARY_GROUP)
@@ -455,10 +528,22 @@
     public static final class Builder implements ContainerDimension.Builder {
       private final DimensionProto.WrappedDimensionProp.Builder mImpl =
           DimensionProto.WrappedDimensionProp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-113456542);
+      private final Fingerprint mFingerprint = new Fingerprint(1118918114);
 
       public Builder() {}
 
+      /**
+       * Sets the minimum size of this dimension. If not set, then there is no minimum size.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setMinimumSizeDp(@Dimension(unit = DP) float minimumSize) {
+        mImpl.setMinimumSize(DimensionProto.DpProp.newBuilder().setValue(minimumSize));
+        mFingerprint.recordPropertyUpdate(1, Float.floatToIntBits(minimumSize));
+        return this;
+      }
+
       @Override
       @NonNull
       public WrappedDimensionProp build() {
@@ -475,6 +560,8 @@
    * specifying an element's size using common ratios (e.g. width=4, height=3), or to allow an
    * element to be resized proportionally based on the size of an underlying asset (e.g. an 800x600
    * image being added to a smaller container and resized accordingly).
+   *
+   * @since 1.0
    */
   public static final class ProportionalDimensionProp implements ImageDimension {
     private final DimensionProto.ProportionalDimensionProp mImpl;
@@ -487,8 +574,9 @@
     }
 
     /**
-     * Gets the width to be used when calculating the aspect ratio to preserve. Intended for testing
-     * purposes only.
+     * Gets the width to be used when calculating the aspect ratio to preserve.
+     *
+     * @since 1.0
      */
     @IntRange(from = 0)
     public int getAspectRatioWidth() {
@@ -496,8 +584,9 @@
     }
 
     /**
-     * Gets the height to be used when calculating the aspect ratio ratio to preserve. Intended for
-     * testing purposes only.
+     * Gets the height to be used when calculating the aspect ratio ratio to preserve.
+     *
+     * @since 1.0
      */
     @IntRange(from = 0)
     public int getAspectRatioHeight() {
@@ -535,11 +624,15 @@
     public static final class Builder implements ImageDimension.Builder {
       private final DimensionProto.ProportionalDimensionProp.Builder mImpl =
           DimensionProto.ProportionalDimensionProp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-2079046835);
+      private final Fingerprint mFingerprint = new Fingerprint(1725027476);
 
       public Builder() {}
 
-      /** Sets the width to be used when calculating the aspect ratio to preserve. */
+      /**
+       * Sets the width to be used when calculating the aspect ratio to preserve.
+       *
+       * @since 1.0
+       */
       @NonNull
       public Builder setAspectRatioWidth(@IntRange(from = 0) int aspectRatioWidth) {
         mImpl.setAspectRatioWidth(aspectRatioWidth);
@@ -547,7 +640,11 @@
         return this;
       }
 
-      /** Sets the height to be used when calculating the aspect ratio ratio to preserve. */
+      /**
+       * Sets the height to be used when calculating the aspect ratio ratio to preserve.
+       *
+       * @since 1.0
+       */
       @NonNull
       public Builder setAspectRatioHeight(@IntRange(from = 0) int aspectRatioHeight) {
         mImpl.setAspectRatioHeight(aspectRatioHeight);
@@ -563,7 +660,11 @@
     }
   }
 
-  /** Interface defining a dimension that can be applied to a container. */
+  /**
+   * Interface defining a dimension that can be applied to a container.
+   *
+   * @since 1.0
+   */
   public interface ContainerDimension {
     /**
      * Get the protocol buffer representation of this object.
@@ -608,7 +709,11 @@
     throw new IllegalStateException("Proto was not a recognised instance of ContainerDimension");
   }
 
-  /** Interface defining a dimension that can be applied to an image. */
+  /**
+   * Interface defining a dimension that can be applied to an image.
+   *
+   * @since 1.0
+   */
   public interface ImageDimension {
     /**
      * Get the protocol buffer representation of this object.
@@ -652,7 +757,11 @@
     throw new IllegalStateException("Proto was not a recognised instance of ImageDimension");
   }
 
-  /** Interface defining a dimension that can be applied to a spacer. */
+  /**
+   * Interface defining a dimension that can be applied to a spacer.
+   *
+   * @since 1.0
+   */
   public interface SpacerDimension {
     /**
      * Get the protocol buffer representation of this object.
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java
index 8e23d72..76dbb60 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021-2022 The Android Open Source Project
+ * Copyright 2022 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.
@@ -19,6 +19,7 @@
 import static androidx.annotation.Dimension.PX;
 
 import android.annotation.SuppressLint;
+
 import androidx.annotation.Dimension;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.IntDef;
@@ -26,10 +27,12 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
-import androidx.wear.protolayout.expression.ProtoLayoutExperimental;
+import androidx.wear.protolayout.TriggerBuilders.Trigger;
+import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
 import androidx.wear.protolayout.proto.ResourceProto;
 import androidx.wear.protolayout.protobuf.ByteString;
-import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Collections;
@@ -39,376 +42,733 @@
 
 /** Builders for the resources for a layout. */
 public final class ResourceBuilders {
-  private ResourceBuilders() {}
-
-  /**
-   * Format describing the contents of an image data byte array.
-   *
-   * @hide
-   */
-  @RestrictTo(RestrictTo.Scope.LIBRARY)
-  @IntDef({IMAGE_FORMAT_UNDEFINED, IMAGE_FORMAT_RGB_565})
-  @Retention(RetentionPolicy.SOURCE)
-  public @interface ImageFormat {}
-
-  /** An undefined image format. */
-  public static final int IMAGE_FORMAT_UNDEFINED = 0;
-
-  /**
-   * An image format where each pixel is stored on 2 bytes, with red using 5 bits, green using 6
-   * bits and blue using 5 bits of precision.
-   */
-  public static final int IMAGE_FORMAT_RGB_565 = 1;
-
-  /** An image resource which maps to an Android drawable by resource ID. */
-  public static final class AndroidImageResourceByResId {
-    private final ResourceProto.AndroidImageResourceByResId mImpl;
-
-    private AndroidImageResourceByResId(ResourceProto.AndroidImageResourceByResId impl) {
-      this.mImpl = impl;
-    }
+    private ResourceBuilders() {}
 
     /**
-     * Gets the Android resource ID of this image. This must refer to a drawable under R.drawable.
-     * Intended for testing purposes only.
-     */
-    @DrawableRes
-    public int getResourceId() {
-      return mImpl.getResourceId();
-    }
-
-    @NonNull
-    static AndroidImageResourceByResId fromProto(
-        @NonNull ResourceProto.AndroidImageResourceByResId proto) {
-      return new AndroidImageResourceByResId(proto);
-    }
-
-    @NonNull
-    ResourceProto.AndroidImageResourceByResId toProto() {
-      return mImpl;
-    }
-
-    /** Builder for {@link AndroidImageResourceByResId} */
-    public static final class Builder {
-      private final ResourceProto.AndroidImageResourceByResId.Builder mImpl =
-          ResourceProto.AndroidImageResourceByResId.newBuilder();
-
-      public Builder() {}
-
-      /**
-       * Sets the Android resource ID of this image. This must refer to a drawable under R.drawable.
-       */
-      @NonNull
-      public Builder setResourceId(@DrawableRes int resourceId) {
-        mImpl.setResourceId(resourceId);
-        return this;
-      }
-
-      /** Builds an instance from accumulated values. */
-      @NonNull
-      public AndroidImageResourceByResId build() {
-        return AndroidImageResourceByResId.fromProto(mImpl.build());
-      }
-    }
-  }
-
-  /**
-   * An image resource whose data is fully inlined, with no dependency on a system or app resource.
-   */
-  public static final class InlineImageResource {
-    private final ResourceProto.InlineImageResource mImpl;
-
-    private InlineImageResource(ResourceProto.InlineImageResource impl) {
-      this.mImpl = impl;
-    }
-
-    /** Gets the byte array representing the image. Intended for testing purposes only. */
-    @NonNull
-    public byte[] getData() {
-      return mImpl.getData().toByteArray();
-    }
-
-    /**
-     * Gets the native width of the image, in pixels. Only required for formats (e.g.
-     * IMAGE_FORMAT_RGB_565) where the image data does not include size. Intended for testing
-     * purposes only.
-     */
-    @Dimension(unit = PX)
-    public int getWidthPx() {
-      return mImpl.getWidthPx();
-    }
-
-    /**
-     * Gets the native height of the image, in pixels. Only required for formats (e.g.
-     * IMAGE_FORMAT_RGB_565) where the image data does not include size. Intended for testing
-     * purposes only.
-     */
-    @Dimension(unit = PX)
-    public int getHeightPx() {
-      return mImpl.getHeightPx();
-    }
-
-    /**
-     * Gets the format of the byte array data representing the image. May be left unspecified or set
-     * to IMAGE_FORMAT_UNDEFINED in which case the platform will attempt to extract this from the
-     * raw image data. If the platform does not support the format, the image will not be decoded or
-     * displayed. Intended for testing purposes only.
-     */
-    @ImageFormat
-    public int getFormat() {
-      return mImpl.getFormat().getNumber();
-    }
-
-    @NonNull
-    static InlineImageResource fromProto(@NonNull ResourceProto.InlineImageResource proto) {
-      return new InlineImageResource(proto);
-    }
-
-    @NonNull
-    ResourceProto.InlineImageResource toProto() {
-      return mImpl;
-    }
-
-    /** Builder for {@link InlineImageResource} */
-    public static final class Builder {
-      private final ResourceProto.InlineImageResource.Builder mImpl =
-          ResourceProto.InlineImageResource.newBuilder();
-
-      public Builder() {}
-
-      /** Sets the byte array representing the image. */
-      @NonNull
-      public Builder setData(@NonNull byte[] data) {
-        mImpl.setData(ByteString.copyFrom(data));
-        return this;
-      }
-
-      /**
-       * Sets the native width of the image, in pixels. Only required for formats (e.g.
-       * IMAGE_FORMAT_RGB_565) where the image data does not include size.
-       */
-      @NonNull
-      public Builder setWidthPx(@Dimension(unit = PX) int widthPx) {
-        mImpl.setWidthPx(widthPx);
-        return this;
-      }
-
-      /**
-       * Sets the native height of the image, in pixels. Only required for formats (e.g.
-       * IMAGE_FORMAT_RGB_565) where the image data does not include size.
-       */
-      @NonNull
-      public Builder setHeightPx(@Dimension(unit = PX) int heightPx) {
-        mImpl.setHeightPx(heightPx);
-        return this;
-      }
-
-      /**
-       * Sets the format of the byte array data representing the image. May be left unspecified or
-       * set to IMAGE_FORMAT_UNDEFINED in which case the platform will attempt to extract this from
-       * the raw image data. If the platform does not support the format, the image will not be
-       * decoded or displayed.
-       */
-      @NonNull
-      public Builder setFormat(@ImageFormat int format) {
-        mImpl.setFormat(ResourceProto.ImageFormat.forNumber(format));
-        return this;
-      }
-
-      /** Builds an instance from accumulated values. */
-      @NonNull
-      public InlineImageResource build() {
-        return InlineImageResource.fromProto(mImpl.build());
-      }
-    }
-  }
-
-  /**
-   * An image resource, which can be used by layouts. This holds multiple underlying resource types,
-   * which the underlying runtime will pick according to what it thinks is appropriate.
-   */
-  public static final class ImageResource {
-    private final ResourceProto.ImageResource mImpl;
-
-    private ImageResource(ResourceProto.ImageResource impl) {
-      this.mImpl = impl;
-    }
-
-    /**
-     * Gets an image resource that maps to an Android drawable by resource ID. Intended for testing
-     * purposes only.
-     */
-    @Nullable
-    public AndroidImageResourceByResId getAndroidResourceByResId() {
-      if (mImpl.hasAndroidResourceByResId()) {
-        return AndroidImageResourceByResId.fromProto(mImpl.getAndroidResourceByResId());
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Gets an image resource that contains the image data inline. Intended for testing purposes
-     * only.
-     */
-    @Nullable
-    public InlineImageResource getInlineResource() {
-      if (mImpl.hasInlineResource()) {
-        return InlineImageResource.fromProto(mImpl.getInlineResource());
-      } else {
-        return null;
-      }
-    }
-
-    @NonNull
-    static ImageResource fromProto(@NonNull ResourceProto.ImageResource proto) {
-      return new ImageResource(proto);
-    }
-
-    @NonNull
-    ResourceProto.ImageResource toProto() {
-      return mImpl;
-    }
-
-    /** Builder for {@link ImageResource} */
-    public static final class Builder {
-      private final ResourceProto.ImageResource.Builder mImpl =
-          ResourceProto.ImageResource.newBuilder();
-
-      public Builder() {}
-
-      /** Sets an image resource that maps to an Android drawable by resource ID. */
-      @NonNull
-      public Builder setAndroidResourceByResId(
-          @NonNull AndroidImageResourceByResId androidResourceByResId) {
-        mImpl.setAndroidResourceByResId(androidResourceByResId.toProto());
-        return this;
-      }
-
-      /** Sets an image resource that contains the image data inline. */
-      @NonNull
-      public Builder setInlineResource(@NonNull InlineImageResource inlineResource) {
-        mImpl.setInlineResource(inlineResource.toProto());
-        return this;
-      }
-
-      /** Builds an instance from accumulated values. */
-      @NonNull
-      public ImageResource build() {
-        return ImageResource.fromProto(mImpl.build());
-      }
-    }
-  }
-
-  /** The resources for a layout. */
-  public static final class Resources {
-    private final ResourceProto.Resources mImpl;
-
-    private Resources(ResourceProto.Resources impl) {
-      this.mImpl = impl;
-    }
-
-    /**
-     * Gets the version of this {@link Resources} instance.
+     * Format describing the contents of an image data byte array.
      *
-     * <p>Each tile specifies the version of resources it requires. After fetching a tile, the
-     * renderer will use the resources version specified by the tile to separately fetch the
-     * resources.
-     *
-     * <p>This value must match the version of the resources required by the tile for the tile to
-     * render successfully, and must match the resource version specified in {@link
-     * androidx.wear.tiles.RequestBuilders.ResourcesRequest} which triggered this request. Intended
-     * for testing purposes only.
-     */
-    @NonNull
-    public String getVersion() {
-      return mImpl.getVersion();
-    }
-
-    /**
-     * Gets a map of resource_ids to images, which can be used by layouts. Intended for testing
-     * purposes only.
-     */
-    @NonNull
-    public Map<String, ImageResource> getIdToImageMapping() {
-      Map<String, ImageResource> map = new HashMap<>();
-      for (Entry<String, ResourceProto.ImageResource> entry : mImpl.getIdToImageMap().entrySet()) {
-        map.put(entry.getKey(), ImageResource.fromProto(entry.getValue()));
-      }
-      return Collections.unmodifiableMap(map);
-    }
-
-    /** Converts to byte array representation. */
-    @NonNull
-    @ProtoLayoutExperimental
-    public byte[] toByteArray() {
-      return mImpl.toByteArray();
-    }
-
-    /** Converts from byte array representation. */
-    @SuppressWarnings("ProtoParseWithRegistry")
-    @Nullable
-    @ProtoLayoutExperimental
-    public static Resources fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return fromProto(ResourceProto.Resources.parseFrom(byteArray));
-      } catch (InvalidProtocolBufferException e) {
-        return null;
-      }
-    }
-
-    @NonNull
-    static Resources fromProto(@NonNull ResourceProto.Resources proto) {
-      return new Resources(proto);
-    }
-
-    /**
-     * Returns the internal proto instance.
-     *
+     * @since 1.0
      * @hide
      */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public ResourceProto.Resources toProto() {
-      return mImpl;
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({IMAGE_FORMAT_UNDEFINED, IMAGE_FORMAT_RGB_565})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ImageFormat {}
+
+    /**
+     * An undefined image format.
+     *
+     * @since 1.0
+     */
+    public static final int IMAGE_FORMAT_UNDEFINED = 0;
+
+    /**
+     * An image format where each pixel is stored on 2 bytes, with red using 5 bits, green using 6
+     * bits and blue using 5 bits of precision.
+     *
+     * @since 1.0
+     */
+    public static final int IMAGE_FORMAT_RGB_565 = 1;
+
+    /**
+     * Format describing the contents of an animated image.
+     *
+     * @since 1.2
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({ANIMATED_IMAGE_FORMAT_UNDEFINED, ANIMATED_IMAGE_FORMAT_AVD})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AnimatedImageFormat {}
+
+    /**
+     * An undefined image format.
+     *
+     * @since 1.2
+     */
+    public static final int ANIMATED_IMAGE_FORMAT_UNDEFINED = 0;
+
+    /**
+     * Android AnimatedVectorDrawable.
+     *
+     * @since 1.2
+     */
+    public static final int ANIMATED_IMAGE_FORMAT_AVD = 1;
+
+    /**
+     * An image resource which maps to an Android drawable by resource ID.
+     *
+     * @since 1.0
+     */
+    public static final class AndroidImageResourceByResId {
+        private final ResourceProto.AndroidImageResourceByResId mImpl;
+
+        AndroidImageResourceByResId(ResourceProto.AndroidImageResourceByResId impl) {
+            this.mImpl = impl;
+        }
+
+        /**
+         * Gets the Android resource ID of this image. This must refer to a drawable under
+         * R.drawable.
+         *
+         * @since 1.0
+         */
+        @DrawableRes
+        public int getResourceId() {
+            return mImpl.getResourceId();
+        }
+
+        @NonNull
+        static AndroidImageResourceByResId fromProto(
+                @NonNull ResourceProto.AndroidImageResourceByResId proto) {
+            return new AndroidImageResourceByResId(proto);
+        }
+
+        @NonNull
+        ResourceProto.AndroidImageResourceByResId toProto() {
+            return mImpl;
+        }
+
+        /** Builder for {@link AndroidImageResourceByResId} */
+        public static final class Builder {
+            private final ResourceProto.AndroidImageResourceByResId.Builder mImpl =
+                    ResourceProto.AndroidImageResourceByResId.newBuilder();
+
+            public Builder() {}
+
+            /**
+             * Sets the Android resource ID of this image. This must refer to a drawable under
+             * R.drawable.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setResourceId(@DrawableRes int resourceId) {
+                mImpl.setResourceId(resourceId);
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @NonNull
+            public AndroidImageResourceByResId build() {
+                return AndroidImageResourceByResId.fromProto(mImpl.build());
+            }
+        }
     }
 
-    /** Builder for {@link Resources} */
-    public static final class Builder {
-      private final ResourceProto.Resources.Builder mImpl = ResourceProto.Resources.newBuilder();
+    /**
+     * An image resource whose data is fully inlined, with no dependency on a system or app
+     * resource.
+     *
+     * @since 1.0
+     */
+    public static final class InlineImageResource {
+        private final ResourceProto.InlineImageResource mImpl;
 
-      public Builder() {}
+        InlineImageResource(ResourceProto.InlineImageResource impl) {
+            this.mImpl = impl;
+        }
 
-      /**
-       * Sets the version of this {@link Resources} instance.
-       *
-       * <p>Each tile specifies the version of resources it requires. After fetching a tile, the
-       * renderer will use the resources version specified by the tile to separately fetch the
-       * resources.
-       *
-       * <p>This value must match the version of the resources required by the tile for the tile to
-       * render successfully, and must match the resource version specified in {@link
-       * androidx.wear.tiles.RequestBuilders.ResourcesRequest} which triggered this request.
-       */
-      @NonNull
-      public Builder setVersion(@NonNull String version) {
-        mImpl.setVersion(version);
-        return this;
-      }
+        /**
+         * Gets the byte array representing the image.
+         *
+         * @since 1.0
+         */
+        @NonNull
+        public byte[] getData() {
+            return mImpl.getData().toByteArray();
+        }
 
-      /** Adds an entry into a map of resource_ids to images, which can be used by layouts. */
-      @SuppressLint("MissingGetterMatchingBuilder")
-      @NonNull
-      public Builder addIdToImageMapping(@NonNull String id, @NonNull ImageResource image) {
-        mImpl.putIdToImage(id, image.toProto());
-        return this;
-      }
+        /**
+         * Gets the native width of the image, in pixels. Only required for formats (e.g.
+         * IMAGE_FORMAT_RGB_565) where the image data does not include size.
+         *
+         * @since 1.0
+         */
+        @Dimension(unit = PX)
+        public int getWidthPx() {
+            return mImpl.getWidthPx();
+        }
 
-      /** Builds an instance from accumulated values. */
-      @NonNull
-      public Resources build() {
-        return Resources.fromProto(mImpl.build());
-      }
+        /**
+         * Gets the native height of the image, in pixels. Only required for formats (e.g.
+         * IMAGE_FORMAT_RGB_565) where the image data does not include size.
+         *
+         * @since 1.0
+         */
+        @Dimension(unit = PX)
+        public int getHeightPx() {
+            return mImpl.getHeightPx();
+        }
+
+        /**
+         * Gets the format of the byte array data representing the image. May be left unspecified or
+         * set to IMAGE_FORMAT_UNDEFINED in which case the platform will attempt to extract this
+         * from the raw image data. If the platform does not support the format, the image will not
+         * be decoded or displayed.
+         *
+         * @since 1.0
+         */
+        @ImageFormat
+        public int getFormat() {
+            return mImpl.getFormat().getNumber();
+        }
+
+        @NonNull
+        static InlineImageResource fromProto(@NonNull ResourceProto.InlineImageResource proto) {
+            return new InlineImageResource(proto);
+        }
+
+        @NonNull
+        ResourceProto.InlineImageResource toProto() {
+            return mImpl;
+        }
+
+        /** Builder for {@link InlineImageResource} */
+        public static final class Builder {
+            private final ResourceProto.InlineImageResource.Builder mImpl =
+                    ResourceProto.InlineImageResource.newBuilder();
+
+            public Builder() {}
+
+            /**
+             * Sets the byte array representing the image.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setData(@NonNull byte[] data) {
+                mImpl.setData(ByteString.copyFrom(data));
+                return this;
+            }
+
+            /**
+             * Sets the native width of the image, in pixels. Only required for formats (e.g.
+             * IMAGE_FORMAT_RGB_565) where the image data does not include size.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setWidthPx(@Dimension(unit = PX) int widthPx) {
+                mImpl.setWidthPx(widthPx);
+                return this;
+            }
+
+            /**
+             * Sets the native height of the image, in pixels. Only required for formats (e.g.
+             * IMAGE_FORMAT_RGB_565) where the image data does not include size.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setHeightPx(@Dimension(unit = PX) int heightPx) {
+                mImpl.setHeightPx(heightPx);
+                return this;
+            }
+
+            /**
+             * Sets the format of the byte array data representing the image. May be left
+             * unspecified or set to IMAGE_FORMAT_UNDEFINED in which case the platform will attempt
+             * to extract this from the raw image data. If the platform does not support the format,
+             * the image will not be decoded or displayed.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setFormat(@ImageFormat int format) {
+                mImpl.setFormat(ResourceProto.ImageFormat.forNumber(format));
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @NonNull
+            public InlineImageResource build() {
+                return InlineImageResource.fromProto(mImpl.build());
+            }
+        }
     }
-  }
+
+    /**
+     * A non-seekable animated image resource that maps to an Android drawable by resource ID. The
+     * animation is started with given trigger, fire and forget.
+     *
+     * @since 1.2
+     */
+    public static final class AndroidAnimatedImageResourceByResId {
+        private final ResourceProto.AndroidAnimatedImageResourceByResId mImpl;
+
+        AndroidAnimatedImageResourceByResId(
+                ResourceProto.AndroidAnimatedImageResourceByResId impl) {
+            this.mImpl = impl;
+        }
+
+        /**
+         * Gets the format for the animated image.
+         *
+         * @since 1.2
+         */
+        @AnimatedImageFormat
+        public int getAnimatedImageFormat() {
+            return mImpl.getFormat().getNumber();
+        }
+
+        /**
+         * Gets the Android resource ID, e.g. R.drawable.foo.
+         *
+         * @since 1.2
+         */
+        @DrawableRes
+        public int getResourceId() {
+            return mImpl.getResourceId();
+        }
+
+        /**
+         * Gets the trigger to start the animation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public Trigger getStartTrigger() {
+            if (mImpl.hasTrigger()) {
+                return TriggerBuilders.triggerFromProto(mImpl.getTrigger());
+            } else {
+                return null;
+            }
+        }
+
+        @NonNull
+        static AndroidAnimatedImageResourceByResId fromProto(
+                @NonNull ResourceProto.AndroidAnimatedImageResourceByResId proto) {
+            return new AndroidAnimatedImageResourceByResId(proto);
+        }
+
+        @NonNull
+        ResourceProto.AndroidAnimatedImageResourceByResId toProto() {
+            return mImpl;
+        }
+
+        /** Builder for {@link AndroidAnimatedImageResourceByResId} */
+        public static final class Builder {
+            private final ResourceProto.AndroidAnimatedImageResourceByResId.Builder mImpl =
+                    ResourceProto.AndroidAnimatedImageResourceByResId.newBuilder();
+
+            public Builder() {}
+
+            /**
+             * Sets the format for the animated image.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimatedImageFormat(@AnimatedImageFormat int format) {
+                mImpl.setFormat(ResourceProto.AnimatedImageFormat.forNumber(format));
+                return this;
+            }
+
+            /**
+             * Sets the Android resource ID, e.g. R.drawable.foo.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setResourceId(@DrawableRes int resourceId) {
+                mImpl.setResourceId(resourceId);
+                return this;
+            }
+
+            /**
+             * Sets the trigger to start the animation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setStartTrigger(@NonNull Trigger trigger) {
+                mImpl.setTrigger(trigger.toTriggerProto());
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @NonNull
+            public AndroidAnimatedImageResourceByResId build() {
+                return AndroidAnimatedImageResourceByResId.fromProto(mImpl.build());
+            }
+        }
+    }
+
+    /**
+     * A seekable animated image resource that maps to an Android drawable by resource ID. The
+     * animation progress is bound to the provided dynamic float.
+     *
+     * @since 1.2
+     */
+    public static final class AndroidSeekableAnimatedImageResourceByResId {
+        private final ResourceProto.AndroidSeekableAnimatedImageResourceByResId mImpl;
+
+        AndroidSeekableAnimatedImageResourceByResId(
+                ResourceProto.AndroidSeekableAnimatedImageResourceByResId impl) {
+            this.mImpl = impl;
+        }
+
+        /**
+         * Gets the format for the animated image.
+         *
+         * @since 1.2
+         */
+        @AnimatedImageFormat
+        public int getAnimatedImageFormat() {
+            return mImpl.getFormat().getNumber();
+        }
+
+        /**
+         * Gets the Android resource ID, e.g. R.drawable.foo.
+         *
+         * @since 1.2
+         */
+        @DrawableRes
+        public int getResourceId() {
+            return mImpl.getResourceId();
+        }
+
+        /**
+         * Gets a {@link DynamicFloat}, normally transformed from certain states with the data
+         * binding pipeline to control the progress of the animation. Its value is required to fall
+         * in the range of [0.0, 1.0]. Any values outside this range would be clamped. When the
+         * first value of the {@link DynamicFloat} arrives, the animation starts from progress 0 to
+         * that value. After that it plays from current progress to the new value on subsequent
+         * updates.
+         * If not set, the animation will play on load (similar to a non-seekable animated).
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getProgress() {
+            if (mImpl.hasProgress()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getProgress());
+            } else {
+                return null;
+            }
+        }
+
+        @NonNull
+        static AndroidSeekableAnimatedImageResourceByResId fromProto(
+                @NonNull ResourceProto.AndroidSeekableAnimatedImageResourceByResId proto) {
+            return new AndroidSeekableAnimatedImageResourceByResId(proto);
+        }
+
+        @NonNull
+        ResourceProto.AndroidSeekableAnimatedImageResourceByResId toProto() {
+            return mImpl;
+        }
+
+        /** Builder for {@link AndroidSeekableAnimatedImageResourceByResId} */
+        public static final class Builder {
+            private final ResourceProto.AndroidSeekableAnimatedImageResourceByResId.Builder mImpl =
+                    ResourceProto.AndroidSeekableAnimatedImageResourceByResId.newBuilder();
+
+            public Builder() {}
+
+            /**
+             * Sets the format for the animated image.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimatedImageFormat(@AnimatedImageFormat int format) {
+                mImpl.setFormat(ResourceProto.AnimatedImageFormat.forNumber(format));
+                return this;
+            }
+
+            /**
+             * Sets the Android resource ID, e.g. R.drawable.foo.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setResourceId(@DrawableRes int resourceId) {
+                mImpl.setResourceId(resourceId);
+                return this;
+            }
+
+            /**
+             * Sets a {@link DynamicFloat}, normally transformed from certain states with the data
+             * binding pipeline to control the progress of the animation. Its value is required to
+             * fall in the range of [0.0, 1.0]. Any values outside this range would be clamped. When
+             * the first value of the {@link DynamicFloat} arrives, the animation starts from
+             * progress 0 to that value. After that it plays from current progress to the new value
+             * on subsequent updates.
+             * If not set, the animation will play on load (similar to a non-seekable animated).
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setProgress(@NonNull DynamicFloat progress) {
+                mImpl.setProgress(progress.toDynamicFloatProto());
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @NonNull
+            public AndroidSeekableAnimatedImageResourceByResId build() {
+                return AndroidSeekableAnimatedImageResourceByResId.fromProto(mImpl.build());
+            }
+        }
+    }
+
+    /**
+     * An image resource, which can be used by layouts. This holds multiple underlying resource
+     * types, which the underlying runtime will pick according to what it thinks is appropriate.
+     *
+     * @since 1.0
+     */
+    public static final class ImageResource {
+        private final ResourceProto.ImageResource mImpl;
+
+        ImageResource(ResourceProto.ImageResource impl) {
+            this.mImpl = impl;
+        }
+
+        /**
+         * Gets an image resource that maps to an Android drawable by resource ID.
+         *
+         * @since 1.0
+         */
+        @Nullable
+        public AndroidImageResourceByResId getAndroidResourceByResId() {
+            if (mImpl.hasAndroidResourceByResId()) {
+                return AndroidImageResourceByResId.fromProto(mImpl.getAndroidResourceByResId());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets an image resource that contains the image data inline.
+         *
+         * @since 1.0
+         */
+        @Nullable
+        public InlineImageResource getInlineResource() {
+            if (mImpl.hasInlineResource()) {
+                return InlineImageResource.fromProto(mImpl.getInlineResource());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets a non-seekable animated image resource that maps to an Android drawable by resource
+         * ID. The animation is started with given trigger, fire and forget.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AndroidAnimatedImageResourceByResId getAndroidAnimatedResourceByResId() {
+            if (mImpl.hasAndroidAnimatedResourceByResId()) {
+                return AndroidAnimatedImageResourceByResId.fromProto(
+                        mImpl.getAndroidAnimatedResourceByResId());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets a seekable animated image resource that maps to an Android drawable by resource ID.
+         * The animation progress is bound to the provided dynamic float.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AndroidSeekableAnimatedImageResourceByResId
+                getAndroidSeekableAnimatedResourceByResId() {
+            if (mImpl.hasAndroidSeekableAnimatedResourceByResId()) {
+                return AndroidSeekableAnimatedImageResourceByResId.fromProto(
+                        mImpl.getAndroidSeekableAnimatedResourceByResId());
+            } else {
+                return null;
+            }
+        }
+
+        @NonNull
+        static ImageResource fromProto(@NonNull ResourceProto.ImageResource proto) {
+            return new ImageResource(proto);
+        }
+
+        @NonNull
+        ResourceProto.ImageResource toProto() {
+            return mImpl;
+        }
+
+        /** Builder for {@link ImageResource} */
+        public static final class Builder {
+            private final ResourceProto.ImageResource.Builder mImpl =
+                    ResourceProto.ImageResource.newBuilder();
+
+            public Builder() {}
+
+            /**
+             * Sets an image resource that maps to an Android drawable by resource ID.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setAndroidResourceByResId(
+                    @NonNull AndroidImageResourceByResId androidResourceByResId) {
+                mImpl.setAndroidResourceByResId(androidResourceByResId.toProto());
+                return this;
+            }
+
+            /**
+             * Sets an image resource that contains the image data inline.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setInlineResource(@NonNull InlineImageResource inlineResource) {
+                mImpl.setInlineResource(inlineResource.toProto());
+                return this;
+            }
+
+            /**
+             * Sets a non-seekable animated image resource that maps to an Android drawable by
+             * resource ID. The animation is started with given trigger, fire and forget.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAndroidAnimatedResourceByResId(
+                    @NonNull AndroidAnimatedImageResourceByResId androidAnimatedResourceByResId) {
+                mImpl.setAndroidAnimatedResourceByResId(androidAnimatedResourceByResId.toProto());
+                return this;
+            }
+
+            /**
+             * Sets a seekable animated image resource that maps to an Android drawable by resource
+             * ID. The animation progress is bound to the provided dynamic float.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAndroidSeekableAnimatedResourceByResId(
+                    @NonNull
+                            AndroidSeekableAnimatedImageResourceByResId
+                                    androidSeekableAnimatedResourceByResId) {
+                mImpl.setAndroidSeekableAnimatedResourceByResId(
+                        androidSeekableAnimatedResourceByResId.toProto());
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @NonNull
+            public ImageResource build() {
+                return ImageResource.fromProto(mImpl.build());
+            }
+        }
+    }
+
+    /**
+     * The resources for a layout.
+     *
+     * @since 1.0
+     */
+    public static final class Resources {
+        private final ResourceProto.Resources mImpl;
+
+        Resources(ResourceProto.Resources impl) {
+            this.mImpl = impl;
+        }
+
+        /**
+         * Gets the version of this {@link Resources} instance.
+         *
+         * <p>Each layout specifies the version of resources it requires. After fetching a layout,
+         * the renderer will use the resources version specified by the layout to separately fetch
+         * the resources.
+         *
+         * <p>This value must match the version of the resources required by the layout for the
+         * layout to render successfully, and must match the resource version specified in
+         * ResourcesRequest which triggered this request.
+         *
+         * @since 1.0
+         */
+        @NonNull
+        public String getVersion() {
+            return mImpl.getVersion();
+        }
+
+        /**
+         * Gets a map of resource_ids to images, which can be used by layouts.
+         *
+         * @since 1.0
+         */
+        @NonNull
+        public Map<String, ImageResource> getIdToImageMapping() {
+            Map<String, ImageResource> map = new HashMap<>();
+            for (Entry<String, ResourceProto.ImageResource> entry :
+                    mImpl.getIdToImageMap().entrySet()) {
+                map.put(entry.getKey(), ImageResource.fromProto(entry.getValue()));
+            }
+            return Collections.unmodifiableMap(map);
+        }
+
+        @NonNull
+        static Resources fromProto(@NonNull ResourceProto.Resources proto) {
+            return new Resources(proto);
+        }
+
+        /**
+         * Returns the internal proto instance.
+         *
+         * @hide
+         */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public ResourceProto.Resources toProto() {
+            return mImpl;
+        }
+
+        /** Builder for {@link Resources} */
+        public static final class Builder {
+            private final ResourceProto.Resources.Builder mImpl =
+                    ResourceProto.Resources.newBuilder();
+
+            public Builder() {}
+
+            /**
+             * Sets the version of this {@link Resources} instance.
+             *
+             * <p>Each layout specifies the version of resources it requires. After fetching a
+             * layout, the renderer will use the resources version specified by the layout to
+             * separately fetch the resources.
+             *
+             * <p>This value must match the version of the resources required by the layout for the
+             * layout to render successfully, and must match the resource version specified in
+             * ResourcesRequest which triggered this request.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setVersion(@NonNull String version) {
+                mImpl.setVersion(version);
+                return this;
+            }
+
+            /**
+             * Adds an entry into a map of resource_ids to images, which can be used by layouts.
+             *
+             * @since 1.0
+             */
+            @SuppressLint("MissingGetterMatchingBuilder")
+            @NonNull
+            public Builder addIdToImageMapping(@NonNull String id, @NonNull ImageResource image) {
+                mImpl.putIdToImage(id, image.toProto());
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @NonNull
+            public Resources build() {
+                return Resources.fromProto(mImpl.build());
+            }
+        }
+    }
 }
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TriggerBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TriggerBuilders.java
new file mode 100644
index 0000000..675364c
--- /dev/null
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TriggerBuilders.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2022 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 androidx.wear.protolayout;
+
+import static androidx.wear.protolayout.expression.Preconditions.checkNotNull;
+
+import android.annotation.SuppressLint;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.RestrictTo.Scope;
+import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
+import androidx.wear.protolayout.expression.Fingerprint;
+import androidx.wear.protolayout.proto.TriggerProto;
+
+/** Builders for triggers that can be used to start an animation. */
+public final class TriggerBuilders {
+  private TriggerBuilders() {}
+
+  /** Shortcut for building an {@link OnLoadTrigger}. */
+  @NonNull
+  public static OnLoadTrigger createOnLoadTrigger() {
+    return new OnLoadTrigger.Builder().build();
+  }
+
+  /** Shortcut for building an {@link OnConditionMetTrigger}. */
+  @NonNull
+  public static OnConditionMetTrigger createOnConditionMetTrigger(
+          @NonNull DynamicBool dynamicBool) {
+    return new OnConditionMetTrigger.Builder().setTrigger(dynamicBool).build();
+  }
+
+  /**
+   * Triggers immediately when the layout is loaded / reloaded.
+   *
+   * @since 1.2
+   */
+  public static final class OnLoadTrigger implements Trigger {
+    private final TriggerProto.OnLoadTrigger mImpl;
+    @Nullable private final Fingerprint mFingerprint;
+
+    OnLoadTrigger(TriggerProto.OnLoadTrigger impl, @Nullable Fingerprint fingerprint) {
+      this.mImpl = impl;
+      this.mFingerprint = fingerprint;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    public Fingerprint getFingerprint() {
+      return mFingerprint;
+    }
+
+    @NonNull
+    static OnLoadTrigger fromProto(@NonNull TriggerProto.OnLoadTrigger proto) {
+      return new OnLoadTrigger(proto, null);
+    }
+
+    @NonNull
+    TriggerProto.OnLoadTrigger toProto() {
+      return mImpl;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+      public TriggerProto.Trigger toTriggerProto() {
+      return TriggerProto.Trigger.newBuilder().setOnLoadTrigger(mImpl).build();
+    }
+
+    /** Builder for {@link OnLoadTrigger}. */
+    public static final class Builder implements Trigger.Builder {
+      private final TriggerProto.OnLoadTrigger.Builder mImpl =
+          TriggerProto.OnLoadTrigger.newBuilder();
+      private final Fingerprint mFingerprint = new Fingerprint(-1262805599);
+
+      public Builder() {}
+
+      @Override
+      @NonNull
+      public OnLoadTrigger build() {
+        return new OnLoadTrigger(mImpl.build(), mFingerprint);
+      }
+    }
+  }
+
+  /**
+   * Triggers *every time* the condition switches from false to true. If the condition is true
+   * initially, that will fire the trigger on load.
+   *
+   * @since 1.2
+   */
+  public static final class OnConditionMetTrigger implements Trigger {
+    private final TriggerProto.OnConditionTrigger mImpl;
+    @Nullable private final Fingerprint mFingerprint;
+
+    OnConditionMetTrigger(TriggerProto.OnConditionTrigger impl, @Nullable Fingerprint fingerprint) {
+      this.mImpl = impl;
+      this.mFingerprint = fingerprint;
+    }
+
+    /**
+     * Gets dynamic boolean used as trigger. Intended for testing purposes only.
+     *
+     * @since 1.2
+     */
+    @Nullable
+    public DynamicBool getTrigger() {
+      if (mImpl.hasDynamicBool()) {
+        return DynamicBuilders.dynamicBoolFromProto(mImpl.getDynamicBool());
+      } else {
+        return null;
+      }
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    public Fingerprint getFingerprint() {
+      return mFingerprint;
+    }
+
+    @NonNull
+    static OnConditionMetTrigger fromProto(@NonNull TriggerProto.OnConditionTrigger proto) {
+      return new OnConditionMetTrigger(proto, null);
+    }
+
+    @NonNull
+    TriggerProto.OnConditionTrigger toProto() {
+      return mImpl;
+    }
+
+    /** @hide */
+    @Override
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+      public TriggerProto.Trigger toTriggerProto() {
+      return TriggerProto.Trigger.newBuilder().setOnConditionTrigger(mImpl).build();
+    }
+
+    /** Builder for {@link OnConditionMetTrigger}. */
+    public static final class Builder implements Trigger.Builder {
+      private final TriggerProto.OnConditionTrigger.Builder mImpl =
+          TriggerProto.OnConditionTrigger.newBuilder();
+      private final Fingerprint mFingerprint = new Fingerprint(1952746052);
+
+      public Builder() {}
+
+      /**
+       * Sets dynamic boolean used as trigger.
+       *
+       * @since 1.2
+       */
+      @NonNull
+      public Builder setTrigger(@NonNull DynamicBool dynamicBool) {
+        mImpl.setDynamicBool(dynamicBool.toDynamicBoolProto());
+        mFingerprint.recordPropertyUpdate(
+            1, checkNotNull(dynamicBool.getFingerprint()).aggregateValueAsInt());
+        return this;
+      }
+
+      @Override
+      @NonNull
+      public OnConditionMetTrigger build() {
+        return new OnConditionMetTrigger(mImpl.build(), mFingerprint);
+      }
+    }
+  }
+
+  /**
+   * Interface defining the triggers that can be fired. These triggers can be used to allow
+   * acting on events. For example some animations can be set to start based on a trigger.
+   *
+   * @since 1.2
+   */
+  public interface Trigger {
+    /**
+     * Get the protocol buffer representation of this object.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    TriggerProto.Trigger toTriggerProto();
+
+    /**
+     * Get the fingerprint for this object or null if unknown.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    Fingerprint getFingerprint();
+
+    /** Builder to create {@link Trigger} objects.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    interface Builder {
+
+      /** Builds an instance with values accumulated in this Builder. */
+      @NonNull
+      Trigger build();
+    }
+  }
+
+  @NonNull
+  static Trigger triggerFromProto(@NonNull TriggerProto.Trigger proto) {
+    if (proto.hasOnLoadTrigger()) {
+      return OnLoadTrigger.fromProto(proto.getOnLoadTrigger());
+    }
+    if (proto.hasOnConditionTrigger()) {
+      return OnConditionMetTrigger.fromProto(proto.getOnConditionTrigger());
+    }
+    throw new IllegalStateException("Proto was not a recognised instance of Trigger");
+  }
+}
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
new file mode 100644
index 0000000..2f54d7b
--- /dev/null
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2023 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 androidx.wear.protolayout;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.wear.protolayout.proto.DimensionProto;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class DimensionBuildersTest {
+
+    @Test
+    public void expandedLayoutWeight() {
+        float layoutWeight = 3.14f;
+        DimensionBuilders.ContainerDimension dimensionProp =
+                new DimensionBuilders.ExpandedDimensionProp.Builder().setLayoutWeight(layoutWeight)
+                        .build();
+
+        DimensionProto.ContainerDimension dimensionProto =
+                dimensionProp.toContainerDimensionProto();
+        assertThat(dimensionProto.getExpandedDimension().getLayoutWeight().getValue())
+                .isWithin(.001f).of(layoutWeight);
+    }
+
+
+    @Test
+    public void wrappedMinSize() {
+        int minSizeDp = 42;
+        DimensionBuilders.ContainerDimension dimensionProp =
+                new DimensionBuilders.WrappedDimensionProp.Builder().setMinimumSizeDp(minSizeDp)
+                        .build();
+
+        DimensionProto.ContainerDimension dimensionProto =
+                dimensionProp.toContainerDimensionProto();
+        assertThat(dimensionProto.getWrappedDimension().getMinimumSize().getValue())
+                .isEqualTo(minSizeDp);
+    }
+}
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
new file mode 100644
index 0000000..59f2df8
--- /dev/null
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2023 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 androidx.wear.protolayout;
+
+import static androidx.wear.protolayout.ResourceBuilders.ANIMATED_IMAGE_FORMAT_AVD;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.proto.ResourceProto;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class ResourceBuildersTest {
+    private static final int RESOURCE_ID = 10;
+    private static final int FORMAT = ANIMATED_IMAGE_FORMAT_AVD;
+
+    @Test
+    public void avd() {
+        ResourceBuilders.AndroidAnimatedImageResourceByResId avd =
+                new ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder()
+                        .setResourceId(RESOURCE_ID)
+                        .setAnimatedImageFormat(FORMAT)
+                        .setStartTrigger(TriggerBuilders.createOnLoadTrigger())
+                        .build();
+
+        ResourceProto.AndroidAnimatedImageResourceByResId avdProto = avd.toProto();
+
+        assertThat(avdProto.getResourceId()).isEqualTo(RESOURCE_ID);
+        assertThat(avdProto.getFormat().getNumber()).isEqualTo(FORMAT);
+        assertThat(avdProto.getTrigger().hasOnLoadTrigger()).isTrue();
+    }
+
+    @Test
+    public void seekableAvd() {
+        String stateKey = "state-key";
+        ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId avd =
+                new ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder()
+                        .setResourceId(RESOURCE_ID)
+                        .setAnimatedImageFormat(FORMAT)
+                        .setProgress(DynamicBuilders.DynamicFloat.fromState(stateKey))
+                        .build();
+
+        ResourceProto.AndroidSeekableAnimatedImageResourceByResId avdProto = avd.toProto();
+
+        assertThat(avdProto.getResourceId()).isEqualTo(RESOURCE_ID);
+        assertThat(avdProto.getFormat().getNumber()).isEqualTo(FORMAT);
+        assertThat(avdProto.getProgress().getStateSource().getSourceKey()).isEqualTo(stateKey);
+    }
+}
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
new file mode 100644
index 0000000..5b3260e
--- /dev/null
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 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 androidx.wear.protolayout;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.wear.protolayout.expression.DynamicBuilders;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class TriggerBuildersTest {
+
+    @Test
+    public void onLoadTrigger() {
+        TriggerBuilders.OnLoadTrigger onLoadTrigger = TriggerBuilders.createOnLoadTrigger();
+
+        assertThat(onLoadTrigger.toTriggerProto().hasOnLoadTrigger()).isTrue();
+    }
+
+
+    @Test
+    public void onConditionTrigger() {
+        DynamicBuilders.DynamicBool condition = DynamicBuilders.DynamicBool.fromState("state");
+
+        TriggerBuilders.OnConditionMetTrigger onConditionMetTrigger =
+                TriggerBuilders.createOnConditionMetTrigger(
+                condition);
+
+        assertThat(
+                onConditionMetTrigger.toTriggerProto().getOnConditionTrigger().getDynamicBool())
+                .isEqualTo(condition.toDynamicBoolProto());
+    }
+}
diff --git a/wear/watchface/watchface-client-guava/api/current.txt b/wear/watchface/watchface-client-guava/api/current.txt
index 4c88746..1b8efee 100644
--- a/wear/watchface/watchface-client-guava/api/current.txt
+++ b/wear/watchface/watchface-client-guava/api/current.txt
@@ -11,9 +11,9 @@
     method public androidx.wear.watchface.client.EditorServiceClient getEditorServiceClient();
     method public androidx.wear.watchface.client.InteractiveWatchFaceClient? getInteractiveWatchFaceClientInstance(String instanceId);
     method @Deprecated public suspend Object? getOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
-    method public suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
+    method public suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
     method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener);
     field public static final androidx.wear.watchface.client.ListenableWatchFaceControlClient.Companion Companion;
   }
 
diff --git a/wear/watchface/watchface-client-guava/api/public_plus_experimental_current.txt b/wear/watchface/watchface-client-guava/api/public_plus_experimental_current.txt
index 4c88746..1b8efee 100644
--- a/wear/watchface/watchface-client-guava/api/public_plus_experimental_current.txt
+++ b/wear/watchface/watchface-client-guava/api/public_plus_experimental_current.txt
@@ -11,9 +11,9 @@
     method public androidx.wear.watchface.client.EditorServiceClient getEditorServiceClient();
     method public androidx.wear.watchface.client.InteractiveWatchFaceClient? getInteractiveWatchFaceClientInstance(String instanceId);
     method @Deprecated public suspend Object? getOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
-    method public suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
+    method public suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
     method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener);
     field public static final androidx.wear.watchface.client.ListenableWatchFaceControlClient.Companion Companion;
   }
 
diff --git a/wear/watchface/watchface-client-guava/api/restricted_current.txt b/wear/watchface/watchface-client-guava/api/restricted_current.txt
index 4c88746..1b8efee 100644
--- a/wear/watchface/watchface-client-guava/api/restricted_current.txt
+++ b/wear/watchface/watchface-client-guava/api/restricted_current.txt
@@ -11,9 +11,9 @@
     method public androidx.wear.watchface.client.EditorServiceClient getEditorServiceClient();
     method public androidx.wear.watchface.client.InteractiveWatchFaceClient? getInteractiveWatchFaceClientInstance(String instanceId);
     method @Deprecated public suspend Object? getOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
-    method public suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
+    method public suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>);
     method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.watchface.client.InteractiveWatchFaceClient> listenableGetOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener);
     field public static final androidx.wear.watchface.client.ListenableWatchFaceControlClient.Companion Companion;
   }
 
diff --git a/wear/watchface/watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt b/wear/watchface/watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt
index 338f592..e3de152 100644
--- a/wear/watchface/watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt
+++ b/wear/watchface/watchface-client-guava/src/main/java/androidx/wear/watchface/client/ListenableWatchFaceControlClient.kt
@@ -19,6 +19,7 @@
 import android.content.ComponentName
 import android.content.Context
 import androidx.concurrent.futures.ResolvableFuture
+import androidx.core.util.Consumer
 import androidx.wear.watchface.Renderer
 import androidx.wear.watchface.client.WatchFaceControlClient.ServiceNotBoundException
 import androidx.wear.watchface.complications.data.ComplicationData
@@ -26,7 +27,6 @@
 import androidx.wear.watchface.utility.AsyncTraceEvent
 import com.google.common.util.concurrent.ListenableFuture
 import java.util.concurrent.Executor
-import java.util.function.Consumer
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
diff --git a/wear/watchface/watchface-client/api/current.txt b/wear/watchface/watchface-client/api/current.txt
index b7a6bc0..04a3c4c 100644
--- a/wear/watchface/watchface-client/api/current.txt
+++ b/wear/watchface/watchface-client/api/current.txt
@@ -190,7 +190,7 @@
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public androidx.wear.watchface.client.EditorServiceClient getEditorServiceClient() throws android.os.RemoteException;
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public androidx.wear.watchface.client.InteractiveWatchFaceClient? getInteractiveWatchFaceClientInstance(String instanceId) throws android.os.RemoteException;
     method @Deprecated @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public suspend Object? getOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
-    method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public default suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
+    method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public default suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
     method public default boolean hasComplicationDataCache();
     field public static final androidx.wear.watchface.client.WatchFaceControlClient.Companion Companion;
   }
diff --git a/wear/watchface/watchface-client/api/public_plus_experimental_current.txt b/wear/watchface/watchface-client/api/public_plus_experimental_current.txt
index ff5390c..16c73b9 100644
--- a/wear/watchface/watchface-client/api/public_plus_experimental_current.txt
+++ b/wear/watchface/watchface-client/api/public_plus_experimental_current.txt
@@ -131,7 +131,7 @@
 
   public interface InteractiveWatchFaceClient extends java.lang.AutoCloseable {
     method @AnyThread public void addClientDisconnectListener(androidx.wear.watchface.client.InteractiveWatchFaceClient.ClientDisconnectListener listener, java.util.concurrent.Executor executor);
-    method @androidx.wear.watchface.client.WatchFaceClientExperimental public default void addOnWatchFaceColorsListener(java.util.concurrent.Executor executor, java.util.function.Consumer<androidx.wear.watchface.WatchFaceColors> listener);
+    method @androidx.wear.watchface.client.WatchFaceClientExperimental public default void addOnWatchFaceColorsListener(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.wear.watchface.WatchFaceColors> listener);
     method public void addOnWatchFaceReadyListener(java.util.concurrent.Executor executor, androidx.wear.watchface.client.InteractiveWatchFaceClient.OnWatchFaceReadyListener listener);
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public default Integer? getComplicationIdAt(@Px int x, @Px int y) throws android.os.RemoteException;
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationSlotsState() throws android.os.RemoteException;
@@ -144,7 +144,7 @@
     method @AnyThread public boolean isConnectionAlive();
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public void performAmbientTick() throws android.os.RemoteException;
     method @AnyThread public void removeClientDisconnectListener(androidx.wear.watchface.client.InteractiveWatchFaceClient.ClientDisconnectListener listener);
-    method @androidx.wear.watchface.client.WatchFaceClientExperimental public default void removeOnWatchFaceColorsListener(java.util.function.Consumer<androidx.wear.watchface.WatchFaceColors> listener);
+    method @androidx.wear.watchface.client.WatchFaceClientExperimental public default void removeOnWatchFaceColorsListener(androidx.core.util.Consumer<androidx.wear.watchface.WatchFaceColors> listener);
     method public void removeOnWatchFaceReadyListener(androidx.wear.watchface.client.InteractiveWatchFaceClient.OnWatchFaceReadyListener listener);
     method @RequiresApi(27) @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public android.graphics.Bitmap renderWatchFaceToBitmap(androidx.wear.watchface.RenderParameters renderParameters, java.time.Instant instant, androidx.wear.watchface.style.UserStyle? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? idAndComplicationData) throws android.os.RemoteException;
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public void sendTouchEvent(@Px int xPosition, @Px int yPosition, @androidx.wear.watchface.TapType int tapType) throws android.os.RemoteException;
@@ -199,7 +199,7 @@
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public androidx.wear.watchface.client.EditorServiceClient getEditorServiceClient() throws android.os.RemoteException;
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public androidx.wear.watchface.client.InteractiveWatchFaceClient? getInteractiveWatchFaceClientInstance(String instanceId) throws android.os.RemoteException;
     method @Deprecated @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public suspend Object? getOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
-    method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public default suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
+    method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public default suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
     method public default boolean hasComplicationDataCache();
     field public static final androidx.wear.watchface.client.WatchFaceControlClient.Companion Companion;
   }
diff --git a/wear/watchface/watchface-client/api/restricted_current.txt b/wear/watchface/watchface-client/api/restricted_current.txt
index b7a6bc0..04a3c4c 100644
--- a/wear/watchface/watchface-client/api/restricted_current.txt
+++ b/wear/watchface/watchface-client/api/restricted_current.txt
@@ -190,7 +190,7 @@
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public androidx.wear.watchface.client.EditorServiceClient getEditorServiceClient() throws android.os.RemoteException;
     method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public androidx.wear.watchface.client.InteractiveWatchFaceClient? getInteractiveWatchFaceClientInstance(String instanceId) throws android.os.RemoteException;
     method @Deprecated @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public suspend Object? getOrCreateInteractiveWatchFaceClient(String id, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
-    method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public default suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, java.util.function.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
+    method @kotlin.jvm.Throws(exceptionClasses=RemoteException::class) public default suspend Object? getOrCreateInteractiveWatchFaceClient(String instanceId, androidx.wear.watchface.client.DeviceConfig deviceConfig, androidx.wear.watchface.client.WatchUiState watchUiState, androidx.wear.watchface.style.UserStyleData? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>? slotIdToComplicationData, java.util.concurrent.Executor previewImageUpdateRequestedExecutor, androidx.core.util.Consumer<java.lang.String> previewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) throws android.os.RemoteException;
     method public default boolean hasComplicationDataCache();
     field public static final androidx.wear.watchface.client.WatchFaceControlClient.Companion Companion;
   }
diff --git a/wear/watchface/watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt b/wear/watchface/watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt
index 365da36..b723da6 100644
--- a/wear/watchface/watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt
+++ b/wear/watchface/watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt
@@ -34,6 +34,7 @@
 import android.view.SurfaceHolder
 import androidx.annotation.CallSuper
 import androidx.annotation.RequiresApi
+import androidx.core.util.Consumer
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -98,7 +99,6 @@
 import java.util.concurrent.Executor
 import java.util.concurrent.TimeUnit
 import java.util.concurrent.TimeoutException
-import java.util.function.Consumer
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Deferred
diff --git a/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt b/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
index 566abd4..394bcfa 100644
--- a/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
+++ b/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
@@ -25,6 +25,7 @@
 import androidx.annotation.IntDef
 import androidx.annotation.Px
 import androidx.annotation.RequiresApi
+import androidx.core.util.Consumer
 import androidx.wear.watchface.ComplicationSlot
 import androidx.wear.watchface.ComplicationSlotBoundsType
 import androidx.wear.watchface.ComplicationSlotsManager
@@ -52,7 +53,6 @@
 import androidx.wear.watchface.utility.TraceEvent
 import java.time.Instant
 import java.util.concurrent.Executor
-import java.util.function.Consumer
 
 /** @hide */
 @IntDef(value = [DisconnectReasons.ENGINE_DIED, DisconnectReasons.ENGINE_DETACHED])
diff --git a/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt b/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
index fad38e4..e9177de 100644
--- a/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
+++ b/wear/watchface/watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
@@ -23,6 +23,7 @@
 import android.os.IBinder
 import android.os.RemoteException
 import android.util.Log
+import androidx.core.util.Consumer
 import androidx.annotation.Px
 import androidx.annotation.RestrictTo
 import androidx.wear.watchface.Renderer
@@ -44,7 +45,6 @@
 import androidx.wear.watchface.utility.AsyncTraceEvent
 import androidx.wear.watchface.utility.TraceEvent
 import java.util.concurrent.Executor
-import java.util.function.Consumer
 import kotlin.coroutines.resume
 import kotlin.coroutines.resumeWithException
 import kotlinx.coroutines.CompletableDeferred
diff --git a/wear/watchface/watchface-complications-data-source/api/current.txt b/wear/watchface/watchface-complications-data-source/api/current.txt
index 73e5e61..d348447 100644
--- a/wear/watchface/watchface-complications-data-source/api/current.txt
+++ b/wear/watchface/watchface-complications-data-source/api/current.txt
@@ -52,14 +52,17 @@
   }
 
   public final class ComplicationRequest {
+    ctor @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType, boolean immediateResponseRequired, Boolean? isForSafeWatchFace);
     ctor public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType, boolean immediateResponseRequired);
     ctor @Deprecated public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType);
     method public int getComplicationInstanceId();
     method public androidx.wear.watchface.complications.data.ComplicationType getComplicationType();
+    method public Boolean? isForSafeWatchFace();
     method public boolean isImmediateResponseRequired();
     property public final int complicationInstanceId;
     property public final androidx.wear.watchface.complications.data.ComplicationType complicationType;
     property public final boolean immediateResponseRequired;
+    property public final Boolean? isForSafeWatchFace;
   }
 
   public final class TimeInterval {
diff --git a/wear/watchface/watchface-complications-data-source/api/public_plus_experimental_current.txt b/wear/watchface/watchface-complications-data-source/api/public_plus_experimental_current.txt
index 73e5e61..d348447 100644
--- a/wear/watchface/watchface-complications-data-source/api/public_plus_experimental_current.txt
+++ b/wear/watchface/watchface-complications-data-source/api/public_plus_experimental_current.txt
@@ -52,14 +52,17 @@
   }
 
   public final class ComplicationRequest {
+    ctor @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType, boolean immediateResponseRequired, Boolean? isForSafeWatchFace);
     ctor public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType, boolean immediateResponseRequired);
     ctor @Deprecated public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType);
     method public int getComplicationInstanceId();
     method public androidx.wear.watchface.complications.data.ComplicationType getComplicationType();
+    method public Boolean? isForSafeWatchFace();
     method public boolean isImmediateResponseRequired();
     property public final int complicationInstanceId;
     property public final androidx.wear.watchface.complications.data.ComplicationType complicationType;
     property public final boolean immediateResponseRequired;
+    property public final Boolean? isForSafeWatchFace;
   }
 
   public final class TimeInterval {
diff --git a/wear/watchface/watchface-complications-data-source/api/restricted_current.txt b/wear/watchface/watchface-complications-data-source/api/restricted_current.txt
index 73e5e61..d348447 100644
--- a/wear/watchface/watchface-complications-data-source/api/restricted_current.txt
+++ b/wear/watchface/watchface-complications-data-source/api/restricted_current.txt
@@ -52,14 +52,17 @@
   }
 
   public final class ComplicationRequest {
+    ctor @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType, boolean immediateResponseRequired, Boolean? isForSafeWatchFace);
     ctor public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType, boolean immediateResponseRequired);
     ctor @Deprecated public ComplicationRequest(int complicationInstanceId, androidx.wear.watchface.complications.data.ComplicationType complicationType);
     method public int getComplicationInstanceId();
     method public androidx.wear.watchface.complications.data.ComplicationType getComplicationType();
+    method public Boolean? isForSafeWatchFace();
     method public boolean isImmediateResponseRequired();
     property public final int complicationInstanceId;
     property public final androidx.wear.watchface.complications.data.ComplicationType complicationType;
     property public final boolean immediateResponseRequired;
+    property public final Boolean? isForSafeWatchFace;
   }
 
   public final class TimeInterval {
diff --git a/wear/watchface/watchface-complications-data-source/src/main/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceService.kt b/wear/watchface/watchface-complications-data-source/src/main/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceService.kt
index 2450fd86..6197888 100644
--- a/wear/watchface/watchface-complications-data-source/src/main/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceService.kt
+++ b/wear/watchface/watchface-complications-data-source/src/main/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceService.kt
@@ -31,6 +31,7 @@
 import android.support.wearable.complications.IComplicationManager
 import android.support.wearable.complications.IComplicationProvider
 import androidx.annotation.MainThread
+import androidx.annotation.RequiresApi
 import androidx.annotation.RestrictTo
 import androidx.wear.watchface.complications.data.ComplicationData
 import androidx.wear.watchface.complications.data.ComplicationDataExpressionEvaluator
@@ -60,12 +61,34 @@
  *   deadline). This will only be `true` within a
  *   [ComplicationDataSourceService.onStartImmediateComplicationRequests]
  *   [ComplicationDataSourceService.onStopImmediateComplicationRequests] pair.
+ * @param isForSafeWatchFace Whether this request is on behalf of a 'safe' watch face as defined by
+ *   the [ComplicationDataSourceService.METADATA_KEY_SAFE_WATCH_FACES] meta data in the data
+ *   source's manifest. The data source may choose to serve different results for a 'safe' watch
+ *   face. If the data source does not have the privileged permission
+ *   `com.google.wear.permission.GET_IS_FOR_SAFE_WATCH_FACE`, then this must be null.
  */
-public class ComplicationRequest(
+public class ComplicationRequest
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+constructor(
     complicationInstanceId: Int,
     complicationType: ComplicationType,
-    immediateResponseRequired: Boolean
+    immediateResponseRequired: Boolean,
+    @Suppress("AutoBoxing")
+    isForSafeWatchFace: Boolean?
 ) {
+    /** Constructs a [ComplicationRequest] without setting [isForSafeWatchFace]. */
+    @Suppress("NewApi")
+    constructor(
+        complicationInstanceId: Int,
+        complicationType: ComplicationType,
+        immediateResponseRequired: Boolean,
+    ) : this(
+        complicationInstanceId,
+        complicationType,
+        immediateResponseRequired,
+        isForSafeWatchFace = false
+    )
+
     /**
      * The system's id for the requested complication which is a unique value for the tuple
      * [Watch face ComponentName, complication slot ID].
@@ -86,6 +109,23 @@
     @get:JvmName("isImmediateResponseRequired")
     public val immediateResponseRequired = immediateResponseRequired
 
+    /**
+     * Intended for OEM use, returns whether this request is on behalf of a 'safe' watch face as
+     * defined by the [ComplicationDataSourceService.METADATA_KEY_SAFE_WATCH_FACES] meta data in the
+     * data source's manifest. The data source may choose to serve different results for a 'safe'
+     * watch face.
+     *
+     * If the [ComplicationDataSourceService.METADATA_KEY_SAFE_WATCH_FACES] meta data is not defined
+     * then this will be false.
+     *
+     * If the DataSourceService does not have the privileged permission
+     * `com.google.wear.permission.GET_IS_FOR_SAFE_WATCH_FACE`, then this will be null.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    @get:JvmName("isForSafeWatchFace")
+    @get:Suppress("AutoBoxing")
+    public val isForSafeWatchFace: Boolean? = isForSafeWatchFace
+
     @Deprecated("Use a constructor that specifies responseNeededSoon.")
     constructor(
         complicationInstanceId: Int,
@@ -140,7 +180,7 @@
  * also register a separate [METADATA_KEY_IMMEDIATE_UPDATE_PERIOD_MILLISECONDS] meta data tag which
  * supports sampling at up to 1Hz when the watch face is visible and non-ambient, however this also
  * requires the DataSourceService to have the privileged permission
- * com.google.android.wearable.permission.USE_IMMEDIATE_COMPLICATION_UPDATE.
+ * `com.google.android.wearable.permission.USE_IMMEDIATE_COMPLICATION_UPDATE`.
  *
  * ```
  *   <meta-data android:name=
@@ -251,7 +291,7 @@
      * deadline is 20 seconds. [ComplicationRequest.immediateResponseRequired] will only ever be
      * `true` if [METADATA_KEY_IMMEDIATE_UPDATE_PERIOD_MILLISECONDS] is present in the manifest, and
      * the provider has the privileged permission
-     * com.google.android.wearable.permission.USE_IMMEDIATE_COMPLICATION_UPDATE, and the
+     * `com.google.android.wearable.permission.USE_IMMEDIATE_COMPLICATION_UPDATE`, and the
      * complication is visible and non-ambient.
      *
      * @param request The details about the complication that has been requested.
@@ -350,14 +390,26 @@
     private inner class IComplicationProviderWrapper : IComplicationProvider.Stub() {
         @SuppressLint("SyntheticAccessor")
         override fun onUpdate(complicationInstanceId: Int, type: Int, manager: IBinder) {
+            onUpdate2(complicationInstanceId, type, isForSafeWatchFace = false, manager)
+        }
+
+        @SuppressLint("SyntheticAccessor")
+        override fun onUpdate2(
+            complicationInstanceId: Int,
+            type: Int,
+            isForSafeWatchFace: Boolean,
+            manager: IBinder
+        ) {
             val expectedDataType = fromWireType(type)
             val iComplicationManager = IComplicationManager.Stub.asInterface(manager)
             mainThreadHandler.post {
                 onComplicationRequest(
+                    @Suppress("NewApi")
                     ComplicationRequest(
                         complicationInstanceId,
                         expectedDataType,
-                        immediateResponseRequired = false
+                        immediateResponseRequired = false,
+                        isForSafeWatchFace = isForSafeWatchFace
                     ),
                     object : ComplicationRequestListener {
                         override fun onComplicationData(complicationData: ComplicationData?) {
@@ -553,6 +605,16 @@
         override fun onSynchronousComplicationRequest(
             complicationInstanceId: Int,
             type: Int
+        ) = onSynchronousComplicationRequest2(
+            complicationInstanceId,
+            isForSafeWatchFace = false,
+            type
+        )
+
+        override fun onSynchronousComplicationRequest2(
+            complicationInstanceId: Int,
+            isForSafeWatchFace: Boolean,
+            type: Int
         ): android.support.wearable.complications.ComplicationData? {
             val expectedDataType = fromWireType(type)
             val complicationType = fromWireType(type)
@@ -561,10 +623,12 @@
                 null
             mainThreadHandler.post {
                 [email protected](
+                    @Suppress("NewApi")
                     ComplicationRequest(
                         complicationInstanceId,
                         complicationType,
-                        immediateResponseRequired = true
+                        immediateResponseRequired = true,
+                        isForSafeWatchFace = isForSafeWatchFace
                     ),
                     object : ComplicationRequestListener {
                         override fun onComplicationData(complicationData: ComplicationData?) {
@@ -717,6 +781,11 @@
          * called, to declare a specific watch face as safe. An entry can also be a package name, as
          * if [ComponentName.getPackageName] had been called, in which case any watch face under the
          * app with that package name will be considered safe for this complication data source.
+         *
+         * From Android T, if this provider has the privileged permission
+         * com.google.wear.permission.GET_IS_FOR_SAFE_WATCH_FACEl, then
+         * [ComplicationRequest.isForSafeWatchFace] will be true if the request is on behalf of a
+         * watch face in this list.
          */
         // TODO(b/192233205): Migrate value to androidx.
         public const val METADATA_KEY_SAFE_WATCH_FACES: String =
diff --git a/wear/watchface/watchface-complications-data-source/src/test/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceServiceTest.kt b/wear/watchface/watchface-complications-data-source/src/test/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceServiceTest.kt
index a568b67..901fd9d 100644
--- a/wear/watchface/watchface-complications-data-source/src/test/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceServiceTest.kt
+++ b/wear/watchface/watchface-complications-data-source/src/test/java/androidx/wear/watchface/complications/datasource/ComplicationDataSourceServiceTest.kt
@@ -15,13 +15,13 @@
  */
 package androidx.wear.watchface.complications.datasource
 
+import android.support.wearable.complications.ComplicationData as WireComplicationData
 import android.content.Intent
 import android.content.res.Resources
 import android.os.Build
 import android.os.Handler
 import android.os.HandlerThread
 import android.os.RemoteException
-import android.support.wearable.complications.ComplicationData as WireComplicationData
 import android.support.wearable.complications.IComplicationManager
 import android.support.wearable.complications.IComplicationProvider
 import android.util.Log
@@ -172,6 +172,25 @@
     }
 
     @Test
+    fun testOnComplicationRequest_isForSafeWatchFace() {
+        mService.responseData = LongTextComplicationData.Builder(
+            PlainComplicationText.Builder("hello").build(),
+            ComplicationText.EMPTY
+        ).build()
+        val id = 123
+
+        @Suppress("NewApi") // onUpdate2
+        mProvider.onUpdate2(
+            id, ComplicationType.LONG_TEXT.toWireComplicationType(),
+            /* isForSafeWatchFace= */ true, mLocalManager
+        )
+
+        assertThat(mUpdateComplicationDataLatch.await(1000, TimeUnit.MILLISECONDS)).isTrue()
+        @Suppress("NewApi") // isForSafeWatchFace
+        assertThat(mService.lastRequest!!.isForSafeWatchFace).isTrue()
+    }
+
+    @Test
     @Config(sdk = [Build.VERSION_CODES.TIRAMISU])
     fun testOnComplicationRequestWithExpression_doesNotEvaluateExpression() {
         mService.responseData =
@@ -453,6 +472,45 @@
         }
     }
 
+    @Test
+    @Suppress("NewApi") // onSynchronousComplicationRequest2
+    fun testImmediateRequest_isForSafeWatchFace() {
+        val id = 123
+        mService.responseData = LongTextComplicationData.Builder(
+            PlainComplicationText.Builder("hello").build(),
+            ComplicationText.EMPTY
+        ).build()
+        val thread = HandlerThread("testThread")
+        try {
+            thread.start()
+            val threadHandler = Handler(thread.looper)
+            val response =
+                AtomicReference<android.support.wearable.complications.ComplicationData>()
+            val doneLatch = CountDownLatch(1)
+            threadHandler.post {
+                try {
+                    @Suppress("NewApi") // onSynchronousComplicationRequest2
+                    response.set(
+                        mProvider.onSynchronousComplicationRequest2(
+                            id,
+                            /* isForSafeWatchFace= */ true,
+                            ComplicationType.LONG_TEXT.toWireComplicationType()
+                        )
+                    )
+                    doneLatch.countDown()
+                } catch (e: RemoteException) {
+                    // Should not happen
+                }
+            }
+
+            assertThat(doneLatch.await(1000, TimeUnit.MILLISECONDS)).isTrue()
+            @Suppress("NewApi") // isForSafeWatchFace
+            assertThat(mService.lastRequest!!.isForSafeWatchFace).isTrue()
+        } finally {
+            thread.quitSafely()
+        }
+    }
+
     private fun runUiThreadTasksWhileAwaitingDataLatch(timeout: Long) {
         // Allowing UI thread to execute while we wait for the data latch.
         var attempts: Long = 0
diff --git a/wear/watchface/watchface-complications-data/src/main/aidl/android/support/wearable/complications/IComplicationProvider.aidl b/wear/watchface/watchface-complications-data/src/main/aidl/android/support/wearable/complications/IComplicationProvider.aidl
index e496132..d5e8eba 100644
--- a/wear/watchface/watchface-complications-data/src/main/aidl/android/support/wearable/complications/IComplicationProvider.aidl
+++ b/wear/watchface/watchface-complications-data/src/main/aidl/android/support/wearable/complications/IComplicationProvider.aidl
@@ -15,7 +15,7 @@
     /**
      * API version number. This should be incremented every time a new method is added.
      */
-    const int API_VERSION = 2;
+    const int API_VERSION = 3;
 
     /**
      * Called when a complication data update is requested for the given complication id.
@@ -132,4 +132,30 @@
      * @since API version 2.
      */
     ComplicationData onSynchronousComplicationRequest(int complicationInstanceId, int type) = 7;
+
+    /**
+     * Same as {@link #onUpdate}, but specifies isForSafeWatchFace.
+     *
+     * @param complicationInstanceId The system's id for the updated complication which is a unique
+     * value for the tuple [Watch face ComponentName, complication slot ID].
+     * @param type The type of complication requested
+     * @param manager The binder for IComplicationManager
+     * @param isForSafeWatchFace Whether this request is on behalf of a safe watchface as defined by
+     * the data source.
+     * @since API version 3.
+     */
+    void onUpdate2(int complicationInstanceId, int type, boolean isForSafeWatchFace,
+        IBinder manager) = 8;
+
+    /**
+     * Same as {@link #onSynchronousComplicationRequest2}, but specifies isForSafeWatchFace.
+     *
+     * @param complicationInstanceId The system's id for the requested complication which is a
+     * @param type The type of complication requested
+     * unique value for the tuple [Watch face ComponentName, complication slot ID].
+     * @return The updated ComplicationData or null if no update is necessary
+     * @since API version 3.
+     */
+    ComplicationData onSynchronousComplicationRequest2(int complicationInstanceId,
+        boolean isForSafeWatchFace, int type) = 9;
 }
diff --git a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
index ae7dd7e..b18b07e 100644
--- a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
+++ b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
@@ -20,6 +20,7 @@
 import android.support.wearable.complications.ComplicationData as WireComplicationData
 import android.support.wearable.complications.ComplicationText as WireComplicationText
 import androidx.annotation.RestrictTo
+import androidx.core.util.Consumer
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat
 import androidx.wear.protolayout.expression.pipeline.BoundDynamicType
 import androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator
@@ -27,7 +28,6 @@
 import androidx.wear.protolayout.expression.pipeline.ObservableStateStore
 import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway
 import java.util.concurrent.Executor
-import java.util.function.Consumer
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.asCoroutineDispatcher
@@ -62,7 +62,6 @@
     @JvmOverloads
     constructor(
         val unevaluatedData: WireComplicationData,
-        private val executor: Executor,
         private val listener: Consumer<WireComplicationData>,
         stateStore: ObservableStateStore = ObservableStateStore(emptyMap()),
         sensorGateway: SensorGateway? = null,
@@ -70,8 +69,11 @@
         private val evaluator =
             ComplicationDataExpressionEvaluator(unevaluatedData, stateStore, sensorGateway)
 
-        /** @see ComplicationDataExpressionEvaluator.init */
-        fun init() {
+        /**
+         * @see ComplicationDataExpressionEvaluator.init, [executor] is used in place of
+         *   `coroutineScope`.
+         */
+        fun init(executor: Executor) {
             evaluator.init()
             evaluator.data
                 .filterNotNull()
@@ -101,13 +103,15 @@
      * Parses the expression and starts blocking evaluation.
      *
      * This needs to be called exactly once.
+     *
+     * @param coroutineScope used for background evaluation
      */
-    fun init() {
+    fun init(coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)) {
         // Add all the receivers before we start binding them because binding can synchronously
         // trigger the receiver, which would update the data before all the fields are evaluated.
         initStateReceivers()
         initEvaluator()
-        monitorState()
+        monitorState(coroutineScope)
     }
 
     /**
@@ -184,13 +188,13 @@
     }
 
     /** Monitors [state] changes and updates [data]. */
-    private fun monitorState() {
+    private fun monitorState(coroutineScope: CoroutineScope) {
         state
             .onEach {
                 if (it.invalid.isNotEmpty()) _data.value = INVALID_DATA
                 else if (it.pending.isEmpty()) _data.value = it.data
             }
-            .launchIn(CoroutineScope(Dispatchers.Main))
+            .launchIn(coroutineScope)
     }
 
     /**
diff --git a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
index 47e9331..5834c42 100644
--- a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
+++ b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
@@ -20,6 +20,7 @@
 import android.support.wearable.complications.ComplicationText as WireComplicationText
 import android.util.Log
 import androidx.core.content.ContextCompat
+import androidx.core.util.Consumer
 import androidx.test.core.app.ApplicationProvider.getApplicationContext
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString
@@ -29,7 +30,6 @@
 import androidx.wear.watchface.complications.data.ComplicationDataExpressionEvaluator.Companion.hasExpression
 import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
-import java.util.function.Consumer
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.SharingStarted
@@ -334,31 +334,22 @@
 
     @Test
     fun compat_notInitialized_listenerNotInvoked() {
-        ComplicationDataExpressionEvaluator.Compat(
-                DATA_WITH_NO_EXPRESSION,
-                ContextCompat.getMainExecutor(getApplicationContext()),
-                listener,
-            )
-            .use {
-                runUiThreadTasks()
+        ComplicationDataExpressionEvaluator.Compat(DATA_WITH_NO_EXPRESSION, listener).use {
+            runUiThreadTasks()
 
-                verify(listener, never()).accept(any())
-            }
+            verify(listener, never()).accept(any())
+        }
     }
 
     @Test
     fun compat_noExpression_listenerInvokedWithData() {
-        ComplicationDataExpressionEvaluator.Compat(
-                DATA_WITH_NO_EXPRESSION,
-                ContextCompat.getMainExecutor(getApplicationContext()),
-                listener,
-            )
-            .use { evaluator ->
-                evaluator.init()
-                runUiThreadTasks()
+        ComplicationDataExpressionEvaluator.Compat(DATA_WITH_NO_EXPRESSION, listener).use {
+            evaluator ->
+            evaluator.init(ContextCompat.getMainExecutor(getApplicationContext()))
+            runUiThreadTasks()
 
-                verify(listener, times(1)).accept(DATA_WITH_NO_EXPRESSION)
-            }
+            verify(listener, times(1)).accept(DATA_WITH_NO_EXPRESSION)
+        }
     }
 
     private companion object {
diff --git a/window/extensions/extensions/api/current.txt b/window/extensions/extensions/api/current.txt
index f0c699b..6988f4b 100644
--- a/window/extensions/extensions/api/current.txt
+++ b/window/extensions/extensions/api/current.txt
@@ -4,6 +4,7 @@
   public interface WindowExtensions {
     method public default androidx.window.extensions.embedding.ActivityEmbeddingComponent? getActivityEmbeddingComponent();
     method public default int getVendorApiLevel();
+    method public default androidx.window.extensions.area.WindowAreaComponent? getWindowAreaComponent();
     method public androidx.window.extensions.layout.WindowLayoutComponent? getWindowLayoutComponent();
   }
 
@@ -13,6 +14,22 @@
 
 }
 
+package androidx.window.extensions.area {
+
+  public interface WindowAreaComponent {
+    method public void addRearDisplayStatusListener(androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    method public void endRearDisplaySession();
+    method public void removeRearDisplayStatusListener(androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    method public void startRearDisplaySession(android.app.Activity, androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    field public static final int SESSION_STATE_ACTIVE = 1; // 0x1
+    field public static final int SESSION_STATE_INACTIVE = 0; // 0x0
+    field public static final int STATUS_AVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNSUPPORTED = 0; // 0x0
+  }
+
+}
+
 package androidx.window.extensions.embedding {
 
   public interface ActivityEmbeddingComponent {
@@ -52,6 +69,7 @@
     method @ColorInt public int getAnimationBackgroundColor();
     method public int getLayoutDirection();
     method public androidx.window.extensions.embedding.SplitAttributes.SplitType getSplitType();
+    field @ColorInt public static final int DEFAULT_ANIMATION_BACKGROUND_COLOR = 0; // 0x0
   }
 
   public static final class SplitAttributes.Builder {
diff --git a/window/extensions/extensions/api/public_plus_experimental_current.txt b/window/extensions/extensions/api/public_plus_experimental_current.txt
index f0c699b..6988f4b 100644
--- a/window/extensions/extensions/api/public_plus_experimental_current.txt
+++ b/window/extensions/extensions/api/public_plus_experimental_current.txt
@@ -4,6 +4,7 @@
   public interface WindowExtensions {
     method public default androidx.window.extensions.embedding.ActivityEmbeddingComponent? getActivityEmbeddingComponent();
     method public default int getVendorApiLevel();
+    method public default androidx.window.extensions.area.WindowAreaComponent? getWindowAreaComponent();
     method public androidx.window.extensions.layout.WindowLayoutComponent? getWindowLayoutComponent();
   }
 
@@ -13,6 +14,22 @@
 
 }
 
+package androidx.window.extensions.area {
+
+  public interface WindowAreaComponent {
+    method public void addRearDisplayStatusListener(androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    method public void endRearDisplaySession();
+    method public void removeRearDisplayStatusListener(androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    method public void startRearDisplaySession(android.app.Activity, androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    field public static final int SESSION_STATE_ACTIVE = 1; // 0x1
+    field public static final int SESSION_STATE_INACTIVE = 0; // 0x0
+    field public static final int STATUS_AVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNSUPPORTED = 0; // 0x0
+  }
+
+}
+
 package androidx.window.extensions.embedding {
 
   public interface ActivityEmbeddingComponent {
@@ -52,6 +69,7 @@
     method @ColorInt public int getAnimationBackgroundColor();
     method public int getLayoutDirection();
     method public androidx.window.extensions.embedding.SplitAttributes.SplitType getSplitType();
+    field @ColorInt public static final int DEFAULT_ANIMATION_BACKGROUND_COLOR = 0; // 0x0
   }
 
   public static final class SplitAttributes.Builder {
diff --git a/window/extensions/extensions/api/restricted_current.txt b/window/extensions/extensions/api/restricted_current.txt
index f0c699b..6988f4b 100644
--- a/window/extensions/extensions/api/restricted_current.txt
+++ b/window/extensions/extensions/api/restricted_current.txt
@@ -4,6 +4,7 @@
   public interface WindowExtensions {
     method public default androidx.window.extensions.embedding.ActivityEmbeddingComponent? getActivityEmbeddingComponent();
     method public default int getVendorApiLevel();
+    method public default androidx.window.extensions.area.WindowAreaComponent? getWindowAreaComponent();
     method public androidx.window.extensions.layout.WindowLayoutComponent? getWindowLayoutComponent();
   }
 
@@ -13,6 +14,22 @@
 
 }
 
+package androidx.window.extensions.area {
+
+  public interface WindowAreaComponent {
+    method public void addRearDisplayStatusListener(androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    method public void endRearDisplaySession();
+    method public void removeRearDisplayStatusListener(androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    method public void startRearDisplaySession(android.app.Activity, androidx.window.extensions.core.util.function.Consumer<java.lang.Integer!>);
+    field public static final int SESSION_STATE_ACTIVE = 1; // 0x1
+    field public static final int SESSION_STATE_INACTIVE = 0; // 0x0
+    field public static final int STATUS_AVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNSUPPORTED = 0; // 0x0
+  }
+
+}
+
 package androidx.window.extensions.embedding {
 
   public interface ActivityEmbeddingComponent {
@@ -52,6 +69,7 @@
     method @ColorInt public int getAnimationBackgroundColor();
     method public int getLayoutDirection();
     method public androidx.window.extensions.embedding.SplitAttributes.SplitType getSplitType();
+    field @ColorInt public static final int DEFAULT_ANIMATION_BACKGROUND_COLOR = 0; // 0x0
   }
 
   public static final class SplitAttributes.Builder {
diff --git a/window/extensions/extensions/src/test/java/androidx/window/extensions/embedding/SplitAttributesTest.java b/window/extensions/extensions/src/androidTest/java/androidx/window/extensions/embedding/SplitAttributesTest.java
similarity index 93%
rename from window/extensions/extensions/src/test/java/androidx/window/extensions/embedding/SplitAttributesTest.java
rename to window/extensions/extensions/src/androidTest/java/androidx/window/extensions/embedding/SplitAttributesTest.java
index 76a1107..0bd4c63 100644
--- a/window/extensions/extensions/src/test/java/androidx/window/extensions/embedding/SplitAttributesTest.java
+++ b/window/extensions/extensions/src/androidTest/java/androidx/window/extensions/embedding/SplitAttributesTest.java
@@ -36,17 +36,17 @@
         final SplitAttributes layout1 = new SplitAttributes.Builder()
                 .setSplitType(splitEqually())
                 .setLayoutDirection(LayoutDirection.LOCALE)
-                .setAnimationBackgroundColor(0)
+                .setAnimationBackgroundColor(SplitAttributes.DEFAULT_ANIMATION_BACKGROUND_COLOR)
                 .build();
         final SplitAttributes layout2 = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.HingeSplitType(splitEqually()))
                 .setLayoutDirection(LayoutDirection.LOCALE)
-                .setAnimationBackgroundColor(0)
+                .setAnimationBackgroundColor(SplitAttributes.DEFAULT_ANIMATION_BACKGROUND_COLOR)
                 .build();
         final SplitAttributes layout3 = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.HingeSplitType(splitEqually()))
                 .setLayoutDirection(LayoutDirection.TOP_TO_BOTTOM)
-                .setAnimationBackgroundColor(0)
+                .setAnimationBackgroundColor(SplitAttributes.DEFAULT_ANIMATION_BACKGROUND_COLOR)
                 .build();
         final SplitAttributes layout4 = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.HingeSplitType(splitEqually()))
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java
index 97a1a86..240e2dc 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java
@@ -20,6 +20,7 @@
 
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.window.extensions.area.WindowAreaComponent;
 import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
 import androidx.window.extensions.layout.WindowLayoutComponent;
 
@@ -61,6 +62,7 @@
      */
     @RestrictTo(LIBRARY_GROUP)
     int VENDOR_API_LEVEL_1 = 1;
+
     // TODO(b/241323716) Removed after we have annotation to check API level
     /**
      * A vendor API level constant. It helps to unify the format of documenting {@code @since}
@@ -109,4 +111,15 @@
     default ActivityEmbeddingComponent getActivityEmbeddingComponent() {
         return null;
     }
+
+    /**
+     * Returns the OEM implementation of {@link WindowAreaComponent} if it is supported on
+     * the device, {@code null} otherwise. The implementation must match the API level reported in
+     * {@link WindowExtensions}.
+     * @return the OEM implementation of {@link WindowAreaComponent}
+     */
+    @Nullable
+    default WindowAreaComponent getWindowAreaComponent() {
+        return null;
+    }
 }
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java
new file mode 100644
index 0000000..422e972
--- /dev/null
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2023 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 androidx.window.extensions.area;
+
+import android.app.Activity;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.window.extensions.WindowExtensions;
+import androidx.window.extensions.core.util.function.Consumer;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The interface definition that will be used by the WindowManager library to get custom
+ * OEM-provided behavior around moving windows between displays or display areas on a device.
+ *
+ * Currently the only behavior supported is RearDisplay Mode, where the window
+ * is moved to the display that faces the same direction as the rear camera.
+ *
+ * <p>This interface should be implemented by OEM and deployed to the target devices.
+ * @see WindowExtensions#getWindowLayoutComponent()
+ */
+public interface WindowAreaComponent {
+
+    /**
+     * WindowArea status constant to signify that the feature is
+     * unsupported on this device. Could be due to the device not supporting that
+     * specific feature.
+     */
+    int STATUS_UNSUPPORTED = 0;
+
+    /**
+     * WindowArea status constant to signify that the feature is
+     * currently unavailable but is supported on this device. This value could signify
+     * that the current device state does not support the specific feature or another
+     * process is currently enabled in that feature.
+     */
+    int STATUS_UNAVAILABLE = 1;
+
+    /**
+     * WindowArea status constant to signify that the feature is
+     * available to be entered or enabled.
+     */
+    int STATUS_AVAILABLE = 2;
+
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+    @IntDef({
+            STATUS_UNSUPPORTED,
+            STATUS_UNAVAILABLE,
+            STATUS_AVAILABLE
+    })
+    @interface WindowAreaStatus {}
+
+    /**
+     * Session state constant to represent there being no active session
+     * currently in progress. Used by the library to call the correct callbacks if
+     * a session is ended.
+     */
+    int SESSION_STATE_INACTIVE = 0;
+
+    /**
+     * Session state constant to represent that there is an
+     * active session currently in progress. Used by the library to
+     * know when to return the session object to the developer when the
+     * session is created and active.
+     */
+    int SESSION_STATE_ACTIVE = 1;
+
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+    @IntDef({
+            SESSION_STATE_ACTIVE,
+            SESSION_STATE_INACTIVE
+    })
+    @interface WindowAreaSessionState {}
+
+    /**
+     * Adds a listener interested in receiving updates on the RearDisplayStatus
+     * of the device. Because this is being called from the OEM provided
+     * extensions, the library will post the result of the listener on the executor
+     * provided by the developer.
+     *
+     * The listener provided will receive values that
+     * correspond to the [WindowAreaStatus] value that aligns with the current status
+     * of the rear display.
+     * @param consumer interested in receiving updates to WindowAreaStatus.
+     */
+    void addRearDisplayStatusListener(@NonNull Consumer<@WindowAreaStatus Integer> consumer);
+
+    /**
+     * Removes a listener no longer interested in receiving updates.
+     * @param consumer no longer interested in receiving updates to WindowAreaStatus
+     */
+    void removeRearDisplayStatusListener(@NonNull Consumer<@WindowAreaStatus Integer> consumer);
+
+    /**
+     * Creates and starts a rear display session and sends state updates to the
+     * consumer provided. This consumer will receive a constant represented by
+     * [WindowAreaSessionState] to represent the state of the current rear display
+     * session. We will translate the values from the {@link Consumer} to a developer-friendly
+     * interface in the developer facing API.
+     *
+     * Because this is being called from the OEM provided extensions, the library
+     * will post the result of the listener on the executor provided by the developer.
+     *
+     * @param activity to allow that the OEM implementation will use as a base
+     * context and to identify the source display area of the request.
+     * The reference to the activity instance must not be stored in the OEM
+     * implementation to prevent memory leaks.
+     * @param consumer to provide updates to the client on the status of the session
+     * @throws UnsupportedOperationException if this method is called when RearDisplay
+     * mode is not available. This could be to an incompatible device state or when
+     * another process is currently in this mode.
+     */
+    void startRearDisplaySession(@NonNull Activity activity,
+            @NonNull Consumer<@WindowAreaSessionState Integer> consumer);
+
+    /**
+     * Ends a RearDisplaySession and sends [STATE_INACTIVE] to the consumer
+     * provided in the {@code startRearDisplaySession} method. This method is only
+     * called through the {@code RearDisplaySession} provided to the developer.
+     */
+    void endRearDisplaySession();
+}
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitAttributes.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitAttributes.java
index 59f8a02..e4f1e81 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitAttributes.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitAttributes.java
@@ -23,6 +23,7 @@
 import static androidx.window.extensions.embedding.SplitAttributes.LayoutDirection.TOP_TO_BOTTOM;
 
 import android.annotation.SuppressLint;
+import android.graphics.Color;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.FloatRange;
@@ -66,6 +67,19 @@
  * Since {@link androidx.window.extensions.WindowExtensions#VENDOR_API_LEVEL_2}
  */
 public class SplitAttributes {
+
+    /**
+     * The default value for animation background color, which means to use the current theme window
+     * background color.
+     *
+     * Only opaque color is supported, so {@code 0} is used as the default. Any other non-opaque
+     * color will be treated as the default.
+     *
+     * @see Builder#setAnimationBackgroundColor(int)
+     */
+    @ColorInt
+    public static final int DEFAULT_ANIMATION_BACKGROUND_COLOR = 0;
+
     /**
      * The type of window split, which defines the proportion of the parent
      * window occupied by the primary and secondary activity containers.
@@ -413,6 +427,9 @@
      * Gets the {@link ColorInt} to use for the background color during the
      * animation of the split involving this {@code SplitAttributes} object.
      *
+     * The default is {@link #DEFAULT_ANIMATION_BACKGROUND_COLOR}, which means
+     * to use the current theme window background color.
+     *
      * @return The animation background {@code ColorInt}.
      */
     @ColorInt
@@ -423,10 +440,9 @@
     /**
      * Builder for creating an instance of {@link SplitAttributes}.
      *
-     * The default split type is an equal split between primary and secondary
-     * containers. The default layout direction is based on locale. The default
-     * animation background color is 0, which specifies the theme window
-     * background color.
+     * - The default split type is an equal split between primary and secondary containers.
+     * - The default layout direction is based on locale.
+     * - The default animation background color is to use the current theme window background color.
      */
     public static final class Builder {
         @NonNull
@@ -481,16 +497,23 @@
          * animation of the split involving this {@code SplitAttributes} object
          * if the animation requires a background.
          *
-         * The default value is 0, which specifies the theme window background
-         * color.
+         * Only opaque color is supported.
+         *
+         * The default value is {@link #DEFAULT_ANIMATION_BACKGROUND_COLOR}, which
+         * means to use the current theme window background color. Any non-opaque
+         * animation color will be treated as
+         * {@link #DEFAULT_ANIMATION_BACKGROUND_COLOR}.
          *
          * @param color A packed color int of the form {@code AARRGGBB} for the
-         *     animation background color.
+         *              animation background color.
          * @return This {@code Builder}.
          */
         @NonNull
         public Builder setAnimationBackgroundColor(@ColorInt int color) {
-            mAnimationBackgroundColor = color;
+            // Any non-opaque color will be treated as the default.
+            mAnimationBackgroundColor = Color.alpha(color) != 255
+                    ? DEFAULT_ANIMATION_BACKGROUND_COLOR
+                    : color;
             return this;
         }
 
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitInfo.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitInfo.java
index 717039b..33b8bb7 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitInfo.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/embedding/SplitInfo.java
@@ -24,6 +24,7 @@
 
 /** Describes a split of two containers with activities. */
 public class SplitInfo {
+
     @NonNull
     private final ActivityStack mPrimaryActivityStack;
     @NonNull
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/layout/WindowLayoutComponent.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/layout/WindowLayoutComponent.java
index 5573abb..9ed7d17 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/layout/WindowLayoutComponent.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/layout/WindowLayoutComponent.java
@@ -40,10 +40,11 @@
  */
 public interface WindowLayoutComponent {
     /**
-     * @deprecated Use {@link #addWindowLayoutInfoListener(Context,Consumer)}
+     * @deprecated Use {@link #addWindowLayoutInfoListener(Context, Consumer)}
      * starting with {@link WindowExtensions#VENDOR_API_LEVEL_2}. Only used if
      * {@link #addWindowLayoutInfoListener(Context, Consumer)} can't be
      * called on {@link WindowExtensions#VENDOR_API_LEVEL_1}.
+     * Since {@link WindowExtensions#VENDOR_API_LEVEL_1}
      */
     @Deprecated
     void addWindowLayoutInfoListener(@NonNull Activity activity,
@@ -54,6 +55,7 @@
      * {@link WindowExtensions#VENDOR_API_LEVEL_2}. Only used if
      * {@link #removeWindowLayoutInfoListener(Consumer)} can't be called on
      * {@link WindowExtensions#VENDOR_API_LEVEL_1}.
+     * Since {@link WindowExtensions#VENDOR_API_LEVEL_1}
      */
     @Deprecated
     void removeWindowLayoutInfoListener(
@@ -61,7 +63,11 @@
 
     // TODO(b/264546746): Remove addWindowLayoutInfoListener(Context, java.util.function.Consumer)
     //  after apps update to the latest WM Jetpack library.
-    /** @deprecated Use {@link #addWindowLayoutInfoListener(Context, Consumer)} instead */
+
+    /**
+     * @deprecated Use {@link #addWindowLayoutInfoListener(Context, Consumer)} instead
+     * Since {@link WindowExtensions#VENDOR_API_LEVEL_2}
+     */
     @SuppressWarnings("PairedRegistration")
     // The paired method for unregistering is also removeWindowLayoutInfoListener.
     @Deprecated
diff --git a/window/window-demos/demo/build.gradle b/window/window-demos/demo/build.gradle
index e579b7f..bc8df52 100644
--- a/window/window-demos/demo/build.gradle
+++ b/window/window-demos/demo/build.gradle
@@ -87,4 +87,4 @@
     type = LibraryType.SAMPLES
     inceptionYear = "2023"
     description = "Samples for the WM Jetpack Library"
-}
\ No newline at end of file
+}
diff --git a/window/window-demos/demo/src/main/AndroidManifest.xml b/window/window-demos/demo/src/main/AndroidManifest.xml
index 36b547be..932003e 100644
--- a/window/window-demos/demo/src/main/AndroidManifest.xml
+++ b/window/window-demos/demo/src/main/AndroidManifest.xml
@@ -58,6 +58,16 @@
             android:exported="false"
             android:configChanges="orientation|screenSize|screenLayout|screenSize"
             android:label="@string/window_metrics"/>
+        <activity android:name=".area.RearDisplayActivityConfigChanges"
+            android:exported="true"
+            android:configChanges=
+                "orientation|screenLayout|screenSize|layoutDirection|smallestScreenSize"
+            android:label="@string/rear_display">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         <activity
             android:name=".embedding.SplitActivityA"
             android:exported="true"
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/area/RearDisplayActivityConfigChanges.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/area/RearDisplayActivityConfigChanges.kt
new file mode 100644
index 0000000..edb2ed1
--- /dev/null
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/area/RearDisplayActivityConfigChanges.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2023 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 androidx.window.demo.area
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.core.util.Consumer
+import androidx.window.area.WindowAreaController
+import androidx.window.area.WindowAreaSession
+import androidx.window.area.WindowAreaSessionCallback
+import androidx.window.area.WindowAreaStatus
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.demo.common.infolog.InfoLogAdapter
+import androidx.window.demo.databinding.ActivityRearDisplayBinding
+import androidx.window.java.area.WindowAreaControllerJavaAdapter
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.concurrent.Executor
+
+/**
+ * Demo Activity that showcases listening for RearDisplay Status
+ * as well as enabling/disabling RearDisplay mode. This Activity
+ * implements [WindowAreaSessionCallback] for simplicity.
+ *
+ * This Activity overrides configuration changes for simplicity.
+ */
+@OptIn(ExperimentalWindowApi::class)
+class RearDisplayActivityConfigChanges : AppCompatActivity(), WindowAreaSessionCallback {
+
+    private lateinit var windowAreaController: WindowAreaControllerJavaAdapter
+    private var rearDisplaySession: WindowAreaSession? = null
+    private val infoLogAdapter = InfoLogAdapter()
+    private lateinit var binding: ActivityRearDisplayBinding
+    private lateinit var executor: Executor
+
+    private val rearDisplayStatusListener = Consumer<WindowAreaStatus> { status ->
+        infoLogAdapter.append(getCurrentTimeString(), status.toString())
+        infoLogAdapter.notifyDataSetChanged()
+        updateRearDisplayButton(status)
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        binding = ActivityRearDisplayBinding.inflate(layoutInflater)
+        setContentView(binding.root)
+
+        executor = ContextCompat.getMainExecutor(this)
+        windowAreaController = WindowAreaControllerJavaAdapter(WindowAreaController.getOrCreate())
+
+        binding.rearStatusRecyclerView.adapter = infoLogAdapter
+
+        binding.rearDisplayButton.setOnClickListener {
+            if (rearDisplaySession != null) {
+                rearDisplaySession?.close()
+            } else {
+                windowAreaController.startRearDisplayModeSession(
+                    this,
+                    executor,
+                    this)
+            }
+        }
+    }
+
+    override fun onStart() {
+        super.onStart()
+        windowAreaController.addRearDisplayStatusListener(
+            executor,
+            rearDisplayStatusListener
+        )
+    }
+
+    override fun onStop() {
+        super.onStop()
+        windowAreaController.removeRearDisplayStatusListener(rearDisplayStatusListener)
+    }
+
+    override fun onSessionStarted(session: WindowAreaSession) {
+        rearDisplaySession = session
+        infoLogAdapter.append(getCurrentTimeString(), "RearDisplay Session has been started")
+        infoLogAdapter.notifyDataSetChanged()
+    }
+
+    override fun onSessionEnded() {
+        rearDisplaySession = null
+        infoLogAdapter.append(getCurrentTimeString(), "RearDisplay Session has ended")
+        infoLogAdapter.notifyDataSetChanged()
+    }
+
+    private fun updateRearDisplayButton(status: WindowAreaStatus) {
+        if (rearDisplaySession != null) {
+            binding.rearDisplayButton.isEnabled = true
+            binding.rearDisplayButton.text = "Disable RearDisplay Mode"
+            return
+        }
+        when (status) {
+            WindowAreaStatus.UNSUPPORTED -> {
+                binding.rearDisplayButton.isEnabled = false
+                binding.rearDisplayButton.text = "RearDisplay is not supported on this device"
+            }
+            WindowAreaStatus.UNAVAILABLE -> {
+                binding.rearDisplayButton.isEnabled = false
+                binding.rearDisplayButton.text = "RearDisplay is not currently available"
+            }
+            WindowAreaStatus.AVAILABLE -> {
+                binding.rearDisplayButton.isEnabled = true
+                binding.rearDisplayButton.text = "Enable RearDisplay Mode"
+            }
+        }
+    }
+
+    private fun getCurrentTimeString(): String {
+        val sdf = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault())
+        val currentDate = sdf.format(Date())
+        return currentDate.toString()
+    }
+
+    private companion object {
+        private val TAG = RearDisplayActivityConfigChanges::class.java.simpleName
+    }
+}
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/DemoActivityEmbeddingController.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/DemoActivityEmbeddingController.kt
index 0d3771e..69542ac 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/DemoActivityEmbeddingController.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/DemoActivityEmbeddingController.kt
@@ -16,8 +16,8 @@
 
 package androidx.window.demo.embedding
 
-import androidx.annotation.ColorInt
 import androidx.annotation.GuardedBy
+import androidx.window.embedding.SplitAttributes
 import java.util.concurrent.locks.ReentrantLock
 import kotlin.concurrent.withLock
 
@@ -27,16 +27,14 @@
     private val lock = Object()
 
     @GuardedBy("lock")
-    @ColorInt
-    private var _animationBackgroundColor = 0
+    private var _animationBackgroundColor = SplitAttributes.BackgroundColor.DEFAULT
 
     /** Animation background color to use when the animation requires a background. */
-    var animationBackgroundColor: Int
-        @ColorInt
+    var animationBackgroundColor: SplitAttributes.BackgroundColor
         get() = synchronized(lock) {
             _animationBackgroundColor
         }
-        set(@ColorInt value) = synchronized(lock) {
+        set(value) = synchronized(lock) {
             _animationBackgroundColor = value
         }
 
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt
index 5f686b2..56850b4 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt
@@ -410,12 +410,12 @@
         const val SUFFIX_REVERSED = "_reversed"
         const val SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP = "_and_horizontal_layout_in_tabletop"
         const val SUFFIX_AND_FULLSCREEN_IN_BOOK_MODE = "_and_fullscreen_in_book_mode"
-        val ANIMATION_BACKGROUND_COLORS_TEXT = arrayOf("BLACK", "BLUE", "GREEN", "YELLOW")
+        val ANIMATION_BACKGROUND_COLORS_TEXT = arrayOf("DEFAULT", "BLUE", "GREEN", "YELLOW")
         val ANIMATION_BACKGROUND_COLORS_VALUE = arrayOf(
-            Color.BLACK,
-            Color.BLUE,
-            Color.GREEN,
-            Color.YELLOW
+            SplitAttributes.BackgroundColor.DEFAULT,
+            SplitAttributes.BackgroundColor.color(Color.BLUE),
+            SplitAttributes.BackgroundColor.color(Color.GREEN),
+            SplitAttributes.BackgroundColor.color(Color.YELLOW)
         )
 
         /**
diff --git a/window/window-java/api/public_plus_experimental_current.txt b/window/window-java/api/public_plus_experimental_current.txt
index 39c35ac..ded945be 100644
--- a/window/window-java/api/public_plus_experimental_current.txt
+++ b/window/window-java/api/public_plus_experimental_current.txt
@@ -1,4 +1,15 @@
 // Signature format: 4.0
+package androidx.window.java.area {
+
+  @androidx.window.core.ExperimentalWindowApi public final class WindowAreaControllerJavaAdapter implements androidx.window.area.WindowAreaController {
+    ctor public WindowAreaControllerJavaAdapter(androidx.window.area.WindowAreaController controller);
+    method public void addRearDisplayStatusListener(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.window.area.WindowAreaStatus> consumer);
+    method public void removeRearDisplayStatusListener(androidx.core.util.Consumer<androidx.window.area.WindowAreaStatus> consumer);
+    method public void startRearDisplayModeSession(android.app.Activity activity, java.util.concurrent.Executor executor, androidx.window.area.WindowAreaSessionCallback windowAreaSessionCallback);
+  }
+
+}
+
 package androidx.window.java.layout {
 
   public final class WindowInfoTrackerCallbackAdapter implements androidx.window.layout.WindowInfoTracker {
diff --git a/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt b/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
index 74b3d87..bd6ae04 100644
--- a/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
+++ b/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
@@ -18,6 +18,7 @@
 
 import android.app.Activity
 import android.content.Context
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.java.TestConsumer
 import androidx.window.layout.FoldingFeature
 import androidx.window.layout.WindowInfoTracker
@@ -35,6 +36,7 @@
  * from the kotlin coroutine API to listeners and callbacks.
  * @see WindowInfoTracker
  */
+@OptIn(ExperimentalWindowApi::class)
 public class WindowInfoTrackerCallbackAdapterTest {
 
     @Test
diff --git a/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt b/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt
new file mode 100644
index 0000000..692d565
--- /dev/null
+++ b/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2023 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 androidx.window.java.area
+
+import android.app.Activity
+import androidx.core.util.Consumer
+import androidx.window.area.WindowAreaSessionCallback
+import androidx.window.area.WindowAreaStatus
+import androidx.window.area.WindowAreaController
+import androidx.window.core.ExperimentalWindowApi
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+import java.util.concurrent.Executor
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
+
+/**
+ * An adapted interface for [WindowAreaController] that provides the information and
+ * functionality around RearDisplay Mode via a callback shaped API.
+ */
+@ExperimentalWindowApi
+class WindowAreaControllerJavaAdapter(
+    private val controller: WindowAreaController
+) : WindowAreaController by controller {
+
+    /**
+     * A [ReentrantLock] to protect against concurrent access to [consumerToJobMap].
+     */
+    private val lock = ReentrantLock()
+    private val consumerToJobMap = mutableMapOf<Consumer<*>, Job>()
+
+    /**
+     * Registers a listener to consume [WindowAreaStatus] values defined as
+     * [WindowAreaStatus.UNSUPPORTED], [WindowAreaStatus.UNAVAILABLE], and
+     * [WindowAreaStatus.AVAILABLE]. The values provided through this listener should be used
+     * to determine if you are able to enable rear display Mode at that time. You can use these
+     * values to modify your UI to show/hide controls and determine when to enable features
+     * that use rear display Mode. You should only try and enter rear display mode when your
+     * [consumer] is provided a value of [WindowAreaStatus.AVAILABLE].
+     *
+     * The [consumer] will be provided an initial value on registration, as well as any change
+     * to the status as they occur. This could happen due to hardware device state changes, or if
+     * another process has enabled RearDisplay Mode.
+     *
+     * @see WindowAreaController.rearDisplayStatus
+     */
+    fun addRearDisplayStatusListener(
+        executor: Executor,
+        consumer: Consumer<WindowAreaStatus>
+    ) {
+        val statusFlow = controller.rearDisplayStatus()
+        lock.withLock {
+            if (consumerToJobMap[consumer] == null) {
+                val scope = CoroutineScope(executor.asCoroutineDispatcher())
+                consumerToJobMap[consumer] = scope.launch {
+                    statusFlow.collect { consumer.accept(it) }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a listener of [WindowAreaStatus] values
+     * @see WindowAreaController.rearDisplayStatus
+     */
+    fun removeRearDisplayStatusListener(consumer: Consumer<WindowAreaStatus>) {
+        lock.withLock {
+            consumerToJobMap[consumer]?.cancel()
+            consumerToJobMap.remove(consumer)
+        }
+    }
+
+    /**
+     * Starts a RearDisplay Mode session and provides updates through the
+     * [WindowAreaSessionCallback] provided. Due to the nature of moving your Activity to a
+     * different display, your Activity will likely go through a configuration change. Because of
+     * this, if your Activity does not override configuration changes, this method should be called
+     * from a component that outlives the Activity lifecycle such as a
+     * [androidx.lifecycle.ViewModel]. If your Activity does override
+     * configuration changes, it is safe to call this method inside your Activity.
+     *
+     * This method should only be called if you have received a [WindowAreaStatus.AVAILABLE]
+     * value from the listener provided through the [addRearDisplayStatusListener] method. If
+     * you try and enable RearDisplay mode without it being available, you will receive an
+     * [UnsupportedOperationException].
+     *
+     * The [windowAreaSessionCallback] provided will receive a call to
+     * [WindowAreaSessionCallback.onSessionStarted] after your Activity has been moved to the
+     * display corresponding to this mode. RearDisplay mode will stay active until the session
+     * provided through [WindowAreaSessionCallback.onSessionStarted] is closed, or there is a device
+     * state change that makes RearDisplay mode incompatible such as if the device is closed so the
+     * outer-display is no longer in line with the rear camera. When this occurs,
+     * [WindowAreaSessionCallback.onSessionEnded] is called to notify you the session has been
+     * ended.
+     *
+     * @see addRearDisplayStatusListener
+     * @throws UnsupportedOperationException if you try and start a RearDisplay session when
+     * your [WindowAreaController.rearDisplayStatus] does not return a value of
+     * [WindowAreaStatus.AVAILABLE]
+     */
+    fun startRearDisplayModeSession(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    ) {
+        controller.rearDisplayMode(activity, executor, windowAreaSessionCallback)
+    }
+}
\ No newline at end of file
diff --git a/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt b/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt
index 5966d28..35b10d3 100644
--- a/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt
+++ b/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt
@@ -21,6 +21,7 @@
 import androidx.annotation.UiContext
 import androidx.core.util.Consumer
 import android.inputmethodservice.InputMethodService
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
 import kotlinx.coroutines.CoroutineScope
@@ -72,6 +73,7 @@
      * @param consumer for [WindowLayoutInfo] values.
      * @see WindowInfoTracker.windowLayoutInfo
      */
+    @OptIn(ExperimentalWindowApi::class)
     fun addWindowLayoutInfoListener(
         @UiContext context: Context,
         executor: Executor,
diff --git a/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt b/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
index 418725d..038ad11 100644
--- a/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
+++ b/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
@@ -18,6 +18,7 @@
 
 import android.app.Activity
 import android.content.Context
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.FoldingFeature
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
@@ -29,6 +30,7 @@
 /**
  * Tests for the RxJava 2 adapters.
  */
+@OptIn(ExperimentalWindowApi::class)
 class WindowInfoTrackerRxTest {
 
     @Test
diff --git a/window/window-rxjava2/src/main/java/androidx/window/rxjava2/layout/WindowInfoTrackerRx.kt b/window/window-rxjava2/src/main/java/androidx/window/rxjava2/layout/WindowInfoTrackerRx.kt
index d41cc80..1833993 100644
--- a/window/window-rxjava2/src/main/java/androidx/window/rxjava2/layout/WindowInfoTrackerRx.kt
+++ b/window/window-rxjava2/src/main/java/androidx/window/rxjava2/layout/WindowInfoTrackerRx.kt
@@ -20,6 +20,7 @@
 import android.app.Activity
 import android.content.Context
 import androidx.annotation.UiContext
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
 import io.reactivex.Flowable
@@ -51,6 +52,7 @@
  * Return an [Observable] stream of [WindowLayoutInfo].
  * @see WindowInfoTracker.windowLayoutInfo
  */
+@OptIn(ExperimentalWindowApi::class)
 fun WindowInfoTracker.windowLayoutInfoObservable(
     @UiContext context: Context
 ): Observable<WindowLayoutInfo> {
@@ -61,6 +63,7 @@
  * Return a [Flowable] stream of [WindowLayoutInfo].
  * @see WindowInfoTracker.windowLayoutInfo
  */
+@OptIn(ExperimentalWindowApi::class)
 fun WindowInfoTracker.windowLayoutInfoFlowable(
     @UiContext context: Context
 ): Flowable<WindowLayoutInfo> {
diff --git a/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt b/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
index f4a4c4c..8630cc6 100644
--- a/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
+++ b/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
@@ -18,6 +18,7 @@
 
 import android.app.Activity
 import android.content.Context
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.FoldingFeature
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
@@ -31,6 +32,7 @@
  * [io.reactivex.rxjava3.core.Flowable] and ensure that data is forwarded appropriately.
  * @see WindowInfoTracker
  */
+@OptIn(ExperimentalWindowApi::class)
 class WindowInfoTrackerRxTest {
 
     @Test
diff --git a/window/window-rxjava3/src/main/java/androidx/window/rxjava3/layout/WindowInfoTrackerRx.kt b/window/window-rxjava3/src/main/java/androidx/window/rxjava3/layout/WindowInfoTrackerRx.kt
index 084292b..d41a416 100644
--- a/window/window-rxjava3/src/main/java/androidx/window/rxjava3/layout/WindowInfoTrackerRx.kt
+++ b/window/window-rxjava3/src/main/java/androidx/window/rxjava3/layout/WindowInfoTrackerRx.kt
@@ -20,6 +20,7 @@
 import android.app.Activity
 import android.content.Context
 import androidx.annotation.UiContext
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
 import io.reactivex.rxjava3.core.Flowable
@@ -51,6 +52,7 @@
  * Return an [Observable] stream of [WindowLayoutInfo].
  * @see WindowInfoTracker.windowLayoutInfo
  */
+@OptIn(ExperimentalWindowApi::class)
 fun WindowInfoTracker.windowLayoutInfoObservable(
     @UiContext context: Context
 ): Observable<WindowLayoutInfo> {
@@ -61,6 +63,7 @@
  * Return a [Flowable] stream of [WindowLayoutInfo].
  * @see WindowInfoTracker.windowLayoutInfo
  */
+@OptIn(ExperimentalWindowApi::class)
 fun WindowInfoTracker.windowLayoutInfoFlowable(
     @UiContext context: Context
 ): Flowable<WindowLayoutInfo> {
diff --git a/window/window/api/current.txt b/window/window/api/current.txt
index 2a716a3..356f9c3 100644
--- a/window/window/api/current.txt
+++ b/window/window/api/current.txt
@@ -84,19 +84,29 @@
   }
 
   public final class SplitAttributes {
-    method public int getAnimationBackgroundColor();
+    method public androidx.window.embedding.SplitAttributes.BackgroundColor getAnimationBackgroundColor();
     method public androidx.window.embedding.SplitAttributes.LayoutDirection getLayoutDirection();
     method public androidx.window.embedding.SplitAttributes.SplitType getSplitType();
-    property public final int animationBackgroundColor;
+    property public final androidx.window.embedding.SplitAttributes.BackgroundColor animationBackgroundColor;
     property public final androidx.window.embedding.SplitAttributes.LayoutDirection layoutDirection;
     property public final androidx.window.embedding.SplitAttributes.SplitType splitType;
     field public static final androidx.window.embedding.SplitAttributes.Companion Companion;
   }
 
+  public static final class SplitAttributes.BackgroundColor {
+    method public static androidx.window.embedding.SplitAttributes.BackgroundColor color(@ColorInt @IntRange(from=android.graphics.Color.BLACK.toLong(), to=android.graphics.Color.WHITE.toLong()) int color);
+    field public static final androidx.window.embedding.SplitAttributes.BackgroundColor.Companion Companion;
+    field public static final androidx.window.embedding.SplitAttributes.BackgroundColor DEFAULT;
+  }
+
+  public static final class SplitAttributes.BackgroundColor.Companion {
+    method public androidx.window.embedding.SplitAttributes.BackgroundColor color(@ColorInt @IntRange(from=android.graphics.Color.BLACK.toLong(), to=android.graphics.Color.WHITE.toLong()) int color);
+  }
+
   public static final class SplitAttributes.Builder {
     ctor public SplitAttributes.Builder();
     method public androidx.window.embedding.SplitAttributes build();
-    method public androidx.window.embedding.SplitAttributes.Builder setAnimationBackgroundColor(@ColorInt int color);
+    method public androidx.window.embedding.SplitAttributes.Builder setAnimationBackgroundColor(androidx.window.embedding.SplitAttributes.BackgroundColor color);
     method public androidx.window.embedding.SplitAttributes.Builder setLayoutDirection(androidx.window.embedding.SplitAttributes.LayoutDirection layoutDirection);
     method public androidx.window.embedding.SplitAttributes.Builder setSplitType(androidx.window.embedding.SplitAttributes.SplitType type);
   }
@@ -326,7 +336,6 @@
 
   public interface WindowInfoTracker {
     method public default static androidx.window.layout.WindowInfoTracker getOrCreate(android.content.Context context);
-    method public default kotlinx.coroutines.flow.Flow<androidx.window.layout.WindowLayoutInfo> windowLayoutInfo(@UiContext android.content.Context context);
     method public kotlinx.coroutines.flow.Flow<androidx.window.layout.WindowLayoutInfo> windowLayoutInfo(android.app.Activity activity);
     field public static final androidx.window.layout.WindowInfoTracker.Companion Companion;
   }
diff --git a/window/window/api/public_plus_experimental_current.txt b/window/window/api/public_plus_experimental_current.txt
index 986a2d0..ffb1d62 100644
--- a/window/window/api/public_plus_experimental_current.txt
+++ b/window/window/api/public_plus_experimental_current.txt
@@ -9,6 +9,40 @@
 
 }
 
+package androidx.window.area {
+
+  @androidx.window.core.ExperimentalWindowApi public interface WindowAreaController {
+    method public default static androidx.window.area.WindowAreaController getOrCreate();
+    method public void rearDisplayMode(android.app.Activity activity, java.util.concurrent.Executor executor, androidx.window.area.WindowAreaSessionCallback windowAreaSessionCallback);
+    method public kotlinx.coroutines.flow.Flow<androidx.window.area.WindowAreaStatus> rearDisplayStatus();
+    field public static final androidx.window.area.WindowAreaController.Companion Companion;
+  }
+
+  public static final class WindowAreaController.Companion {
+    method public androidx.window.area.WindowAreaController getOrCreate();
+  }
+
+  @androidx.window.core.ExperimentalWindowApi public interface WindowAreaSession {
+    method public void close();
+  }
+
+  @androidx.window.core.ExperimentalWindowApi public interface WindowAreaSessionCallback {
+    method public void onSessionEnded();
+    method public void onSessionStarted(androidx.window.area.WindowAreaSession session);
+  }
+
+  @androidx.window.core.ExperimentalWindowApi public final class WindowAreaStatus {
+    field public static final androidx.window.area.WindowAreaStatus AVAILABLE;
+    field public static final androidx.window.area.WindowAreaStatus.Companion Companion;
+    field public static final androidx.window.area.WindowAreaStatus UNAVAILABLE;
+    field public static final androidx.window.area.WindowAreaStatus UNSUPPORTED;
+  }
+
+  public static final class WindowAreaStatus.Companion {
+  }
+
+}
+
 package androidx.window.core {
 
   @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalWindowApi {
@@ -91,19 +125,29 @@
   }
 
   public final class SplitAttributes {
-    method public int getAnimationBackgroundColor();
+    method public androidx.window.embedding.SplitAttributes.BackgroundColor getAnimationBackgroundColor();
     method public androidx.window.embedding.SplitAttributes.LayoutDirection getLayoutDirection();
     method public androidx.window.embedding.SplitAttributes.SplitType getSplitType();
-    property public final int animationBackgroundColor;
+    property public final androidx.window.embedding.SplitAttributes.BackgroundColor animationBackgroundColor;
     property public final androidx.window.embedding.SplitAttributes.LayoutDirection layoutDirection;
     property public final androidx.window.embedding.SplitAttributes.SplitType splitType;
     field public static final androidx.window.embedding.SplitAttributes.Companion Companion;
   }
 
+  public static final class SplitAttributes.BackgroundColor {
+    method public static androidx.window.embedding.SplitAttributes.BackgroundColor color(@ColorInt @IntRange(from=android.graphics.Color.BLACK.toLong(), to=android.graphics.Color.WHITE.toLong()) int color);
+    field public static final androidx.window.embedding.SplitAttributes.BackgroundColor.Companion Companion;
+    field public static final androidx.window.embedding.SplitAttributes.BackgroundColor DEFAULT;
+  }
+
+  public static final class SplitAttributes.BackgroundColor.Companion {
+    method public androidx.window.embedding.SplitAttributes.BackgroundColor color(@ColorInt @IntRange(from=android.graphics.Color.BLACK.toLong(), to=android.graphics.Color.WHITE.toLong()) int color);
+  }
+
   public static final class SplitAttributes.Builder {
     ctor public SplitAttributes.Builder();
     method public androidx.window.embedding.SplitAttributes build();
-    method public androidx.window.embedding.SplitAttributes.Builder setAnimationBackgroundColor(@ColorInt int color);
+    method public androidx.window.embedding.SplitAttributes.Builder setAnimationBackgroundColor(androidx.window.embedding.SplitAttributes.BackgroundColor color);
     method public androidx.window.embedding.SplitAttributes.Builder setLayoutDirection(androidx.window.embedding.SplitAttributes.LayoutDirection layoutDirection);
     method public androidx.window.embedding.SplitAttributes.Builder setSplitType(androidx.window.embedding.SplitAttributes.SplitType type);
   }
@@ -336,7 +380,7 @@
 
   public interface WindowInfoTracker {
     method public default static androidx.window.layout.WindowInfoTracker getOrCreate(android.content.Context context);
-    method public default kotlinx.coroutines.flow.Flow<androidx.window.layout.WindowLayoutInfo> windowLayoutInfo(@UiContext android.content.Context context);
+    method @androidx.window.core.ExperimentalWindowApi public default kotlinx.coroutines.flow.Flow<androidx.window.layout.WindowLayoutInfo> windowLayoutInfo(@UiContext android.content.Context context);
     method public kotlinx.coroutines.flow.Flow<androidx.window.layout.WindowLayoutInfo> windowLayoutInfo(android.app.Activity activity);
     field public static final androidx.window.layout.WindowInfoTracker.Companion Companion;
   }
diff --git a/window/window/api/restricted_current.txt b/window/window/api/restricted_current.txt
index 2a716a3..356f9c3 100644
--- a/window/window/api/restricted_current.txt
+++ b/window/window/api/restricted_current.txt
@@ -84,19 +84,29 @@
   }
 
   public final class SplitAttributes {
-    method public int getAnimationBackgroundColor();
+    method public androidx.window.embedding.SplitAttributes.BackgroundColor getAnimationBackgroundColor();
     method public androidx.window.embedding.SplitAttributes.LayoutDirection getLayoutDirection();
     method public androidx.window.embedding.SplitAttributes.SplitType getSplitType();
-    property public final int animationBackgroundColor;
+    property public final androidx.window.embedding.SplitAttributes.BackgroundColor animationBackgroundColor;
     property public final androidx.window.embedding.SplitAttributes.LayoutDirection layoutDirection;
     property public final androidx.window.embedding.SplitAttributes.SplitType splitType;
     field public static final androidx.window.embedding.SplitAttributes.Companion Companion;
   }
 
+  public static final class SplitAttributes.BackgroundColor {
+    method public static androidx.window.embedding.SplitAttributes.BackgroundColor color(@ColorInt @IntRange(from=android.graphics.Color.BLACK.toLong(), to=android.graphics.Color.WHITE.toLong()) int color);
+    field public static final androidx.window.embedding.SplitAttributes.BackgroundColor.Companion Companion;
+    field public static final androidx.window.embedding.SplitAttributes.BackgroundColor DEFAULT;
+  }
+
+  public static final class SplitAttributes.BackgroundColor.Companion {
+    method public androidx.window.embedding.SplitAttributes.BackgroundColor color(@ColorInt @IntRange(from=android.graphics.Color.BLACK.toLong(), to=android.graphics.Color.WHITE.toLong()) int color);
+  }
+
   public static final class SplitAttributes.Builder {
     ctor public SplitAttributes.Builder();
     method public androidx.window.embedding.SplitAttributes build();
-    method public androidx.window.embedding.SplitAttributes.Builder setAnimationBackgroundColor(@ColorInt int color);
+    method public androidx.window.embedding.SplitAttributes.Builder setAnimationBackgroundColor(androidx.window.embedding.SplitAttributes.BackgroundColor color);
     method public androidx.window.embedding.SplitAttributes.Builder setLayoutDirection(androidx.window.embedding.SplitAttributes.LayoutDirection layoutDirection);
     method public androidx.window.embedding.SplitAttributes.Builder setSplitType(androidx.window.embedding.SplitAttributes.SplitType type);
   }
@@ -326,7 +336,6 @@
 
   public interface WindowInfoTracker {
     method public default static androidx.window.layout.WindowInfoTracker getOrCreate(android.content.Context context);
-    method public default kotlinx.coroutines.flow.Flow<androidx.window.layout.WindowLayoutInfo> windowLayoutInfo(@UiContext android.content.Context context);
     method public kotlinx.coroutines.flow.Flow<androidx.window.layout.WindowLayoutInfo> windowLayoutInfo(android.app.Activity activity);
     field public static final androidx.window.layout.WindowInfoTracker.Companion Companion;
   }
diff --git a/window/window/samples/src/main/java/androidx.window.samples.embedding/SplitAttributesCalculatorSamples.kt b/window/window/samples/src/main/java/androidx.window.samples.embedding/SplitAttributesCalculatorSamples.kt
index 8eebd5c..2cba736 100644
--- a/window/window/samples/src/main/java/androidx.window.samples.embedding/SplitAttributesCalculatorSamples.kt
+++ b/window/window/samples/src/main/java/androidx.window.samples.embedding/SplitAttributesCalculatorSamples.kt
@@ -59,7 +59,7 @@
                         }
                     )
                     // Set the color to use when switching between vertical and horizontal
-                    .setAnimationBackgroundColor(Color.GRAY)
+                    .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GRAY))
                     .build()
             }
             return@setSplitAttributesCalculator if (
@@ -69,7 +69,7 @@
                 SplitAttributes.Builder()
                     .setSplitType(SplitAttributes.SplitType.splitEqually())
                     .setLayoutDirection(SplitAttributes.LayoutDirection.LOCALE)
-                    .setAnimationBackgroundColor(Color.GRAY)
+                    .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GRAY))
                     .build()
             } else {
                 // Expand containers if the device is in portrait or the width is less than 600 dp.
@@ -93,13 +93,13 @@
                 builder
                     .setLayoutDirection(SplitAttributes.LayoutDirection.LOCALE)
                     // Set the color to use when switching between vertical and horizontal
-                    .setAnimationBackgroundColor(Color.GRAY)
+                    .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GRAY))
                     .build()
             } else if (parentConfiguration.screenHeightDp >= 600) {
                 builder
                     .setLayoutDirection(SplitAttributes.LayoutDirection.TOP_TO_BOTTOM)
                     // Set the color to use when switching between vertical and horizontal
-                    .setAnimationBackgroundColor(Color.GRAY)
+                    .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GRAY))
                     .build()
             } else {
                 // Fallback to expand the secondary container
diff --git a/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
new file mode 100644
index 0000000..3b10142
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.area
+
+import android.annotation.TargetApi
+import android.app.Activity
+import android.content.pm.ActivityInfo
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.window.TestActivity
+import androidx.window.TestConsumer
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+import androidx.window.extensions.core.util.function.Consumer
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+import org.junit.Assume.assumeTrue
+import org.junit.Rule
+import org.junit.Test
+import kotlin.test.assertFailsWith
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+
+@OptIn(ExperimentalCoroutinesApi::class, ExperimentalWindowApi::class)
+class WindowAreaControllerImplTest {
+
+    @get:Rule
+    public val activityScenario: ActivityScenarioRule<TestActivity> =
+        ActivityScenarioRule(TestActivity::class.java)
+
+    private val testScope = TestScope(UnconfinedTestDispatcher())
+
+    @TargetApi(Build.VERSION_CODES.N)
+    @Test
+    public fun testRearDisplayStatus(): Unit = testScope.runTest {
+        assumeTrue(Build.VERSION.SDK_INT > Build.VERSION_CODES.N)
+        activityScenario.scenario.onActivity {
+            val extensionComponent = FakeWindowAreaComponent()
+            val repo = WindowAreaControllerImpl(extensionComponent)
+            val collector = TestConsumer<WindowAreaStatus>()
+            extensionComponent
+                .updateStatusListeners(WindowAreaComponent.STATUS_UNAVAILABLE)
+            testScope.launch(Job()) {
+                repo.rearDisplayStatus().collect(collector::accept)
+            }
+            collector.assertValue(WindowAreaStatus.UNAVAILABLE)
+            extensionComponent
+                .updateStatusListeners(WindowAreaComponent.STATUS_AVAILABLE)
+            collector.assertValues(
+                WindowAreaStatus.UNAVAILABLE,
+                WindowAreaStatus.AVAILABLE
+            )
+        }
+    }
+
+    @Test
+    public fun testRearDisplayStatusNullComponent(): Unit = testScope.runTest {
+        activityScenario.scenario.onActivity {
+            val repo = EmptyWindowAreaControllerImpl()
+            val collector = TestConsumer<WindowAreaStatus>()
+            testScope.launch(Job()) {
+                repo.rearDisplayStatus().collect(collector::accept)
+            }
+            collector.assertValue(WindowAreaStatus.UNSUPPORTED)
+        }
+    }
+
+    /**
+     * Tests the rear display mode flow works as expected. Tests the flow
+     * through WindowAreaControllerImpl with a fake extension. This fake extension
+     * changes the orientation of the activity to landscape when rear display mode is enabled
+     * and then returns it back to portrait when it's disabled.
+     */
+    @TargetApi(Build.VERSION_CODES.N)
+    @Test
+    public fun testRearDisplayMode(): Unit = testScope.runTest {
+        assumeTrue(Build.VERSION.SDK_INT > Build.VERSION_CODES.N)
+        val extensions = FakeWindowAreaComponent()
+        val repo = WindowAreaControllerImpl(extensions)
+        extensions.currentStatus = WindowAreaComponent.STATUS_AVAILABLE
+        val callback = TestWindowAreaSessionCallback()
+        activityScenario.scenario.onActivity { testActivity ->
+            testActivity.resetLayoutCounter()
+            testActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+            testActivity.waitForLayout()
+        }
+
+        activityScenario.scenario.onActivity { testActivity ->
+            assert(testActivity.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+            testActivity.resetLayoutCounter()
+            repo.rearDisplayMode(testActivity, Runnable::run, callback)
+        }
+
+        activityScenario.scenario.onActivity { testActivity ->
+            assert(testActivity.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
+            assert(callback.currentSession != null)
+            testActivity.resetLayoutCounter()
+            callback.endSession()
+        }
+        activityScenario.scenario.onActivity { testActivity ->
+            assert(testActivity.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+            assert(callback.currentSession == null)
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.N)
+    @Test
+    public fun testRearDisplayModeReturnsError(): Unit = testScope.runTest {
+        assumeTrue(Build.VERSION.SDK_INT > Build.VERSION_CODES.N)
+        val extensionComponent = FakeWindowAreaComponent()
+        extensionComponent.currentStatus = WindowAreaComponent.STATUS_UNAVAILABLE
+        val repo = WindowAreaControllerImpl(extensionComponent)
+        val callback = TestWindowAreaSessionCallback()
+        activityScenario.scenario.onActivity { testActivity ->
+            assertFailsWith(
+                exceptionClass = UnsupportedOperationException::class,
+                block = { repo.rearDisplayMode(testActivity, Runnable::run, callback) }
+            )
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.N)
+    @Test
+    public fun testRearDisplayModeNullComponent(): Unit = testScope.runTest {
+        assumeTrue(Build.VERSION.SDK_INT > Build.VERSION_CODES.N)
+        val repo = EmptyWindowAreaControllerImpl()
+        val callback = TestWindowAreaSessionCallback()
+        activityScenario.scenario.onActivity { testActivity ->
+            assertFailsWith(
+                exceptionClass = UnsupportedOperationException::class,
+                block = { repo.rearDisplayMode(testActivity, Runnable::run, callback) }
+            )
+        }
+    }
+
+    private class FakeWindowAreaComponent : WindowAreaComponent {
+        val statusListeners = mutableListOf<Consumer<Int>>()
+        var currentStatus = WindowAreaComponent.STATUS_UNSUPPORTED
+        var testActivity: Activity? = null
+        var sessionConsumer: Consumer<Int>? = null
+
+        @RequiresApi(Build.VERSION_CODES.N)
+        override fun addRearDisplayStatusListener(consumer: Consumer<Int>) {
+            statusListeners.add(consumer)
+            consumer.accept(currentStatus)
+        }
+
+        override fun removeRearDisplayStatusListener(consumer: Consumer<Int>) {
+            statusListeners.remove(consumer)
+        }
+
+        // Fake WindowAreaComponent will change the orientation of the activity to signal
+        // entering rear display mode, as well as ending the session
+        @RequiresApi(Build.VERSION_CODES.N)
+        override fun startRearDisplaySession(
+            activity: Activity,
+            rearDisplaySessionConsumer: Consumer<Int>
+        ) {
+            if (currentStatus != WindowAreaComponent.STATUS_AVAILABLE) {
+                throw UnsupportedOperationException("Rear Display mode cannot be enabled currently")
+            }
+            testActivity = activity
+            sessionConsumer = rearDisplaySessionConsumer
+            testActivity!!.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+            rearDisplaySessionConsumer.accept(WindowAreaComponent.SESSION_STATE_ACTIVE)
+        }
+
+        @RequiresApi(Build.VERSION_CODES.N)
+        override fun endRearDisplaySession() {
+            testActivity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+            sessionConsumer?.accept(WindowAreaComponent.SESSION_STATE_INACTIVE)
+        }
+
+        @RequiresApi(Build.VERSION_CODES.N)
+        fun updateStatusListeners(newStatus: Int) {
+            currentStatus = newStatus
+            for (consumer in statusListeners) {
+                consumer.accept(currentStatus)
+            }
+        }
+    }
+
+    private class TestWindowAreaSessionCallback : WindowAreaSessionCallback {
+
+        var currentSession: WindowAreaSession? = null
+        var error: Throwable? = null
+
+        override fun onSessionStarted(session: WindowAreaSession) {
+            currentSession = session
+        }
+
+        override fun onSessionEnded() {
+            currentSession = null
+        }
+
+        fun endSession() = currentSession?.close()
+    }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
index 1d9d74c..44e9c5b 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
@@ -52,16 +52,20 @@
     }
 
     @Test
-    fun testMatchActivity_MatchIntentWithoutAction() {
+    fun testMatch_WithoutAction() {
         val filter = ActivityFilter(COMPONENT_1, null /* intentAction */)
 
         assertWithMessage("#matchActivity must be true because intent.component matches")
             .that(filter.matchesActivity(activity)).isTrue()
+        assertWithMessage("#matchIntent must be true because intent.component matches")
+            .that(filter.matchesIntent(intent)).isTrue()
 
         intent.component = COMPONENT_2
 
         assertWithMessage("#matchActivity must be false because component mismatches")
             .that(filter.matchesActivity(activity)).isFalse()
+        assertWithMessage("#matchesIntent must be false because component mismatches")
+            .that(filter.matchesIntent(intent)).isFalse()
 
         doReturn(COMPONENT_1).whenever(activity).componentName
 
@@ -70,29 +74,37 @@
     }
 
     @Test
-    fun testMatchActivity_MatchIntentWithAction() {
+    fun testMatch_WithAction() {
         val filter = ActivityFilter(COMPONENT_1, ACTION)
 
         assertWithMessage("#matchActivity must be false because intent has no action")
             .that(filter.matchesActivity(activity)).isFalse()
+        assertWithMessage("#matchesIntent must be false because intent has no action")
+            .that(filter.matchesIntent(intent)).isFalse()
 
         intent.action = ACTION
 
         assertWithMessage("#matchActivity must be true because intent matches")
             .that(filter.matchesActivity(activity)).isTrue()
+        assertWithMessage("#matchesIntent must be true because intent matches")
+            .that(filter.matchesIntent(intent)).isTrue()
     }
 
     @Test
-    fun testMatchActivity_MatchWildcardWithAction() {
+    fun testMatch_WildcardWithAction() {
         val filter = ActivityFilter(WILDCARD, ACTION)
 
         assertWithMessage("#matchActivity must be false because intent has no action")
             .that(filter.matchesActivity(activity)).isFalse()
+        assertWithMessage("#matchesIntent must be false because intent has no action")
+            .that(filter.matchesIntent(intent)).isFalse()
 
         intent.action = ACTION
 
         assertWithMessage("#matchActivity must be true because intent.action matches")
             .that(filter.matchesActivity(activity)).isTrue()
+        assertWithMessage("#matchesIntent must be true because intent.action matches")
+            .that(filter.matchesIntent(intent)).isTrue()
 
         intent.component = null
 
@@ -101,10 +113,15 @@
                 "of null component"
         )
             .that(filter.matchesActivity(activity)).isTrue()
+        assertWithMessage(
+            "#matchesIntent must be true because intent.action matches regardless " +
+                "of null component"
+        )
+            .that(filter.matchesIntent(intent)).isTrue()
     }
 
     @Test
-    fun testMatchActivity_MatchIntentWithPackage() {
+    fun testMatch_IntentWithPackage() {
         val filter = ActivityFilter(WILDCARD, null /* intentAction */)
 
         intent.component = null
@@ -112,6 +129,20 @@
 
         assertWithMessage("#matchActivity must be true because intent.package matches")
             .that(filter.matchesActivity(activity)).isTrue()
+        assertWithMessage("#matchesIntent must be true because intent.package matches")
+            .that(filter.matchesIntent(intent)).isTrue()
+    }
+
+    @Test
+    fun testMatch_EmptyIntentWithWildcard() {
+        val filter = ActivityFilter(WILDCARD, null /* intentAction */)
+
+        intent.component = null
+
+        assertWithMessage("#matchActivity must be true because rule is wildcard to match all")
+            .that(filter.matchesActivity(activity)).isTrue()
+        assertWithMessage("#matchesIntent must be true because rule is wildcard to match all")
+            .that(filter.matchesIntent(intent)).isTrue()
     }
 
     companion object {
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
index f098cd6..0ce0920 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
@@ -59,7 +59,7 @@
             SplitAttributes.Builder()
                 .setSplitType(SplitType.splitEqually())
                 .setLayoutDirection(SplitAttributes.LayoutDirection.LOCALE)
-                .setAnimationBackgroundColor(0)
+                .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
                 .build()
         )
         assertEquals(listOf(expectedSplitInfo), adapter.translate(listOf(oemSplitInfo)))
@@ -134,7 +134,7 @@
             SplitAttributes.Builder()
                 .setSplitType(SplitType.splitByHinge(SplitType.ratio(0.3f)))
                 .setLayoutDirection(SplitAttributes.LayoutDirection.TOP_TO_BOTTOM)
-                .setAnimationBackgroundColor(Color.YELLOW)
+                .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.YELLOW))
                 .build()
         )
         assertEquals(listOf(expectedSplitInfo), adapter.translate(listOf(oemSplitInfo)))
@@ -143,7 +143,7 @@
     private fun createTestOEMSplitInfo(
         testPrimaryActivityStack: OEMActivityStack,
         testSecondaryActivityStack: OEMActivityStack,
-        testSplitAttributes: OEMSplitAttributes
+        testSplitAttributes: OEMSplitAttributes,
     ): OEMSplitInfo {
         return mock<OEMSplitInfo>().apply {
             whenever(primaryActivityStack).thenReturn(testPrimaryActivityStack)
@@ -156,7 +156,7 @@
 
     private fun createTestOEMActivityStack(
         testActivities: List<Activity>,
-        testIsEmpty: Boolean
+        testIsEmpty: Boolean,
     ): OEMActivityStack {
         return mock<OEMActivityStack>().apply {
             whenever(activities).thenReturn(testActivities)
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingRuleConstructionTests.kt b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingRuleConstructionTests.kt
index 62dcd3b..582d047 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingRuleConstructionTests.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingRuleConstructionTests.kt
@@ -81,7 +81,7 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.5f))
             .setLayoutDirection(LOCALE)
-            .setAnimationBackgroundColor(0)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
             .build()
         assertNull(rule.tag)
         assertEquals(SPLIT_MIN_DIMENSION_DP_DEFAULT, rule.minWidthDp)
@@ -133,7 +133,7 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.3f))
             .setLayoutDirection(TOP_TO_BOTTOM)
-            .setAnimationBackgroundColor(Color.BLUE)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.BLUE))
             .build()
         assertEquals(TEST_TAG, rule.tag)
         assertEquals(NEVER, rule.finishPrimaryWithSecondary)
@@ -154,7 +154,7 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.5f))
             .setLayoutDirection(LOCALE)
-            .setAnimationBackgroundColor(0)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
             .build()
         assertNull(rule.tag)
         assertEquals(SPLIT_MIN_DIMENSION_DP_DEFAULT, rule.minWidthDp)
@@ -180,7 +180,7 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.3f))
             .setLayoutDirection(LEFT_TO_RIGHT)
-            .setAnimationBackgroundColor(Color.GREEN)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GREEN))
             .build()
         filters.add(
             SplitPairFilter(
@@ -382,7 +382,7 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.5f))
             .setLayoutDirection(LOCALE)
-            .setAnimationBackgroundColor(0)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
             .build()
         assertNull(rule.tag)
         assertEquals(SPLIT_MIN_DIMENSION_DP_DEFAULT, rule.minWidthDp)
@@ -437,7 +437,8 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.3f))
             .setLayoutDirection(BOTTOM_TO_TOP)
-            .setAnimationBackgroundColor(application.resources.getColor(R.color.testColor, null))
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(
+                application.resources.getColor(R.color.testColor, null)))
             .build()
         assertEquals(TEST_TAG, rule.tag)
         assertEquals(ALWAYS, rule.finishPrimaryWithPlaceholder)
@@ -465,7 +466,7 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.5f))
             .setLayoutDirection(LOCALE)
-            .setAnimationBackgroundColor(0)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
             .build()
         assertEquals(expectedSplitLayout, rule.defaultSplitAttributes)
         assertTrue(rule.checkParentBounds(density, minValidWindowBounds()))
@@ -489,7 +490,7 @@
         val expectedSplitLayout = SplitAttributes.Builder()
             .setSplitType(SplitAttributes.SplitType.ratio(0.3f))
             .setLayoutDirection(LEFT_TO_RIGHT)
-            .setAnimationBackgroundColor(Color.GREEN)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GREEN))
             .build()
         val rule = SplitPlaceholderRule.Builder(filters, intent)
             .setMinWidthDp(123)
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/SafeActivityEmbeddingComponentProviderTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/SafeActivityEmbeddingComponentProviderTest.kt
new file mode 100644
index 0000000..3b93a9a
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/embedding/SafeActivityEmbeddingComponentProviderTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2023 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 androidx.window.embedding
+
+import android.util.Log
+import androidx.window.core.ConsumerAdapter
+import androidx.window.extensions.WindowExtensions
+import androidx.window.extensions.WindowExtensionsProvider
+import org.junit.Assert.assertNull
+import org.junit.Test
+
+/**
+ * An integration test to verify that if [WindowExtensionsProvider] is present then
+ * [SafeActivityEmbeddingComponentProvider.activityEmbeddingComponent] will return a value.
+ * This can fail if the implementation of window:extensions:extensions
+ * does not have the expected API.
+ */
+class SafeActivityEmbeddingComponentProviderTest {
+
+    /**
+     * Test that if [WindowExtensionsProvider] is available then
+     * use [SafeActivityEmbeddingComponentProvider.activityEmbeddingComponent] to validate.
+     * If [WindowExtensions.getActivityEmbeddingComponent] matches contract,
+     * return a non-null value.
+     * If it doesn't match, it will return a null.
+     *
+     *  TODO(b/267708462) : add a more reliable test
+     */
+    @Test
+    fun activityEmbeddingComponentIsAvailable_ifProviderIsAvailable() {
+        val loader = SafeActivityEmbeddingComponentProviderTest::class.java.classLoader!!
+        val consumerAdapter = ConsumerAdapter(loader)
+        val windowExtensions: WindowExtensions = try {
+            WindowExtensionsProvider.getWindowExtensions()
+        } catch (e: UnsupportedOperationException) {
+            Log.d(TAG, "Device doesn't have WindowExtensions available")
+            return
+        }
+        val safeComponent = SafeActivityEmbeddingComponentProvider(
+            loader,
+            consumerAdapter,
+            windowExtensions
+        )
+            .activityEmbeddingComponent
+        try {
+            val actualComponent = windowExtensions.activityEmbeddingComponent
+            if (actualComponent == null) {
+                assertNull(safeComponent)
+            } else {
+                // TODO(b/267573854) : verify upon each api level
+                // TODO(b/267708462) : more reliable test for testing actual method matching
+                if (safeComponent == null) {
+                    Log.d(TAG, "ActivityEmbeddingComponent on device doesn't match our constraints")
+                }
+            }
+        } catch (e: UnsupportedOperationException) {
+            // Invalid implementation of extensions
+            assertNull(safeComponent)
+        }
+    }
+
+    companion object {
+        private const val TAG = "SafeActivityEmbeddingComponentProviderTest"
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/test/java/androidx/window/embedding/SplitAttributesTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/SplitAttributesTest.kt
similarity index 92%
rename from window/window/src/test/java/androidx/window/embedding/SplitAttributesTest.kt
rename to window/window/src/androidTest/java/androidx/window/embedding/SplitAttributesTest.kt
index 96571cc..69c507d 100644
--- a/window/window/src/test/java/androidx/window/embedding/SplitAttributesTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/SplitAttributesTest.kt
@@ -36,27 +36,27 @@
         val attrs1 = SplitAttributes.Builder()
             .setSplitType(SplitType.splitEqually())
             .setLayoutDirection(LOCALE)
-            .setAnimationBackgroundColor(0)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
             .build()
         val attrs2 = SplitAttributes.Builder()
             .setSplitType(SplitType.splitByHinge())
             .setLayoutDirection(LOCALE)
-            .setAnimationBackgroundColor(0)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
             .build()
         val attrs3 = SplitAttributes.Builder()
             .setSplitType(SplitType.splitByHinge())
             .setLayoutDirection(TOP_TO_BOTTOM)
-            .setAnimationBackgroundColor(0)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.DEFAULT)
             .build()
         val attrs4 = SplitAttributes.Builder()
             .setSplitType(SplitType.splitByHinge())
             .setLayoutDirection(TOP_TO_BOTTOM)
-            .setAnimationBackgroundColor(Color.GREEN)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GREEN))
             .build()
         val attrs5 = SplitAttributes.Builder()
             .setSplitType(SplitType.splitByHinge())
             .setLayoutDirection(TOP_TO_BOTTOM)
-            .setAnimationBackgroundColor(Color.GREEN)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.color(Color.GREEN))
             .build()
 
         assertNotEquals(attrs1, attrs2)
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/SplitPairFilterTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/SplitPairFilterTest.kt
index 408102b..4c75bd7 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/SplitPairFilterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/SplitPairFilterTest.kt
@@ -22,43 +22,122 @@
 import com.google.common.truth.Truth.assertWithMessage
 import com.nhaarman.mockitokotlin2.doReturn
 import com.nhaarman.mockitokotlin2.mock
+import com.nhaarman.mockitokotlin2.whenever
+import org.junit.Before
 import org.junit.Test
 
 class SplitPairFilterTest {
-    private val component1 = ComponentName("a.b.c", "a.b.c.TestActivity")
-    private val component2 = ComponentName("d.e.f", "d.e.f.TestActivity")
-    private val intentClassWildcard = ComponentName("d.e.f", "*")
-    private val intent = Intent()
-    private val activity = mock<Activity> {
-        on { intent } doReturn intent
-        on { componentName } doReturn component1
+    private val intent1 = Intent()
+    private val intent2 = Intent()
+    private val activity1 = mock<Activity> {
+        on { intent } doReturn intent1
+        on { componentName } doReturn COMPONENT_1
     }
-    private val filter =
-        SplitPairFilter(component1, intentClassWildcard, null /* secondaryActivityIntentAction */)
+    private val activity2 = mock<Activity> {
+        on { intent } doReturn intent2
+        on { componentName } doReturn COMPONENT_2
+    }
 
-    @Test
-    fun testMatchActivityIntentPair_MatchIntentComponent() {
-        assertWithMessage("#matchesActivityIntentPair must be false because intent is empty")
-            .that(filter.matchesActivityIntentPair(activity, intent)).isFalse()
-
-        intent.component = component2
-
-        assertWithMessage("#matchesActivityIntentPair must be true because intent.component" +
-            " matches")
-            .that(filter.matchesActivityIntentPair(activity, intent)).isTrue()
+    @Before
+    fun setUp() {
+        intent1.component = COMPONENT_1
+        intent2.component = COMPONENT_2
     }
 
     @Test
-    fun testMatchActivityIntentPair_MatchIntentPackage() {
-        intent.`package` = intentClassWildcard.packageName
+    fun testMatch_WithoutAction() {
+        val filter = SplitPairFilter(
+            COMPONENT_1,
+            COMPONENT_2,
+            null /* secondaryActivityIntentAction */
+        )
 
+        assertWithMessage("#matchesActivityPair must be true because intents match")
+            .that(filter.matchesActivityPair(activity1, activity2)).isTrue()
+        assertWithMessage("#matchesActivityIntentPair must be true because intents match")
+            .that(filter.matchesActivityIntentPair(activity1, intent2)).isTrue()
+
+        assertWithMessage("#matchesActivityPair must be false because secondary doesn't match")
+            .that(filter.matchesActivityPair(activity1, activity1)).isFalse()
+        assertWithMessage(
+            "#matchesActivityIntentPair must be false because secondary doesn't match"
+        )
+            .that(filter.matchesActivityIntentPair(activity1, intent1)).isFalse()
+
+        assertWithMessage("#matchesActivityPair must be false because primary doesn't match")
+            .that(filter.matchesActivityPair(activity2, activity2)).isFalse()
+        assertWithMessage(
+            "#matchesActivityIntentPair must be false because primary doesn't match"
+        )
+            .that(filter.matchesActivityIntentPair(activity2, intent2)).isFalse()
+    }
+
+    @Test
+    fun testMatch_WithAction() {
+        val filter = SplitPairFilter(COMPONENT_1, WILDCARD, ACTION)
+
+        assertWithMessage("#matchesActivityPair must be false because intent has no action")
+            .that(filter.matchesActivityPair(activity1, activity2)).isFalse()
+        assertWithMessage("#matchesActivityIntentPair must be false because intent has no action")
+            .that(filter.matchesActivityIntentPair(activity1, intent2)).isFalse()
+
+        intent2.action = ACTION
+
+        assertWithMessage("#matchesActivityPair must be true because intent.action matches")
+            .that(filter.matchesActivityPair(activity1, activity2)).isTrue()
+        assertWithMessage("#matchesActivityIntentPair must be true because intent.action matches")
+            .that(filter.matchesActivityIntentPair(activity1, intent2)).isTrue()
+    }
+
+    @Test
+    fun testMatch_WithIntentPackage() {
+        val filter = SplitPairFilter(
+            COMPONENT_1,
+            CLASS_WILDCARD,
+            null /* secondaryActivityIntentAction */
+        )
+        intent2.component = null
+        intent2.`package` = CLASS_WILDCARD.packageName
+        doReturn(COMPONENT_1).whenever(activity2).componentName
+
+        assertWithMessage("#matchesActivityPair must be true because intent.package matches")
+            .that(filter.matchesActivityPair(activity1, activity2)).isTrue()
         assertWithMessage("#matchesActivityIntentPair must be true because intent.package matches")
-            .that(filter.matchesActivityIntentPair(activity, intent)).isTrue()
+            .that(filter.matchesActivityIntentPair(activity1, intent2)).isTrue()
 
-        intent.component = component1
+        intent2.component = COMPONENT_1
 
-        assertWithMessage("#matchesActivityIntentPair must be false because intent.component" +
-            " doesn't match")
-            .that(filter.matchesActivityIntentPair(activity, intent)).isFalse()
+        assertWithMessage(
+            "#matchesActivityPair must be false because intent.component doesn't match"
+        )
+            .that(filter.matchesActivityPair(activity1, activity1)).isFalse()
+        assertWithMessage(
+            "#matchesActivityIntentPair must be false because intent.component doesn't match"
+        )
+            .that(filter.matchesActivityIntentPair(activity1, intent1)).isFalse()
+    }
+
+    @Test
+    fun testMatch_EmptyIntentWithWildcard() {
+        val filter = SplitPairFilter(
+            WILDCARD,
+            WILDCARD,
+            null /* secondaryActivityIntentAction */
+        )
+        intent1.component = null
+        intent2.component = null
+
+        assertWithMessage("#matchesActivityPair must be true because rule is wildcard")
+            .that(filter.matchesActivityPair(activity1, activity2)).isTrue()
+        assertWithMessage("#matchesActivityIntentPair must be true because rule is wildcard")
+            .that(filter.matchesActivityIntentPair(activity1, intent2)).isTrue()
+    }
+
+    companion object {
+        private const val ACTION = "action.test"
+        private val COMPONENT_1 = ComponentName("a.b.c", "a.b.c.TestActivity")
+        private val COMPONENT_2 = ComponentName("d.e.f", "d.e.f.TestActivity")
+        private val WILDCARD = ComponentName("*", "*")
+        private val CLASS_WILDCARD = ComponentName("d.e.f", "*")
     }
 }
\ No newline at end of file
diff --git a/window/window/src/androidTest/java/androidx/window/layout/SafeWindowLayoutComponentProviderTest.kt b/window/window/src/androidTest/java/androidx/window/layout/SafeWindowLayoutComponentProviderTest.kt
index 246e9a3..bc78a38 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/SafeWindowLayoutComponentProviderTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/SafeWindowLayoutComponentProviderTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.window.layout
 
+import android.util.Log
 import androidx.window.core.ConsumerAdapter
 import androidx.window.extensions.WindowExtensionsProvider
-import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertNull
 import org.junit.Test
 
@@ -46,11 +46,17 @@
             if (actualComponent == null) {
                 assertNull(safeComponent)
             } else {
-                assertNotNull(safeComponent)
+                // TODO(b/267831038): verify upon each api level
+                // TODO(b/267708462): more reliable test for testing actual method matching
+                Log.d(TAG, "WindowLayoutComponent on device doesn't match our constraints")
             }
         } catch (e: UnsupportedOperationException) {
             // Invalid implementation of extensions
             assertNull(safeComponent)
         }
     }
+
+    companion object {
+        private const val TAG = "SafeWindowLayoutComponentProviderTest"
+    }
 }
\ No newline at end of file
diff --git a/window/window/src/androidTest/java/androidx/window/layout/WindowInfoTrackerImplTest.kt b/window/window/src/androidTest/java/androidx/window/layout/WindowInfoTrackerImplTest.kt
index 1d86ece..9ff7856 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/WindowInfoTrackerImplTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/WindowInfoTrackerImplTest.kt
@@ -24,6 +24,7 @@
 import androidx.window.TestConsumer
 import androidx.window.WindowTestUtils
 import androidx.window.WindowTestUtils.Companion.assumeAtLeastVendorApiLevel
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.adapter.WindowBackend
 import java.util.concurrent.Executor
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -35,7 +36,7 @@
 import org.junit.Rule
 import org.junit.Test
 
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalCoroutinesApi::class, ExperimentalWindowApi::class)
 public class WindowInfoTrackerImplTest {
 
     @get:Rule
diff --git a/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt b/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt
new file mode 100644
index 0000000..d56eccb
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import android.app.Activity
+import androidx.window.core.ExperimentalWindowApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+import java.util.concurrent.Executor
+
+/**
+ * Empty Implementation for devices that do not
+ * support the [WindowAreaController] functionality
+ */
+@ExperimentalWindowApi
+internal class EmptyWindowAreaControllerImpl : WindowAreaController {
+    override fun rearDisplayStatus(): Flow<WindowAreaStatus> {
+        return flowOf(WindowAreaStatus.UNSUPPORTED)
+    }
+
+    override fun rearDisplayMode(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    ) {
+        // TODO(b/269144982): Investigate not throwing an exception
+        throw UnsupportedOperationException("Rear Display mode cannot be enabled currently")
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/area/RearDisplaySessionImpl.kt b/window/window/src/main/java/androidx/window/area/RearDisplaySessionImpl.kt
new file mode 100644
index 0000000..ae7d3ca
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/RearDisplaySessionImpl.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+
+@ExperimentalWindowApi
+internal class RearDisplaySessionImpl(
+    private val windowAreaComponent: WindowAreaComponent
+) : WindowAreaSession {
+
+    override fun close() {
+        windowAreaComponent.endRearDisplaySession()
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaAdapter.kt b/window/window/src/main/java/androidx/window/area/WindowAreaAdapter.kt
new file mode 100644
index 0000000..65154449
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaAdapter.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+
+/**
+ * Adapter object to assist in translating values received from [WindowAreaComponent]
+ * to developer friendly values in [WindowAreaController]
+ */
+@ExperimentalWindowApi
+internal object WindowAreaAdapter {
+
+    internal fun translate(status: @WindowAreaComponent.WindowAreaStatus Int): WindowAreaStatus {
+        return when (status) {
+            WindowAreaComponent.STATUS_AVAILABLE -> WindowAreaStatus.AVAILABLE
+            WindowAreaComponent.STATUS_UNAVAILABLE -> WindowAreaStatus.UNAVAILABLE
+            else -> WindowAreaStatus.UNSUPPORTED
+        }
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaController.kt b/window/window/src/main/java/androidx/window/area/WindowAreaController.kt
new file mode 100644
index 0000000..385b290
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaController.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import android.app.Activity
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RestrictTo
+import androidx.window.core.BuildConfig
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.core.VerificationMode
+import androidx.window.extensions.WindowExtensionsProvider
+import androidx.window.extensions.area.WindowAreaComponent
+import java.util.concurrent.Executor
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * An interface to provide information about available window areas on the device and an option
+ * to use the rear display area of a foldable device, exclusively or concurrently with the internal
+ * display.
+ */
+@ExperimentalWindowApi
+interface WindowAreaController {
+
+    /**
+     * Provides information about the current state of the window area of the rear display on the
+     * device, if or when it is available. Rear Display mode can be invoked if the current status is
+     * [WindowAreaStatus.AVAILABLE].
+     */
+    fun rearDisplayStatus(): Flow<WindowAreaStatus>
+
+    /**
+     * Starts Rear Display Mode and moves the provided activity to the rear side of the device in
+     * order to face the same direction as the primary device camera(s). When a rear display
+     * mode is started, the system will turn on the rear display of the device to show the content
+     * there, and can disable the internal display. The provided [Activity] is likely to get a
+     * configuration change or being relaunched due to the difference in the internal and rear
+     * display sizes on the device.
+     * <p>Only the top visible application can request and use this mode. The system can dismiss the
+     * mode if the user changes the device state.
+     * <p>This method can only be called if the feature is supported on the device and is reported
+     * as available in the current state through [rearDisplayStatus], otherwise it will
+     * throw an [Exception].
+     */
+    fun rearDisplayMode(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    )
+
+    public companion object {
+        private val TAG = WindowAreaController::class.simpleName
+
+        private var decorator: WindowAreaControllerDecorator = EmptyDecorator
+
+        /**
+         * Provides an instance of [WindowAreaController].
+         */
+        @JvmName("getOrCreate")
+        @JvmStatic
+        fun getOrCreate(): WindowAreaController {
+            var windowAreaComponentExtensions: WindowAreaComponent?
+            try {
+                // TODO(b/267972002): Introduce reflection guard for WindowAreaComponent
+                windowAreaComponentExtensions = WindowExtensionsProvider
+                    .getWindowExtensions()
+                    .windowAreaComponent
+            } catch (t: Throwable) {
+                if (BuildConfig.verificationMode == VerificationMode.STRICT) {
+                    Log.d(TAG, "Failed to load WindowExtensions")
+                }
+                windowAreaComponentExtensions = null
+            }
+            val controller =
+                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N ||
+                    windowAreaComponentExtensions == null) {
+                    EmptyWindowAreaControllerImpl()
+                } else {
+                    WindowAreaControllerImpl(windowAreaComponentExtensions)
+                }
+            return decorator.decorate(controller)
+        }
+
+        @JvmStatic
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        fun overrideDecorator(overridingDecorator: WindowAreaControllerDecorator) {
+            decorator = overridingDecorator
+        }
+
+        @JvmStatic
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        fun reset() {
+            decorator = EmptyDecorator
+        }
+    }
+}
+
+/**
+ * Decorator that allows us to provide different functionality
+ * in our window-testing artifact.
+ */
+@ExperimentalWindowApi
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+interface WindowAreaControllerDecorator {
+    /**
+     * Returns an instance of [WindowAreaController] associated to the [Activity]
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public fun decorate(controller: WindowAreaController): WindowAreaController
+}
+
+@ExperimentalWindowApi
+private object EmptyDecorator : WindowAreaControllerDecorator {
+    override fun decorate(controller: WindowAreaController): WindowAreaController {
+        return controller
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaControllerImpl.kt b/window/window/src/main/java/androidx/window/area/WindowAreaControllerImpl.kt
new file mode 100644
index 0000000..af9a398
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaControllerImpl.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import android.app.Activity
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.window.core.BuildConfig
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.core.VerificationMode
+import androidx.window.extensions.area.WindowAreaComponent
+import androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_ACTIVE
+import androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_INACTIVE
+import androidx.window.extensions.core.util.function.Consumer
+import java.util.concurrent.Executor
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+
+/**
+ * Implementation of WindowAreaController for devices
+ * that do implement the WindowAreaComponent on device.
+ *
+ * Requires [Build.VERSION_CODES.N] due to the use of [Consumer].
+ * Will not be created though on API levels lower than
+ * [Build.VERSION_CODES.S] as that's the min level of support for
+ * this functionality.
+ */
+@ExperimentalWindowApi
+@RequiresApi(Build.VERSION_CODES.N)
+internal class WindowAreaControllerImpl(
+    private val windowAreaComponent: WindowAreaComponent
+) : WindowAreaController {
+
+    private var currentStatus: WindowAreaStatus? = null
+
+    override fun rearDisplayStatus(): Flow<WindowAreaStatus> {
+        return callbackFlow {
+            val listener = Consumer<@WindowAreaComponent.WindowAreaStatus Int> { status ->
+                currentStatus = WindowAreaAdapter.translate(status)
+                channel.trySend(currentStatus ?: WindowAreaStatus.UNSUPPORTED)
+            }
+            windowAreaComponent.addRearDisplayStatusListener(listener)
+            awaitClose {
+                windowAreaComponent.removeRearDisplayStatusListener(listener)
+            }
+        }.distinctUntilChanged()
+    }
+
+    override fun rearDisplayMode(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    ) {
+        // If we already have a status value that is not [WindowAreaStatus.AVAILABLE]
+        // we should throw an exception quick to indicate they tried to enable
+        // RearDisplay mode when it was not available.
+        if (currentStatus != null && currentStatus != WindowAreaStatus.AVAILABLE) {
+            throw UnsupportedOperationException("Rear Display mode cannot be enabled currently")
+        }
+        val rearDisplaySessionConsumer =
+            RearDisplaySessionConsumer(executor, windowAreaSessionCallback, windowAreaComponent)
+        windowAreaComponent.startRearDisplaySession(activity, rearDisplaySessionConsumer)
+    }
+
+    internal class RearDisplaySessionConsumer(
+        private val executor: Executor,
+        private val appCallback: WindowAreaSessionCallback,
+        private val extensionsComponent: WindowAreaComponent
+    ) : Consumer<@WindowAreaComponent.WindowAreaSessionState Int> {
+
+        private var session: WindowAreaSession? = null
+
+        override fun accept(t: @WindowAreaComponent.WindowAreaSessionState Int) {
+            when (t) {
+                SESSION_STATE_ACTIVE -> onSessionStarted()
+                SESSION_STATE_INACTIVE -> onSessionFinished()
+                else -> {
+                    if (BuildConfig.verificationMode == VerificationMode.STRICT) {
+                        Log.d(TAG, "Received an unknown session status value: $t")
+                    }
+                    onSessionFinished()
+                }
+            }
+        }
+
+        private fun onSessionStarted() {
+            session = RearDisplaySessionImpl(extensionsComponent)
+            session?.let { executor.execute { appCallback.onSessionStarted(it) } }
+        }
+
+        private fun onSessionFinished() {
+            session = null
+            executor.execute { appCallback.onSessionEnded() }
+        }
+    }
+
+    internal companion object {
+        private val TAG = WindowAreaControllerImpl::class.simpleName
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaSession.kt b/window/window/src/main/java/androidx/window/area/WindowAreaSession.kt
new file mode 100644
index 0000000..e84cb4a
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaSession.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+
+/**
+ * Session interface to represent a long-standing
+ * WindowArea mode or feature that provides a handle
+ * to close the session.
+ */
+@ExperimentalWindowApi
+public interface WindowAreaSession {
+    fun close()
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaSessionCallback.kt b/window/window/src/main/java/androidx/window/area/WindowAreaSessionCallback.kt
new file mode 100644
index 0000000..15ea453
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaSessionCallback.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+
+/**
+ * Callback to update the client on the WindowArea Session being
+ * started and ended.
+ * TODO(b/207720511) Move to window-java module when Kotlin API Finalized
+ */
+@ExperimentalWindowApi
+interface WindowAreaSessionCallback {
+
+    fun onSessionStarted(session: WindowAreaSession)
+
+    fun onSessionEnded()
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaStatus.kt b/window/window/src/main/java/androidx/window/area/WindowAreaStatus.kt
new file mode 100644
index 0000000..5f8f668
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaStatus.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 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 androidx.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+
+/**
+ * Represents a window area status.
+ */
+@ExperimentalWindowApi
+class WindowAreaStatus private constructor(private val mDescription: String) {
+
+    override fun toString(): String {
+        return mDescription
+    }
+
+    companion object {
+        /**
+         * Status representing that the WindowArea feature is not a supported
+         * feature on the device.
+         */
+        @JvmField
+        val UNSUPPORTED = WindowAreaStatus("UNSUPPORTED")
+
+        /**
+         * Status representing that the WindowArea feature is currently not available
+         * to be enabled. This could be due to another process has enabled it, or that the
+         * current device configuration doesn't allow it.
+         */
+        @JvmField
+        val UNAVAILABLE = WindowAreaStatus("UNAVAILABLE")
+
+        /**
+         * Status representing that the WindowArea feature is available to be enabled.
+         */
+        @JvmField
+        val AVAILABLE = WindowAreaStatus("AVAILABLE")
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/embedding/ActivityFilter.kt b/window/window/src/main/java/androidx/window/embedding/ActivityFilter.kt
index 836a897..b76a3c2 100644
--- a/window/window/src/main/java/androidx/window/embedding/ActivityFilter.kt
+++ b/window/window/src/main/java/androidx/window/embedding/ActivityFilter.kt
@@ -20,10 +20,11 @@
 import android.content.Intent
 import android.util.Log
 import androidx.window.core.ActivityComponentInfo
-import androidx.window.embedding.MatcherUtils.isActivityOrIntentMatching
+import androidx.window.embedding.MatcherUtils.isActivityMatching
 import androidx.window.embedding.MatcherUtils.isIntentMatching
 import androidx.window.embedding.MatcherUtils.sDebugMatchers
 import androidx.window.embedding.MatcherUtils.sMatchersTag
+import androidx.window.embedding.MatcherUtils.validateComponentName
 
 /**
  * Filter for [ActivityRule] and [SplitPlaceholderRule] that checks for component name match when
@@ -69,26 +70,7 @@
     )
 
     init {
-        val packageName = activityComponentInfo.packageName
-        val className = activityComponentInfo.className
-        require(
-            packageName.isNotEmpty()
-        ) { "Package name must not be empty" }
-        require(
-            className.isNotEmpty()
-        ) { "Activity class name must not be empty." }
-        require(
-            !(
-                packageName.contains("*") &&
-                    packageName.indexOf("*") != packageName.length - 1
-                )
-        ) { "Wildcard in package name is only allowed at the end." }
-        require(
-            !(
-                className.contains("*") &&
-                    className.indexOf("*") != className.length - 1
-                )
-        ) { "Wildcard in class name is only allowed at the end." }
+        validateComponentName(activityComponentInfo.packageName, activityComponentInfo.className)
     }
 
     /**
@@ -122,9 +104,8 @@
      * @param activity the [Activity] to test against.
      */
     fun matchesActivity(activity: Activity): Boolean {
-        val match =
-            isActivityOrIntentMatching(activity, activityComponentInfo) &&
-                (intentAction == null || intentAction == activity.intent?.action)
+        val match = isActivityMatching(activity, activityComponentInfo) &&
+            (intentAction == null || intentAction == activity.intent?.action)
         if (sDebugMatchers) {
             val matchString = if (match) "MATCH" else "NO MATCH"
             Log.w(
diff --git a/window/window/src/main/java/androidx/window/embedding/ActivityRule.kt b/window/window/src/main/java/androidx/window/embedding/ActivityRule.kt
index c231818..310a9fa 100644
--- a/window/window/src/main/java/androidx/window/embedding/ActivityRule.kt
+++ b/window/window/src/main/java/androidx/window/embedding/ActivityRule.kt
@@ -47,18 +47,29 @@
         private var alwaysExpand: Boolean = false
 
         /**
-         * Whether the activity should always be expanded on launch. Some activities are supposed to
-         * expand to the full task bounds, independent of the state of the split. An example is an
-         * activity that blocks all user interactions, such as a warning dialog.
+         * Sets whether the activity should always be expanded on launch. Some activities are
+         * supposed to expand to the full task bounds, independent of the state of the split. An
+         * example is an activity that blocks all user interactions, such as a warning dialog.
+         *
+         * @param alwaysExpand whether the activity should always be expanded on launch.
          */
         @SuppressWarnings("MissingGetterMatchingBuilder")
         fun setAlwaysExpand(alwaysExpand: Boolean): Builder =
             apply { this.alwaysExpand = alwaysExpand }
 
-        /** @see ActivityRule.tag */
+        /**
+         * Sets a unique string to identify this [ActivityRule], which defaults to `null`.
+         *
+         * @param tag unique string to identify this [ActivityRule].
+         */
         fun setTag(tag: String): Builder =
             apply { this.tag = tag }
 
+        /**
+         * Builds an `ActivityRule` instance.
+         *
+         * @return The new `ActivityRule` instance.
+         */
         fun build() = ActivityRule(tag, filters, alwaysExpand)
     }
 
diff --git a/window/window/src/main/java/androidx/window/embedding/ActivityStack.kt b/window/window/src/main/java/androidx/window/embedding/ActivityStack.kt
index 310ce17..7666ad7 100644
--- a/window/window/src/main/java/androidx/window/embedding/ActivityStack.kt
+++ b/window/window/src/main/java/androidx/window/embedding/ActivityStack.kt
@@ -38,18 +38,19 @@
      * process(es), [activitiesInProcess] will return an empty list, but this method will return
      * `false`.
      */
-    val isEmpty: Boolean = false
+    val isEmpty: Boolean
 ) {
 
+    /**
+     * Whether this [ActivityStack] contains the [activity].
+     */
     operator fun contains(activity: Activity): Boolean {
         return activitiesInProcess.contains(activity)
     }
 
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
-        if (javaClass != other?.javaClass) return false
-
-        other as ActivityStack
+        if (other !is ActivityStack) return false
 
         if (activitiesInProcess != other.activitiesInProcess) return false
         if (isEmpty != other.isEmpty) return false
diff --git a/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt b/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt
index c38e4f3..da6a05b 100644
--- a/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt
+++ b/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt
@@ -50,17 +50,7 @@
 import androidx.window.extensions.embedding.SplitPairRule.FINISH_NEVER
 import androidx.window.layout.WindowMetricsCalculator
 import androidx.window.layout.adapter.extensions.ExtensionsWindowLayoutInfoAdapter
-import kotlin.Any
-import kotlin.Float
-import kotlin.IllegalArgumentException
-import kotlin.IllegalStateException
-import kotlin.Int
 import kotlin.Pair
-import kotlin.Suppress
-import kotlin.apply
-import kotlin.arrayOf
-import kotlin.let
-import kotlin.require
 
 /**
  * Adapter class that translates data classes between Extension and Jetpack interfaces.
@@ -113,7 +103,9 @@
                     )
                 }
             )
-            .setAnimationBackgroundColor(splitAttributes.animationBackgroundColor)
+            .setAnimationBackgroundColor(SplitAttributes.BackgroundColor.buildFromValue(
+                splitAttributes.animationBackgroundColor)
+            )
             .build()
 
     private fun translate(splitType: OEMSplitType): SplitType =
@@ -228,7 +220,7 @@
                     )
                 }
             )
-            .setAnimationBackgroundColor(splitAttributes.animationBackgroundColor)
+            .setAnimationBackgroundColor(splitAttributes.animationBackgroundColor.value)
             .build()
     }
 
diff --git a/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt b/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt
index 4b13ef5..dafb5b9 100644
--- a/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt
+++ b/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt
@@ -111,7 +111,13 @@
 
         fun isEmbeddingAvailable(): Boolean {
             return try {
-                WindowExtensionsProvider.getWindowExtensions().activityEmbeddingComponent != null
+                EmbeddingCompat::class.java.classLoader?.let { loader ->
+                    SafeActivityEmbeddingComponentProvider(
+                        loader,
+                        ConsumerAdapter(loader),
+                        WindowExtensionsProvider.getWindowExtensions(),
+                    ).activityEmbeddingComponent != null
+                } ?: false
             } catch (e: NoClassDefFoundError) {
                 if (DEBUG) {
                     Log.d(TAG, "Embedding extension version not found")
@@ -127,17 +133,23 @@
 
         fun embeddingComponent(): ActivityEmbeddingComponent {
             return if (isEmbeddingAvailable()) {
-                WindowExtensionsProvider.getWindowExtensions().activityEmbeddingComponent
-                    ?: Proxy.newProxyInstance(
-                        EmbeddingCompat::class.java.classLoader,
-                        arrayOf(ActivityEmbeddingComponent::class.java)
-                    ) { _, _, _ -> } as ActivityEmbeddingComponent
+                EmbeddingCompat::class.java.classLoader?.let { loader ->
+                    SafeActivityEmbeddingComponentProvider(
+                        loader,
+                        ConsumerAdapter(loader),
+                        WindowExtensionsProvider.getWindowExtensions(),
+                    ).activityEmbeddingComponent
+                } ?: emptyActivityEmbeddingProxy()
             } else {
-                Proxy.newProxyInstance(
-                    EmbeddingCompat::class.java.classLoader,
-                    arrayOf(ActivityEmbeddingComponent::class.java)
-                ) { _, _, _ -> } as ActivityEmbeddingComponent
+                emptyActivityEmbeddingProxy()
             }
         }
+
+        private fun emptyActivityEmbeddingProxy(): ActivityEmbeddingComponent {
+            return Proxy.newProxyInstance(
+                EmbeddingCompat::class.java.classLoader,
+                arrayOf(ActivityEmbeddingComponent::class.java)
+            ) { _, _, _ -> } as ActivityEmbeddingComponent
+        }
     }
 }
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/embedding/MatcherUtils.kt b/window/window/src/main/java/androidx/window/embedding/MatcherUtils.kt
index eb61516..1095444 100644
--- a/window/window/src/main/java/androidx/window/embedding/MatcherUtils.kt
+++ b/window/window/src/main/java/androidx/window/embedding/MatcherUtils.kt
@@ -16,7 +16,6 @@
 package androidx.window.embedding
 
 import android.app.Activity
-import android.content.ComponentName
 import android.content.Intent
 import android.util.Log
 import androidx.window.core.ActivityComponentInfo
@@ -27,18 +26,6 @@
 internal object MatcherUtils {
     /** Checks component match allowing wildcard patterns. */
     internal fun areComponentsMatching(
-        activityComponent: ComponentName?,
-        ruleComponent: ComponentName
-    ): Boolean {
-        val activityActivityComponentInfo = activityComponent?.let(::ActivityComponentInfo)
-        return areComponentsMatching(
-            activityActivityComponentInfo,
-            ActivityComponentInfo(ruleComponent)
-        )
-    }
-
-    /** Checks component match allowing wildcard patterns. */
-    internal fun areComponentsMatching(
         activityComponent: ActivityComponentInfo?,
         ruleComponent: ActivityComponentInfo
     ): Boolean {
@@ -69,7 +56,7 @@
      * Returns `true` if [Activity.getComponentName] match or [Activity.getIntent] match allowing
      * wildcard patterns.
      */
-    internal fun isActivityOrIntentMatching(
+    internal fun isActivityMatching(
         activity: Activity,
         ruleComponent: ActivityComponentInfo
     ): Boolean {
@@ -86,20 +73,24 @@
      */
     internal fun isIntentMatching(
         intent: Intent,
-        ruleActivityComponentInfo: ActivityComponentInfo
+        ruleComponent: ActivityComponentInfo
     ): Boolean {
-        if (intent.component != null) {
-            // Compare the component if set.
-            return areComponentsMatching(
+        // Check if the component is matched.
+        if (areComponentsMatching(
                 intent.component?.let(::ActivityComponentInfo),
-                ruleActivityComponentInfo
-            )
+                ruleComponent
+            )) {
+            return true
+        }
+        if (intent.component != null) {
+            // Only check package if the component is not set.
+            return false
         }
         // Check if there is wildcard match for Intent that only specifies the packageName.
         val packageName = intent.`package` ?: return false
-        return (packageName == ruleActivityComponentInfo.packageName ||
-            wildcardMatch(packageName, ruleActivityComponentInfo.packageName)) &&
-            ruleActivityComponentInfo.className == "*"
+        return (packageName == ruleComponent.packageName ||
+            wildcardMatch(packageName, ruleComponent.packageName)) &&
+            ruleComponent.className == "*"
     }
 
     /**
@@ -123,6 +114,22 @@
         return name.startsWith(pattern.substring(0, pattern.length - 1))
     }
 
+    /**
+     * Makes sure the component name is in the correct format.
+     */
+    internal fun validateComponentName(packageName: String, className: String) {
+        require(packageName.isNotEmpty()) { "Package name must not be empty" }
+        require(className.isNotEmpty()) { "Activity class name must not be empty" }
+        require(
+            !(packageName.contains("*") &&
+                packageName.indexOf("*") != packageName.length - 1)
+        ) { "Wildcard in package name is only allowed at the end." }
+        require(
+            !(className.contains("*") &&
+                className.indexOf("*") != className.length - 1)
+        ) { "Wildcard in class name is only allowed at the end." }
+    }
+
     internal const val sDebugMatchers = SplitController.sDebug
     internal const val sMatchersTag = "SplitRuleResolution"
 }
diff --git a/window/window/src/main/java/androidx/window/embedding/RuleParser.kt b/window/window/src/main/java/androidx/window/embedding/RuleParser.kt
index c3334c0..add2f25 100644
--- a/window/window/src/main/java/androidx/window/embedding/RuleParser.kt
+++ b/window/window/src/main/java/androidx/window/embedding/RuleParser.kt
@@ -176,7 +176,8 @@
             val clearTop = typedArray.getBoolean(R.styleable.SplitPairRule_clearTop, false)
             val animationBackgroundColor = typedArray.getColor(
                 R.styleable.SplitPairRule_animationBackgroundColor,
-                0)
+                SplitAttributes.BackgroundColor.DEFAULT.value
+            )
             typedArray.recycle()
 
             val defaultAttrs = SplitAttributes.Builder()
@@ -184,7 +185,9 @@
                 .setLayoutDirection(
                     SplitAttributes.LayoutDirection.getLayoutDirectionFromValue(layoutDir)
                 )
-                .setAnimationBackgroundColor(animationBackgroundColor)
+                .setAnimationBackgroundColor(
+                    SplitAttributes.BackgroundColor.buildFromValue(animationBackgroundColor)
+                )
                 .build()
 
             SplitPairRule.Builder(emptySet())
@@ -258,7 +261,8 @@
             )
             val animationBackgroundColor = typedArray.getColor(
                 R.styleable.SplitPlaceholderRule_animationBackgroundColor,
-                0)
+                SplitAttributes.BackgroundColor.DEFAULT.value
+            )
             typedArray.recycle()
 
             val defaultAttrs = SplitAttributes.Builder()
@@ -266,7 +270,9 @@
                 .setLayoutDirection(
                     SplitAttributes.LayoutDirection.getLayoutDirectionFromValue(layoutDir)
                 )
-                .setAnimationBackgroundColor(animationBackgroundColor)
+                .setAnimationBackgroundColor(
+                    SplitAttributes.BackgroundColor.buildFromValue(animationBackgroundColor)
+                )
                 .build()
             val packageName = context.applicationContext.packageName
             val placeholderActivityClassName = buildClassName(
diff --git a/window/window/src/main/java/androidx/window/embedding/SafeActivityEmbeddingComponentProvider.kt b/window/window/src/main/java/androidx/window/embedding/SafeActivityEmbeddingComponentProvider.kt
new file mode 100644
index 0000000..44699d8
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/embedding/SafeActivityEmbeddingComponentProvider.kt
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2023 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 androidx.window.embedding
+
+import android.app.Activity
+import androidx.window.core.ConsumerAdapter
+import androidx.window.core.ExtensionsUtil
+import androidx.window.extensions.WindowExtensions
+import androidx.window.extensions.core.util.function.Consumer
+import androidx.window.extensions.core.util.function.Function
+import androidx.window.extensions.embedding.ActivityEmbeddingComponent
+import androidx.window.reflection.ReflectionUtils.doesReturn
+import androidx.window.reflection.ReflectionUtils.isPublic
+import androidx.window.reflection.ReflectionUtils.validateReflection
+import androidx.window.reflection.WindowExtensionsConstants.ACTIVITY_EMBEDDING_COMPONENT_CLASS
+import androidx.window.reflection.WindowExtensionsConstants.WINDOW_EXTENSIONS_CLASS
+import androidx.window.reflection.WindowExtensionsConstants.WINDOW_EXTENSIONS_PROVIDER_CLASS
+
+/**
+ * Reflection Guard for [ActivityEmbeddingComponent].
+ * This will go through the [ActivityEmbeddingComponent]'s method by reflection and
+ * check each method's name and signature to see if the interface is what we required.
+ */
+internal class SafeActivityEmbeddingComponentProvider(
+    private val loader: ClassLoader,
+    private val consumerAdapter: ConsumerAdapter,
+    private val windowExtensions: WindowExtensions
+) {
+    val activityEmbeddingComponent: ActivityEmbeddingComponent?
+        get() {
+            return if (canUseActivityEmbeddingComponent()) {
+                try {
+                    windowExtensions.activityEmbeddingComponent
+                } catch (e: UnsupportedOperationException) {
+                    null
+                }
+            } else {
+                null
+            }
+        }
+
+    private fun canUseActivityEmbeddingComponent(): Boolean {
+        if (!isWindowExtensionsValid() || !isActivityEmbeddingComponentValid()) {
+            return false
+        }
+        // TODO(b/267573854) : update logic to fallback to lower version
+        //  if higher version is not matched
+        return when (ExtensionsUtil.safeVendorApiLevel) {
+            1 -> hasValidVendorApiLevel1()
+            in 2..Int.MAX_VALUE -> hasValidVendorApiLevel2()
+            // TODO(b/267956499) : add  hasValidVendorApiLevel3
+            else -> false
+        }
+    }
+
+    /**
+     * [WindowExtensions.VENDOR_API_LEVEL_1] includes the following methods:
+     *  - [ActivityEmbeddingComponent.setEmbeddingRules]
+     *  - [ActivityEmbeddingComponent.isActivityEmbedded]
+     *  - [ActivityEmbeddingComponent.setSplitInfoCallback] with [java.util.function.Consumer]
+     * and following classes: TODO(b/268583307) : add guard function for those classes
+     *  - [androidx.window.extensions.embedding.ActivityRule]
+     *  - [androidx.window.extensions.embedding.SplitPairRule]
+     *  - [androidx.window.extensions.embedding.SplitPlaceholderRule]
+     *  - [androidx.window.extensions.embedding.SplitInfo]
+     */
+    private fun hasValidVendorApiLevel1(): Boolean {
+        return isMethodSetEmbeddingRulesValid() &&
+            isMethodIsActivityEmbeddedValid() &&
+            isMethodSetSplitInfoCallbackJavaConsumerValid()
+    }
+
+    /**
+     * [WindowExtensions.VENDOR_API_LEVEL_2] includes the following methods
+     *  - [ActivityEmbeddingComponent.setSplitInfoCallback] with [Consumer]
+     *  - [ActivityEmbeddingComponent.clearSplitInfoCallback]
+     *  - [ActivityEmbeddingComponent.setSplitAttributesCalculator]
+     *  - [ActivityEmbeddingComponent.clearSplitAttributesCalculator]
+     * and following classes: TODO(b/268583307) : add guard function for those classes
+     *  - [androidx.window.extensions.embedding.SplitAttributes]
+     */
+    private fun hasValidVendorApiLevel2(): Boolean {
+        return hasValidVendorApiLevel1() &&
+            isMethodSetSplitInfoCallbackWindowConsumerValid() &&
+            isMethodClearSplitInfoCallbackValid() &&
+            isMethodSplitAttributesCalculatorValid()
+    }
+
+    private fun isMethodSetEmbeddingRulesValid(): Boolean {
+        return validateReflection("ActivityEmbeddingComponent#setEmbeddingRules is not valid") {
+            val setEmbeddingRulesMethod = activityEmbeddingComponentClass.getMethod(
+                "setEmbeddingRules",
+                Set::class.java
+            )
+            setEmbeddingRulesMethod.isPublic
+        }
+    }
+
+    private fun isMethodIsActivityEmbeddedValid(): Boolean {
+        return validateReflection("ActivityEmbeddingComponent#isActivityEmbedded is not valid") {
+            val isActivityEmbeddedMethod = activityEmbeddingComponentClass.getMethod(
+                "isActivityEmbedded",
+                Activity::class.java
+            )
+            isActivityEmbeddedMethod.isPublic &&
+                isActivityEmbeddedMethod.doesReturn(Boolean::class.java)
+        }
+    }
+
+    private fun isMethodClearSplitInfoCallbackValid(): Boolean {
+        return validateReflection(
+            "ActivityEmbeddingComponent#clearSplitInfoCallback is not valid"
+        ) {
+            val clearSplitInfoCallbackMethod =
+                activityEmbeddingComponentClass.getMethod("clearSplitInfoCallback")
+            clearSplitInfoCallbackMethod.isPublic
+        }
+    }
+
+    private fun isMethodSplitAttributesCalculatorValid(): Boolean {
+        return validateReflection(
+            "ActivityEmbeddingComponent#setSplitAttributesCalculator is not valid"
+        ) {
+            val setSplitAttributesCalculatorMethod = activityEmbeddingComponentClass.getMethod(
+                "setSplitAttributesCalculator",
+                Function::class.java
+            )
+            val clearSplitAttributesCalculatorMethod =
+                activityEmbeddingComponentClass.getMethod("clearSplitAttributesCalculator")
+            setSplitAttributesCalculatorMethod.isPublic &&
+                clearSplitAttributesCalculatorMethod.isPublic
+        }
+    }
+
+    private fun isMethodSetSplitInfoCallbackJavaConsumerValid(): Boolean {
+        return validateReflection("ActivityEmbeddingComponent#setSplitInfoCallback is not valid") {
+            val consumerClass =
+                consumerAdapter.consumerClassOrNull() ?: return@validateReflection false
+            val setSplitInfoCallbackMethod =
+                activityEmbeddingComponentClass.getMethod("setSplitInfoCallback", consumerClass)
+            setSplitInfoCallbackMethod.isPublic
+        }
+    }
+
+    private fun isMethodSetSplitInfoCallbackWindowConsumerValid(): Boolean {
+        return validateReflection("ActivityEmbeddingComponent#setSplitInfoCallback is not valid") {
+            val setSplitInfoCallbackMethod = activityEmbeddingComponentClass.getMethod(
+                "setSplitInfoCallback",
+                Consumer::class.java
+            )
+            setSplitInfoCallbackMethod.isPublic
+        }
+    }
+
+    private fun isWindowExtensionsValid(): Boolean {
+        return validateReflection("WindowExtensionsProvider#getWindowExtensions is not valid") {
+            val providerClass = windowExtensionsProviderClass
+            val getWindowExtensionsMethod = providerClass.getDeclaredMethod("getWindowExtensions")
+            val windowExtensionsClass = windowExtensionsClass
+            getWindowExtensionsMethod.isPublic && getWindowExtensionsMethod.doesReturn(
+                windowExtensionsClass
+            )
+        }
+    }
+
+    private fun isActivityEmbeddingComponentValid(): Boolean {
+        return validateReflection("WindowExtensions#getActivityEmbeddingComponent is not valid") {
+            val extensionsClass = windowExtensionsClass
+            val getActivityEmbeddingComponentMethod =
+                extensionsClass.getMethod("getActivityEmbeddingComponent")
+            val activityEmbeddingComponentClass = activityEmbeddingComponentClass
+            getActivityEmbeddingComponentMethod.isPublic &&
+                getActivityEmbeddingComponentMethod.doesReturn(activityEmbeddingComponentClass)
+        }
+    }
+
+    private val windowExtensionsProviderClass: Class<*>
+        get() {
+            return loader.loadClass(WINDOW_EXTENSIONS_PROVIDER_CLASS)
+        }
+
+    private val windowExtensionsClass: Class<*>
+        get() {
+            return loader.loadClass(WINDOW_EXTENSIONS_CLASS)
+        }
+
+    private val activityEmbeddingComponentClass: Class<*>
+        get() {
+            return loader.loadClass(ACTIVITY_EMBEDDING_COMPONENT_CLASS)
+        }
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt b/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt
index d83ce52..64219d2 100644
--- a/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt
@@ -17,14 +17,14 @@
 package androidx.window.embedding
 
 import android.annotation.SuppressLint
+import android.graphics.Color
 import androidx.annotation.ColorInt
 import androidx.annotation.FloatRange
 import androidx.annotation.IntRange
 import androidx.window.core.SpecificationComputer.Companion.startSpecification
 import androidx.window.core.VerificationMode
-import androidx.window.embedding.SplitAttributes.LayoutDirection
+import androidx.window.embedding.SplitAttributes.BackgroundColor
 import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.LOCALE
-import androidx.window.embedding.SplitAttributes.SplitType
 import androidx.window.embedding.SplitAttributes.SplitType.Companion.splitEqually
 
 /**
@@ -48,15 +48,16 @@
  *   - Setting `splitRatio`, `splitLayoutDirection`, and
  *     `animationBackgroundColor` attributes in `<SplitPairRule>` or
  *     `<SplitPlaceholderRule>` tags in an XML configuration file. The
- *     attributes are parsed as [SplitType], [LayoutDirection], and [ColorInt],
- *     respectively. Note that [SplitType.HingeSplitType] is not supported XML
- *     format.
+ *     attributes are parsed as [SplitType], [LayoutDirection], and
+ *     [BackgroundColor], respectively. Note that [SplitType.HingeSplitType]
+ *     is not supported XML format.
  *   - Using
  *     [SplitAttributesCalculator.computeSplitAttributesForParams] to customize
  *     the `SplitAttributes` for a given device and window state.
  *
  * @see SplitAttributes.SplitType
  * @see SplitAttributes.LayoutDirection
+ * @see SplitAttributes.BackgroundColor
  */
 class SplitAttributes internal constructor(
 
@@ -73,14 +74,16 @@
     val layoutDirection: LayoutDirection = LOCALE,
 
     /**
-     * The [ColorInt] to use for the background color during the animation of
+     * The color to use for the background color during the animation of
      * the split involving this `SplitAttributes` object if the animation
      * requires a background.
      *
-     * The default is 0, which specifies the theme window background color.
+     * The default is to use the current theme window background color.
+     *
+     * @see BackgroundColor.color
+     * @see BackgroundColor.DEFAULT
      */
-    @ColorInt
-    val animationBackgroundColor: Int = 0
+    val animationBackgroundColor: BackgroundColor = BackgroundColor.DEFAULT
 ) {
 
     /**
@@ -422,6 +425,85 @@
     }
 
     /**
+     * Background color to be used for window transition animations in a split if the animation
+     * requires a background.
+     *
+     * @see SplitAttributes.animationBackgroundColor
+     */
+    class BackgroundColor private constructor(
+
+        /**
+         * The description of this `BackgroundColor`.
+         */
+        private val description: String,
+
+        /**
+         * [ColorInt] to represent the color to use as the background color.
+         */
+        @ColorInt
+        internal val value: Int,
+    ) {
+        override fun toString() = "BackgroundColor($description)"
+
+        override fun equals(other: Any?): Boolean {
+            if (other === this) return true
+            if (other !is BackgroundColor) return false
+            return value == other.value && description == other.description
+        }
+
+        override fun hashCode() = description.hashCode() + 31 * value.hashCode()
+
+        /**
+         * Methods that create various [BackgroundColor].
+         */
+        companion object {
+
+            /**
+             * Creates a [BackgroundColor] to represent the given [color].
+             *
+             * Only opaque color is supported.
+             *
+             * @param color [ColorInt] of an opaque color.
+             * @return the [BackgroundColor] representing the [color].
+             *
+             * @see [DEFAULT] for the default value, which means to use the
+             * current theme window background color.
+             */
+            @JvmStatic
+            fun color(
+                @IntRange(from = Color.BLACK.toLong(), to = Color.WHITE.toLong())
+                @ColorInt
+                color: Int
+            ):
+                BackgroundColor {
+                require(Color.BLACK <= color && color <= Color.WHITE) {
+                    "Background color must be opaque"
+                }
+                return BackgroundColor("color:${Integer.toHexString(color)}", color)
+            }
+
+            /**
+             * The special [BackgroundColor] to represent the default value,
+             * which means to use the current theme window background color.
+             */
+            @JvmField
+            val DEFAULT = BackgroundColor("DEFAULT", 0)
+
+            /**
+             * Returns a [BackgroundColor] with the given [value]
+             */
+            internal fun buildFromValue(@ColorInt value: Int): BackgroundColor {
+                return if (Color.alpha(value) != 255) {
+                    // Treat any non-opaque color as the default.
+                    DEFAULT
+                } else {
+                    color(value)
+                }
+            }
+        }
+    }
+
+    /**
      * Non-public properties and methods.
      */
     companion object {
@@ -464,21 +546,21 @@
     override fun toString(): String =
         "${SplitAttributes::class.java.simpleName}:" +
             "{splitType=$splitType, layoutDir=$layoutDirection," +
-            " animationBackgroundColor=${Integer.toHexString(animationBackgroundColor)}"
+            " animationBackgroundColor=$animationBackgroundColor"
 
     /**
      * Builder for creating an instance of [SplitAttributes].
      *
-     * The default split type is an equal split between primary and secondary
-     * containers. The default layout direction is based on locale. The default
-     * animation background color is 0, which specifies the theme window
-     * background color.
+     *  - The default split type is an equal split between primary and secondary
+     *    containers.
+     *  - The default layout direction is based on locale.
+     *  - The default animation background color is to use the current theme
+     *    window background color.
      */
     class Builder {
         private var splitType: SplitType = splitEqually()
         private var layoutDirection = LOCALE
-        @ColorInt
-        private var animationBackgroundColor = 0
+        private var animationBackgroundColor = BackgroundColor.DEFAULT
 
         /**
          * Sets the split type attribute.
@@ -507,20 +589,23 @@
             apply { this.layoutDirection = layoutDirection }
 
         /**
-         * Sets the [ColorInt] to use for the background color during animation
+         * Sets the color to use for the background color during animation
          * of the split involving this `SplitAttributes` object if the animation
-         * requires a background.
+         * requires a background. Only opaque color is supported.
          *
-         * The default is 0, which specifies the theme window background color.
+         * The default is [BackgroundColor.DEFAULT], which means to use the
+         * current theme window background color.
          *
-         * @param color A packed color int of the form `AARRGGBB`, for the
-         * animation background color.
+         * @param color The animation background color.
          * @return This `Builder`.
          *
-         * @see SplitAttributes.animationBackgroundColor
+         * @see BackgroundColor.color
+         * @see BackgroundColor.DEFAULT
          */
-        fun setAnimationBackgroundColor(@ColorInt color: Int): Builder =
-            apply { this.animationBackgroundColor = color }
+        fun setAnimationBackgroundColor(color: BackgroundColor): Builder =
+            apply {
+                animationBackgroundColor = color
+            }
 
         /**
          * Builds a `SplitAttributes` instance with the attributes specified by
diff --git a/window/window/src/main/java/androidx/window/embedding/SplitInfo.kt b/window/window/src/main/java/androidx/window/embedding/SplitInfo.kt
index fabb354..b3dc89c 100644
--- a/window/window/src/main/java/androidx/window/embedding/SplitInfo.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SplitInfo.kt
@@ -31,6 +31,10 @@
     /** The [SplitAttributes] of this split pair. */
     val splitAttributes: SplitAttributes
 ) {
+    /**
+     * Whether the [primaryActivityStack] or the [secondaryActivityStack] in this [SplitInfo]
+     * contains the [activity].
+     */
     operator fun contains(activity: Activity): Boolean {
         return primaryActivityStack.contains(activity) ||
             secondaryActivityStack.contains(activity)
diff --git a/window/window/src/main/java/androidx/window/embedding/SplitPairFilter.kt b/window/window/src/main/java/androidx/window/embedding/SplitPairFilter.kt
index d09fa3b..5c022fa 100644
--- a/window/window/src/main/java/androidx/window/embedding/SplitPairFilter.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SplitPairFilter.kt
@@ -20,10 +20,11 @@
 import android.content.Intent
 import android.util.Log
 import androidx.window.core.ActivityComponentInfo
-import androidx.window.embedding.MatcherUtils.areComponentsMatching
+import androidx.window.embedding.MatcherUtils.isActivityMatching
 import androidx.window.embedding.MatcherUtils.isIntentMatching
 import androidx.window.embedding.MatcherUtils.sDebugMatchers
 import androidx.window.embedding.MatcherUtils.sMatchersTag
+import androidx.window.embedding.MatcherUtils.validateComponentName
 
 /**
  * Filter for [SplitPairRule] and used to find if a pair of activities should be put in a split.
@@ -79,6 +80,14 @@
     val secondaryActivityIntentAction: String?
 ) {
 
+    init {
+        validateComponentName(primaryActivityName.packageName, primaryActivityName.className)
+        validateComponentName(secondaryActivityName.packageName, secondaryActivityName.className)
+    }
+
+    private val primaryActivityInfo: ActivityComponentInfo
+        get() = ActivityComponentInfo(primaryActivityName)
+
     private val secondaryActivityInfo: ActivityComponentInfo
         get() = ActivityComponentInfo(secondaryActivityName)
 
@@ -92,11 +101,13 @@
      */
     fun matchesActivityPair(primaryActivity: Activity, secondaryActivity: Activity): Boolean {
         // Check if the activity component names match
-        var match = areComponentsMatching(primaryActivity.componentName, primaryActivityName) &&
-            areComponentsMatching(secondaryActivity.componentName, secondaryActivityName)
-        // If the intent is not empty - check that the rest of the filter fields match
-        if (secondaryActivity.intent != null) {
-            match = match && matchesActivityIntentPair(primaryActivity, secondaryActivity.intent)
+        val match = if (!isActivityMatching(primaryActivity, primaryActivityInfo)) {
+            false
+        } else if (!isActivityMatching(secondaryActivity, secondaryActivityInfo)) {
+            false
+        } else {
+            secondaryActivityIntentAction == null ||
+                secondaryActivityIntentAction == secondaryActivity.intent?.action
         }
 
         if (sDebugMatchers) {
@@ -123,14 +134,9 @@
         primaryActivity: Activity,
         secondaryActivityIntent: Intent
     ): Boolean {
-        val inPrimaryActivityName = primaryActivity.componentName
-        val match = if (
-            !areComponentsMatching(inPrimaryActivityName, primaryActivityName)
-        ) {
+        val match = if (!isActivityMatching(primaryActivity, primaryActivityInfo)) {
             false
-        } else if (
-            !isIntentMatching(secondaryActivityIntent, secondaryActivityInfo)
-        ) {
+        } else if (!isIntentMatching(secondaryActivityIntent, secondaryActivityInfo)) {
             false
         } else {
             secondaryActivityIntentAction == null ||
@@ -147,43 +153,6 @@
         return match
     }
 
-    init {
-        val primaryPackageName = primaryActivityName.packageName
-        val primaryClassName = primaryActivityName.className
-        val secondaryPackageName = secondaryActivityName.packageName
-        val secondaryClassName = secondaryActivityName.className
-        require(
-            !(primaryPackageName.isEmpty() || secondaryPackageName.isEmpty())
-        ) { "Package name must not be empty" }
-        require(
-            !(primaryClassName.isEmpty() || secondaryClassName.isEmpty())
-        ) { "Activity class name must not be empty." }
-        require(
-            !(
-                primaryPackageName.contains("*") &&
-                    primaryPackageName.indexOf("*") != primaryPackageName.length - 1
-                )
-        ) { "Wildcard in package name is only allowed at the end." }
-        require(
-            !(
-                primaryClassName.contains("*") &&
-                    primaryClassName.indexOf("*") != primaryClassName.length - 1
-                )
-        ) { "Wildcard in class name is only allowed at the end." }
-        require(
-            !(
-                secondaryPackageName.contains("*") &&
-                    secondaryPackageName.indexOf("*") != secondaryPackageName.length - 1
-                )
-        ) { "Wildcard in package name is only allowed at the end." }
-        require(
-            !(
-                secondaryClassName.contains("*") &&
-                    secondaryClassName.indexOf("*") != secondaryClassName.length - 1
-                )
-        ) { "Wildcard in class name is only allowed at the end." }
-    }
-
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (other !is SplitPairFilter) return false
diff --git a/window/window/src/main/java/androidx/window/embedding/SplitPairRule.kt b/window/window/src/main/java/androidx/window/embedding/SplitPairRule.kt
index 76a561c..2cf3650 100644
--- a/window/window/src/main/java/androidx/window/embedding/SplitPairRule.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SplitPairRule.kt
@@ -117,6 +117,9 @@
          *
          * The default is [SPLIT_MIN_DIMENSION_DP_DEFAULT] if the app doesn't set.
          * [SPLIT_MIN_DIMENSION_ALWAYS_ALLOW] means to always allow split.
+         *
+         * @param minWidthDp the smallest value of width of the parent window when the split should
+         * be used, in DP.
          */
         fun setMinWidthDp(@IntRange(from = 0) minWidthDp: Int): Builder =
             apply { this.minWidthDp = minWidthDp }
@@ -133,6 +136,9 @@
          * The default is [SPLIT_MIN_DIMENSION_DP_DEFAULT] if the app doesn't set.
          * [SPLIT_MIN_DIMENSION_ALWAYS_ALLOW] means to always allow split.
          *
+         * @param minHeightDp the smallest value of height of the parent task window when the split
+         * should be used, in DP.
+         *
          * @see SplitAttributes.LayoutDirection.TOP_TO_BOTTOM
          * @see SplitAttributes.LayoutDirection.BOTTOM_TO_TOP
          */
@@ -141,12 +147,15 @@
 
         /**
          * Sets the smallest value of the smallest possible width of the parent window in any
-         * rotation  when the split should be used, in DP. When the window size is smaller than
+         * rotation when the split should be used, in DP. When the window size is smaller than
          * requested here, activities in the secondary container will be stacked on top of the
          * activities in the primary one, completely overlapping them.
          *
          * The default is [SPLIT_MIN_DIMENSION_DP_DEFAULT] if the app doesn't set.
          * [SPLIT_MIN_DIMENSION_ALWAYS_ALLOW] means to always allow split.
+         *
+         * @param minSmallestWidthDp the smallest value of the smallest possible width of the parent
+         * window in any rotation when the split should be used, in DP.
          */
         fun setMinSmallestWidthDp(@IntRange(from = 0) minSmallestWidthDp: Int): Builder =
             apply { this.minSmallestWidthDp = minSmallestWidthDp }
@@ -163,6 +172,9 @@
          * the recommend value to only allow split when the parent window is not too stretched in
          * portrait.
          *
+         * @param aspectRatio the largest value of the aspect ratio, expressed as `height / width`
+         * in decimal form, of the parent window bounds in portrait when the split should be used.
+         *
          * @see EmbeddingAspectRatio.ratio
          * @see EmbeddingAspectRatio.ALWAYS_ALLOW
          * @see EmbeddingAspectRatio.ALWAYS_DISALLOW
@@ -181,6 +193,9 @@
          * The default is [SPLIT_MAX_ASPECT_RATIO_LANDSCAPE_DEFAULT] if the app doesn't set, which
          * is the recommend value to always allow split when the parent window is in landscape.
          *
+         * @param aspectRatio the largest value of the aspect ratio, expressed as `width / height`
+         * in decimal form, of the parent window bounds in landscape when the split should be used.
+         *
          * @see EmbeddingAspectRatio.ratio
          * @see EmbeddingAspectRatio.ALWAYS_ALLOW
          * @see EmbeddingAspectRatio.ALWAYS_DISALLOW
@@ -192,6 +207,9 @@
          * Sets the behavior of the primary container when all activities are finished in the
          * associated secondary container.
          *
+         * @param finishPrimaryWithSecondary the [SplitRule.FinishBehavior] of the primary container
+         * when all activities are finished in the associated secondary container.
+         *
          * @see SplitRule.FinishBehavior.NEVER
          * @see SplitRule.FinishBehavior.ALWAYS
          * @see SplitRule.FinishBehavior.ADJACENT
@@ -205,6 +223,9 @@
          * Sets the behavior of the secondary container when all activities are finished in the
          * associated primary container.
          *
+         * @param finishSecondaryWithPrimary the [SplitRule.FinishBehavior] of the secondary
+         * container when all activities are finished in the associated primary container.
+         *
          * @see SplitRule.FinishBehavior.NEVER
          * @see SplitRule.FinishBehavior.ALWAYS
          * @see SplitRule.FinishBehavior.ADJACENT
@@ -218,6 +239,9 @@
          * Sets whether the existing secondary container on top and all activities in it should be
          * destroyed when a new split is created using this rule. Otherwise the new secondary will
          * appear on top by default.
+         *
+         * @param clearTop whether the existing secondary container on top and all activities in it
+         * should be destroyed when a new split is created using this rule.
          */
         @SuppressWarnings("MissingGetterMatchingBuilder")
         fun setClearTop(clearTop: Boolean): Builder =
@@ -227,6 +251,9 @@
          * Sets the default [SplitAttributes] to apply on the activity containers pair when the host
          * task bounds satisfy [minWidthDp], [minHeightDp], [minSmallestWidthDp],
          * [maxAspectRatioInPortrait] and [maxAspectRatioInLandscape] requirements.
+         *
+         * @param defaultSplitAttributes the default [SplitAttributes] to apply on the activity
+         * containers pair when the host task bounds satisfy all the rule requirements.
          */
         fun setDefaultSplitAttributes(defaultSplitAttributes: SplitAttributes): Builder =
             apply { this.defaultSplitAttributes = defaultSplitAttributes }
@@ -235,10 +262,17 @@
          * Sets a unique string to identify this [SplitPairRule], which defaults to `null`.
          * The suggested usage is to set the tag to be able to differentiate between different rules
          * in the [SplitAttributesCalculatorParams.splitRuleTag].
+         *
+         * @param tag unique string to identify this [SplitPairRule].
          */
         fun setTag(tag: String?): Builder =
             apply { this.tag = tag }
 
+        /**
+         * Builds a `SplitPairRule` instance.
+         *
+         * @return The new `SplitPairRule` instance.
+         */
         fun build() = SplitPairRule(
             tag,
             filters,
diff --git a/window/window/src/main/java/androidx/window/embedding/SplitPlaceholderRule.kt b/window/window/src/main/java/androidx/window/embedding/SplitPlaceholderRule.kt
index 1dc70c1..2639171 100644
--- a/window/window/src/main/java/androidx/window/embedding/SplitPlaceholderRule.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SplitPlaceholderRule.kt
@@ -128,6 +128,9 @@
          *
          * The default is [SPLIT_MIN_DIMENSION_DP_DEFAULT] if the app doesn't set.
          * [SPLIT_MIN_DIMENSION_ALWAYS_ALLOW] means to always allow split.
+         *
+         * @param minWidthDp the smallest value of width of the parent window when the split should
+         * be used, in DP.
          */
         fun setMinWidthDp(@IntRange(from = 0) minWidthDp: Int): Builder =
             apply { this.minWidthDp = minWidthDp }
@@ -144,6 +147,9 @@
          * The default is [SPLIT_MIN_DIMENSION_DP_DEFAULT] if the app doesn't set.
          * [SPLIT_MIN_DIMENSION_ALWAYS_ALLOW] means to always allow split.
          *
+         * @param minHeightDp the smallest value of height of the parent task window when the split
+         * should be used, in DP.
+         *
          * @see SplitAttributes.LayoutDirection.TOP_TO_BOTTOM
          * @see SplitAttributes.LayoutDirection.BOTTOM_TO_TOP
          */
@@ -152,12 +158,15 @@
 
         /**
          * Sets the smallest value of the smallest possible width of the parent window in any
-         * rotation  when the split should be used, in DP. When the window size is smaller than
+         * rotation when the split should be used, in DP. When the window size is smaller than
          * requested here, activities in the secondary container will be stacked on top of the
          * activities in the primary one, completely overlapping them.
          *
          * The default is [SPLIT_MIN_DIMENSION_DP_DEFAULT] if the app doesn't set.
          * [SPLIT_MIN_DIMENSION_ALWAYS_ALLOW] means to always allow split.
+         *
+         * @param minSmallestWidthDp the smallest value of the smallest possible width of the parent
+         * window in any rotation when the split should be used, in DP.
          */
         fun setMinSmallestWidthDp(@IntRange(from = 0) minSmallestWidthDp: Int): Builder =
             apply { this.minSmallestWidthDp = minSmallestWidthDp }
@@ -174,6 +183,9 @@
          * the recommend value to only allow split when the parent window is not too stretched in
          * portrait.
          *
+         * @param aspectRatio the largest value of the aspect ratio, expressed as `height / width`
+         * in decimal form, of the parent window bounds in portrait when the split should be used.
+         *
          * @see EmbeddingAspectRatio.ratio
          * @see EmbeddingAspectRatio.ALWAYS_ALLOW
          * @see EmbeddingAspectRatio.ALWAYS_DISALLOW
@@ -192,6 +204,9 @@
          * The default is [SPLIT_MAX_ASPECT_RATIO_LANDSCAPE_DEFAULT] if the app doesn't set, which
          * is the recommend value to always allow split when the parent window is in landscape.
          *
+         * @param aspectRatio the largest value of the aspect ratio, expressed as `width / height`
+         * in decimal form, of the parent window bounds in landscape when the split should be used.
+         *
          * @see EmbeddingAspectRatio.ratio
          * @see EmbeddingAspectRatio.ALWAYS_ALLOW
          * @see EmbeddingAspectRatio.ALWAYS_DISALLOW
@@ -205,6 +220,9 @@
          *
          * **Note** that it is not valid to set [SplitRule.FinishBehavior.NEVER]
          *
+         * @param finishPrimaryWithPlaceholder the [SplitRule.FinishBehavior] of the primary
+         * container when all activities are finished in the associated placeholder container.
+         *
          * @see SplitRule.FinishBehavior.ALWAYS
          * @see SplitRule.FinishBehavior.ADJACENT
          */
@@ -216,6 +234,9 @@
         /**
          * Sets whether the placeholder will show on top in a smaller window size after it first
          * appeared in a split with sufficient minimum width.
+         *
+         * @param isSticky whether the placeholder will show on top in a smaller window size after
+         * it first appeared in a split with sufficient minimum width.
          */
         fun setSticky(isSticky: Boolean): Builder =
             apply { this.isSticky = isSticky }
@@ -224,6 +245,9 @@
          * Sets the default [SplitAttributes] to apply on the activity containers pair when the host
          * task bounds satisfy [minWidthDp], [minHeightDp], [minSmallestWidthDp],
          * [maxAspectRatioInPortrait] and [maxAspectRatioInLandscape] requirements.
+         *
+         * @param defaultSplitAttributes the default [SplitAttributes] to apply on the activity
+         * containers pair when the host task bounds satisfy all the rule requirements.
          */
         fun setDefaultSplitAttributes(defaultSplitAttributes: SplitAttributes): Builder =
             apply { this.defaultSplitAttributes = defaultSplitAttributes }
@@ -232,10 +256,17 @@
          * Sets a unique string to identify this [SplitPlaceholderRule], which defaults to `null`.
          * The suggested usage is to set the tag to be able to differentiate between different rules
          * in the [SplitAttributesCalculatorParams.splitRuleTag].
+         *
+         * @param tag unique string to identify this [SplitPlaceholderRule].
          */
         fun setTag(tag: String?): Builder =
             apply { this.tag = tag }
 
+        /**
+         * Builds a `SplitPlaceholderRule` instance.
+         *
+         * @return The new `SplitPlaceholderRule` instance.
+         */
         fun build() = SplitPlaceholderRule(
             tag,
             filters,
diff --git a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
index 6c9ec9d..fdc25a2 100644
--- a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
+++ b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
@@ -17,14 +17,30 @@
 package androidx.window.layout
 
 import android.app.Activity
+import android.content.Context
 import android.graphics.Rect
 import androidx.window.core.ConsumerAdapter
+import androidx.window.core.ExtensionsUtil
+import androidx.window.extensions.WindowExtensions
 import androidx.window.extensions.WindowExtensionsProvider
+import androidx.window.extensions.core.util.function.Consumer
 import androidx.window.extensions.layout.WindowLayoutComponent
-import java.lang.reflect.Method
-import java.lang.reflect.Modifier
-import kotlin.reflect.KClass
+import androidx.window.reflection.ReflectionUtils.checkIsPresent
+import androidx.window.reflection.ReflectionUtils.doesReturn
+import androidx.window.reflection.ReflectionUtils.isPublic
+import androidx.window.reflection.ReflectionUtils.validateReflection
+import androidx.window.reflection.WindowExtensionsConstants.FOLDING_FEATURE_CLASS
+import androidx.window.reflection.WindowExtensionsConstants.JAVA_CONSUMER
+import androidx.window.reflection.WindowExtensionsConstants.WINDOW_CONSUMER
+import androidx.window.reflection.WindowExtensionsConstants.WINDOW_EXTENSIONS_CLASS
+import androidx.window.reflection.WindowExtensionsConstants.WINDOW_EXTENSIONS_PROVIDER_CLASS
+import androidx.window.reflection.WindowExtensionsConstants.WINDOW_LAYOUT_COMPONENT_CLASS
 
+/**
+ * Reflection Guard for [WindowLayoutComponent].
+ * This will go through the [WindowLayoutComponent]'s method by reflection and
+ * check each method's name and signature to see if the interface is what we required.
+ */
 internal class SafeWindowLayoutComponentProvider(
     private val loader: ClassLoader,
     private val consumerAdapter: ConsumerAdapter
@@ -44,14 +60,53 @@
         }
 
     private fun canUseWindowLayoutComponent(): Boolean {
-        return isWindowLayoutProviderValid() &&
-            isWindowExtensionsValid() &&
-            isWindowLayoutComponentValid() &&
-            isFoldingFeatureValid()
+        if (!isWindowExtensionsPresent() || !isWindowExtensionsValid() ||
+            !isWindowLayoutProviderValid() ||
+            !isFoldingFeatureValid()
+        ) {
+            return false
+        }
+        // TODO(b/267831038): can fallback to VendorApiLevel1 when level2 is not match
+        //  but level 1 is matched
+        return when (ExtensionsUtil.safeVendorApiLevel) {
+            1 -> hasValidVendorApiLevel1()
+            in 2..Int.MAX_VALUE -> hasValidVendorApiLevel2()
+            // TODO(b/267956499): add hasValidVendorApiLevel3
+            else -> false
+        }
     }
 
-    private fun isWindowLayoutProviderValid(): Boolean {
-        return validate {
+    private fun isWindowExtensionsPresent(): Boolean {
+        return checkIsPresent {
+            loader.loadClass(WINDOW_EXTENSIONS_PROVIDER_CLASS)
+        }
+    }
+
+    /**
+     * [WindowExtensions.VENDOR_API_LEVEL_1] includes the following methods
+     *  - [WindowLayoutComponent.addWindowLayoutInfoListener] with [Activity] and
+     * [java.util.function.Consumer]
+     *  - [WindowLayoutComponent.removeWindowLayoutInfoListener] with [java.util.function.Consumer]
+     */
+    private fun hasValidVendorApiLevel1(): Boolean {
+        return isMethodWindowLayoutInfoListenerJavaConsumerValid()
+    }
+
+    /**
+     * [WindowExtensions.VENDOR_API_LEVEL_2] includes the following methods
+     *  - [WindowLayoutComponent.addWindowLayoutInfoListener] with [Context] and
+     * [java.util.function.Consumer]
+     *  - [WindowLayoutComponent.addWindowLayoutInfoListener] with [Context] and [Consumer]
+     *  - [WindowLayoutComponent.removeWindowLayoutInfoListener] with [Consumer]
+     */
+    private fun hasValidVendorApiLevel2(): Boolean {
+        return hasValidVendorApiLevel1() &&
+            isMethodWindowLayoutInfoListenerJavaConsumerUiContextValid() &&
+            isMethodWindowLayoutInfoListenerWindowConsumerValid()
+    }
+
+    private fun isWindowExtensionsValid(): Boolean {
+        return validateReflection("WindowExtensionsProvider#getWindowExtensions is not valid") {
             val providerClass = windowExtensionsProviderClass
             val getWindowExtensionsMethod = providerClass.getDeclaredMethod("getWindowExtensions")
             val windowExtensionsClass = windowExtensionsClass
@@ -60,8 +115,8 @@
         }
     }
 
-    private fun isWindowExtensionsValid(): Boolean {
-        return validate {
+    private fun isWindowLayoutProviderValid(): Boolean {
+        return validateReflection("WindowExtensions#getWindowLayoutComponent is not valid") {
             val extensionsClass = windowExtensionsClass
             val getWindowLayoutComponentMethod =
                 extensionsClass.getMethod("getWindowLayoutComponent")
@@ -72,7 +127,7 @@
     }
 
     private fun isFoldingFeatureValid(): Boolean {
-        return validate {
+        return validateReflection("FoldingFeature class is not valid") {
             val foldingFeatureClass = foldingFeatureClass
             val getBoundsMethod = foldingFeatureClass.getMethod("getBounds")
             val getTypeMethod = foldingFeatureClass.getMethod("getType")
@@ -86,9 +141,13 @@
         }
     }
 
-    private fun isWindowLayoutComponentValid(): Boolean {
-        return validate {
-            val consumerClass = consumerAdapter.consumerClassOrNull() ?: return@validate false
+    private fun isMethodWindowLayoutInfoListenerJavaConsumerValid(): Boolean {
+        return validateReflection(
+            "WindowLayoutComponent#addWindowLayoutInfoListener(" +
+                "${Activity::class.java.name}, $JAVA_CONSUMER) is not valid"
+        ) {
+            val consumerClass =
+                consumerAdapter.consumerClassOrNull() ?: return@validateReflection false
             val windowLayoutComponent = windowLayoutComponentClass
             val addListenerMethod = windowLayoutComponent
                 .getMethod(
@@ -102,46 +161,59 @@
         }
     }
 
-    private fun validate(block: () -> Boolean): Boolean {
-        return try {
-            block()
-        } catch (noClass: ClassNotFoundException) {
-            false
-        } catch (noMethod: NoSuchMethodException) {
-            false
+    private fun isMethodWindowLayoutInfoListenerWindowConsumerValid(): Boolean {
+        return validateReflection(
+            "WindowLayoutComponent#addWindowLayoutInfoListener" +
+                "(${Context::class.java.name}, $WINDOW_CONSUMER) is not valid"
+        ) {
+            val windowLayoutComponent = windowLayoutComponentClass
+            val addListenerMethod = windowLayoutComponent
+                .getMethod(
+                    "addWindowLayoutInfoListener",
+                    Context::class.java,
+                    Consumer::class.java
+                )
+            val removeListenerMethod = windowLayoutComponent
+                .getMethod("removeWindowLayoutInfoListener", Consumer::class.java)
+            addListenerMethod.isPublic && removeListenerMethod.isPublic
         }
     }
 
-    private val Method.isPublic: Boolean
-        get() {
-            return Modifier.isPublic(modifiers)
+    private fun isMethodWindowLayoutInfoListenerJavaConsumerUiContextValid(): Boolean {
+        return validateReflection(
+            "WindowLayoutComponent#addWindowLayoutInfoListener" +
+                "(${Context::class.java.name}, $JAVA_CONSUMER) is not valid"
+        ) {
+            val consumerClass =
+                consumerAdapter.consumerClassOrNull() ?: return@validateReflection false
+            val windowLayoutComponent = windowLayoutComponentClass
+            val addListenerMethod = windowLayoutComponent
+                .getMethod(
+                    "addWindowLayoutInfoListener",
+                    Context::class.java,
+                    consumerClass
+                )
+            addListenerMethod.isPublic
         }
-
-    private fun Method.doesReturn(clazz: KClass<*>): Boolean {
-        return doesReturn(clazz.java)
-    }
-
-    private fun Method.doesReturn(clazz: Class<*>): Boolean {
-        return returnType.equals(clazz)
     }
 
     private val windowExtensionsProviderClass: Class<*>
         get() {
-            return loader.loadClass("androidx.window.extensions.WindowExtensionsProvider")
+            return loader.loadClass(WINDOW_EXTENSIONS_PROVIDER_CLASS)
         }
 
     private val windowExtensionsClass: Class<*>
         get() {
-            return loader.loadClass("androidx.window.extensions.WindowExtensions")
+            return loader.loadClass(WINDOW_EXTENSIONS_CLASS)
         }
 
     private val foldingFeatureClass: Class<*>
         get() {
-            return loader.loadClass("androidx.window.extensions.layout.FoldingFeature")
+            return loader.loadClass(FOLDING_FEATURE_CLASS)
         }
 
     private val windowLayoutComponentClass: Class<*>
         get() {
-            return loader.loadClass("androidx.window.extensions.layout.WindowLayoutComponent")
+            return loader.loadClass(WINDOW_LAYOUT_COMPONENT_CLASS)
         }
 }
diff --git a/window/window/src/main/java/androidx/window/layout/WindowInfoTracker.kt b/window/window/src/main/java/androidx/window/layout/WindowInfoTracker.kt
index 242217a..8af11e0 100644
--- a/window/window/src/main/java/androidx/window/layout/WindowInfoTracker.kt
+++ b/window/window/src/main/java/androidx/window/layout/WindowInfoTracker.kt
@@ -24,6 +24,7 @@
 import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
 import androidx.annotation.UiContext
 import androidx.window.core.ConsumerAdapter
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.adapter.WindowBackend
 import androidx.window.layout.adapter.extensions.ExtensionWindowLayoutInfoBackend
 import androidx.window.layout.adapter.sidecar.SidecarWindowBackend
@@ -61,6 +62,7 @@
      * @throws NotImplementedError when [Context] is not an [UiContext] or this method has no
      * supporting implementation.
      */
+    @ExperimentalWindowApi
     fun windowLayoutInfo(@UiContext context: Context): Flow<WindowLayoutInfo> {
         val windowLayoutInfoFlow: Flow<WindowLayoutInfo>? = windowLayoutInfo((context as Activity))
         return windowLayoutInfoFlow
diff --git a/window/window/src/main/java/androidx/window/layout/WindowInfoTrackerImpl.kt b/window/window/src/main/java/androidx/window/layout/WindowInfoTrackerImpl.kt
index 0796437..2247c4b 100644
--- a/window/window/src/main/java/androidx/window/layout/WindowInfoTrackerImpl.kt
+++ b/window/window/src/main/java/androidx/window/layout/WindowInfoTrackerImpl.kt
@@ -20,6 +20,7 @@
 import android.content.Context
 import androidx.annotation.UiContext
 import androidx.core.util.Consumer
+import androidx.window.core.ExperimentalWindowApi
 import androidx.window.layout.adapter.WindowBackend
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
@@ -41,6 +42,7 @@
      * A [Flow] of window layout changes in the current visual [UiContext]. A context has to be
      * either an [Activity] or created with [Context#createWindowContext].
      */
+    @ExperimentalWindowApi
     override fun windowLayoutInfo(@UiContext context: Context): Flow<WindowLayoutInfo> {
         return callbackFlow {
             val listener = Consumer { info: WindowLayoutInfo -> trySend(info) }
diff --git a/window/window/src/main/java/androidx/window/reflection/ReflectionUtils.kt b/window/window/src/main/java/androidx/window/reflection/ReflectionUtils.kt
new file mode 100644
index 0000000..326486e
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/reflection/ReflectionUtils.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 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 androidx.window.reflection
+
+import android.util.Log
+import java.lang.reflect.Method
+import java.lang.reflect.Modifier
+import kotlin.reflect.KClass
+
+/**
+ * Utility class used for reflection guard for WindowExtensions classes' validation
+ */
+internal object ReflectionUtils {
+
+    internal fun checkIsPresent(classLoader: () -> Class<*>): Boolean {
+        return try {
+            classLoader()
+            true
+        } catch (noClass: ClassNotFoundException) {
+            false
+        } catch (noDefinition: NoClassDefFoundError) {
+            false
+        }
+    }
+
+    /**
+     * Validates the code block normally for reflection. If there are [ClassNotFoundException]
+     * or [NoSuchMethodException] thrown, validation will fail.
+     * Otherwise will return the validation result from the [block]
+     */
+    @JvmStatic
+    internal fun validateReflection(errorMessage: String? = null, block: () -> Boolean): Boolean {
+        return try {
+            val result = block()
+            if (!result && errorMessage != null) {
+                Log.e("ReflectionGuard", errorMessage)
+            }
+            result
+        } catch (noClass: ClassNotFoundException) {
+            Log.e("ReflectionGuard", "ClassNotFound: ${errorMessage.orEmpty()}")
+            false
+        } catch (noMethod: NoSuchMethodException) {
+            Log.e("ReflectionGuard", "NoSuchMethod: ${errorMessage.orEmpty()}")
+            false
+        }
+    }
+
+    /**
+     * Checks if a method has public modifier
+     */
+    internal val Method.isPublic: Boolean
+        get() {
+            return Modifier.isPublic(modifiers)
+        }
+
+    /**
+     * Checks if a method's return value is type of kotlin [clazz]
+     */
+    internal fun Method.doesReturn(clazz: KClass<*>): Boolean {
+        return doesReturn(clazz.java)
+    }
+
+    /**
+     * Checks if a method's return value is type of java [clazz]
+     */
+    internal fun Method.doesReturn(clazz: Class<*>): Boolean {
+        return returnType.equals(clazz)
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/reflection/WindowExtensionsConstants.kt b/window/window/src/main/java/androidx/window/reflection/WindowExtensionsConstants.kt
new file mode 100644
index 0000000..341e019
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/reflection/WindowExtensionsConstants.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2023 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 androidx.window.reflection
+
+/**
+ * Constants for WindowExtensions
+ */
+internal object WindowExtensionsConstants {
+    /**
+     * Constant name for package [androidx.window.extensions]
+     */
+    private const val WINDOW_EXTENSIONS_PACKAGE_NAME = "androidx.window.extensions"
+
+    /**
+     * Constant name for class [androidx.window.extensions.WindowExtensionsProvider] used
+     * for reflection
+     */
+    internal const val WINDOW_EXTENSIONS_PROVIDER_CLASS =
+        "$WINDOW_EXTENSIONS_PACKAGE_NAME.WindowExtensionsProvider"
+
+    /**
+     * Constant name for class [androidx.window.extensions.WindowExtensions] used for reflection
+     */
+    internal const val WINDOW_EXTENSIONS_CLASS =
+        "$WINDOW_EXTENSIONS_PACKAGE_NAME.WindowExtensions"
+
+    /**
+     * Constant name for class [androidx.window.extensions.layout.FoldingFeature]
+     * used for reflection
+     */
+    internal const val FOLDING_FEATURE_CLASS =
+        "$WINDOW_EXTENSIONS_PACKAGE_NAME.layout.FoldingFeature"
+
+    /**
+     * Constant name for class [androidx.window.extensions.layout.WindowLayoutComponent]
+     * used for reflection
+     */
+    internal const val WINDOW_LAYOUT_COMPONENT_CLASS =
+        "$WINDOW_EXTENSIONS_PACKAGE_NAME.layout.WindowLayoutComponent"
+
+    /**
+     * Constant name for class [androidx.window.extensions.embedding.ActivityEmbeddingComponent]
+     * used for reflection
+     */
+    internal const val ACTIVITY_EMBEDDING_COMPONENT_CLASS =
+        "$WINDOW_EXTENSIONS_PACKAGE_NAME.embedding.ActivityEmbeddingComponent"
+
+    /**
+     * Constant name for class [androidx.window.extensions.core.util.function]
+     * used for reflection
+     */
+    internal const val WINDOW_CONSUMER =
+        "$WINDOW_EXTENSIONS_PACKAGE_NAME.core.util.function.Consumer"
+
+    /**
+     * Constant name for class [java.util.function.Consumer]
+     * used for reflection
+     */
+    internal const val JAVA_CONSUMER = "java.util.function.Consumer"
+}
diff --git a/window/window/src/main/res/values/attrs.xml b/window/window/src/main/res/values/attrs.xml
index 8ee9802..a2880ca 100644
--- a/window/window/src/main/res/values/attrs.xml
+++ b/window/window/src/main/res/values/attrs.xml
@@ -47,8 +47,9 @@
     <attr name="tag" format="string" />
     <!-- An attribute for Activity Embedding rules.
          Background color of Activity Embedding window animation if the animation requires a
-         background.
-         The default is to use the theme's windowBackground. -->
+         background. Only opaque color is supported.
+         The default is to use the current theme's windowBackground. Any non-opaque color will be
+         treated the same as default. -->
     <attr name="animationBackgroundColor" format="color" />
 
     <!-- An attribute for Activity Embedding rules.
diff --git a/window/window/src/test/java/androidx/window/area/WindowAreaAdapterUnitTest.kt b/window/window/src/test/java/androidx/window/area/WindowAreaAdapterUnitTest.kt
new file mode 100644
index 0000000..89a9808
--- /dev/null
+++ b/window/window/src/test/java/androidx/window/area/WindowAreaAdapterUnitTest.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+import org.junit.Test
+
+/**
+ * Unit tests for [WindowAreaAdapter] that run on the JVM.
+ */
+@OptIn(ExperimentalWindowApi::class)
+class WindowAreaAdapterUnitTest {
+
+    @Test
+    fun testWindowAreaStatusTranslateValueAvailable() {
+        val expected = WindowAreaStatus.AVAILABLE
+        val translateValue = WindowAreaAdapter.translate(WindowAreaComponent.STATUS_AVAILABLE)
+        assert(expected == translateValue)
+    }
+
+    @Test
+    fun testWindowAreaStatusTranslateValueUnavailable() {
+        val expected = WindowAreaStatus.UNAVAILABLE
+        val translateValue = WindowAreaAdapter.translate(WindowAreaComponent.STATUS_UNAVAILABLE)
+        assert(expected == translateValue)
+    }
+
+    @Test
+    fun testWindowAreaStatusTranslateValueUnsupported() {
+        val expected = WindowAreaStatus.UNSUPPORTED
+        val translateValue = WindowAreaAdapter.translate(WindowAreaComponent.STATUS_UNSUPPORTED)
+        assert(expected == translateValue)
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/test/java/androidx/window/embedding/EmbeddingAspectRatioTest.kt b/window/window/src/test/java/androidx/window/embedding/EmbeddingAspectRatioTest.kt
new file mode 100644
index 0000000..fc5fb0c
--- /dev/null
+++ b/window/window/src/test/java/androidx/window/embedding/EmbeddingAspectRatioTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2023 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 androidx.window.embedding
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertThrows
+import org.junit.Test
+
+/**
+ * The unit tests for [EmbeddingAspectRatio].
+ */
+class EmbeddingAspectRatioTest {
+
+    @Test
+    fun testRatio() {
+        // ratio must > 1.
+        assertThrows(IllegalArgumentException::class.java) {
+            EmbeddingAspectRatio.ratio(0f)
+        }
+        assertThrows(IllegalArgumentException::class.java) {
+            EmbeddingAspectRatio.ratio(1f)
+        }
+
+        // test equals and value.
+        assertEquals(EmbeddingAspectRatio.ratio(1.1f), EmbeddingAspectRatio.ratio(1.1f))
+        assertEquals(1.1f, EmbeddingAspectRatio.ratio(1.1f).value)
+    }
+
+    @Test
+    fun testAlwaysAllow() {
+        assertEquals(0f, EmbeddingAspectRatio.ALWAYS_ALLOW.value)
+    }
+
+    @Test
+    fun testAlwaysDisallow() {
+        assertEquals(-1f, EmbeddingAspectRatio.ALWAYS_DISALLOW.value)
+    }
+
+    @Test
+    fun testBuildAspectRatioFromValue() {
+        assertEquals(
+            EmbeddingAspectRatio.ALWAYS_ALLOW,
+            EmbeddingAspectRatio.buildAspectRatioFromValue(0f)
+        )
+        assertEquals(
+            EmbeddingAspectRatio.ALWAYS_DISALLOW,
+            EmbeddingAspectRatio.buildAspectRatioFromValue(-1f)
+        )
+        assertEquals(
+            EmbeddingAspectRatio.ratio(1.1f),
+            EmbeddingAspectRatio.buildAspectRatioFromValue(1.1f)
+        )
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/test/java/androidx/window/reflection/ReflectionUtilsTest.kt b/window/window/src/test/java/androidx/window/reflection/ReflectionUtilsTest.kt
new file mode 100644
index 0000000..bdab6f7
--- /dev/null
+++ b/window/window/src/test/java/androidx/window/reflection/ReflectionUtilsTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2023 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 androidx.window.reflection
+
+import androidx.window.reflection.ReflectionUtils.doesReturn
+import androidx.window.reflection.ReflectionUtils.isPublic
+import androidx.window.reflection.ReflectionUtils.validateReflection
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+
+/**
+ * Unit test for reflection utilities
+ */
+class ReflectionUtilsTest {
+
+    private lateinit var classLoader: ClassLoader
+
+    @Before
+    fun setup() {
+        classLoader = this::class.java.classLoader!!
+    }
+
+    @Test
+    fun testValidateReflectionSuccess() {
+        val result = validateReflection {
+            true
+        }
+        assertTrue(result)
+    }
+
+    @Test
+    fun testValidateReflectionFail() {
+        val result = validateReflection {
+            classLoader.loadClass("SomeUnExistedClass.java")
+            true
+        }
+        assertFalse(result)
+    }
+
+    @Test
+    fun testMethodModifier() {
+        val result = validateReflection {
+            val testClass = this::class.java
+            val privateMethod = testClass.getDeclaredMethod("testMethod").isPublic
+            assertFalse(privateMethod)
+            val publicMethod = testClass.getDeclaredMethod("testMethodModifier").isPublic
+            assertTrue(publicMethod)
+            true
+        }
+        assertTrue(result)
+    }
+
+    @Test
+    fun testDoesReturn() {
+        val result = validateReflection {
+            val testClass = this::class.java
+            val privateMethod = testClass.getDeclaredMethod("testMethod")
+            assertTrue(privateMethod.doesReturn(Int::class.java))
+            assertTrue(privateMethod.doesReturn(Int::class))
+            assertFalse(privateMethod.doesReturn(Any::class.java))
+            assertFalse(privateMethod.doesReturn(Any::class))
+            true
+        }
+        assertTrue(result)
+    }
+
+    // method for testing
+    @Suppress("unused")
+    private fun testMethod(): Int {
+        return 0
+    }
+}
\ No newline at end of file
diff --git a/work/work-lint/src/main/java/androidx/work/lint/WorkManagerIssueRegistry.kt b/work/work-lint/src/main/java/androidx/work/lint/WorkManagerIssueRegistry.kt
index ac9972b..28e0e2f 100644
--- a/work/work-lint/src/main/java/androidx/work/lint/WorkManagerIssueRegistry.kt
+++ b/work/work-lint/src/main/java/androidx/work/lint/WorkManagerIssueRegistry.kt
@@ -25,7 +25,7 @@
 
 class WorkManagerIssueRegistry : IssueRegistry() {
     override val minApi = CURRENT_API
-    override val api = 14
+    override val api = 13
     override val issues: List<Issue> = listOf(
         BadConfigurationProviderIssueDetector.ISSUE,
         IdleBatteryChargingConstraintsDetector.ISSUE,
diff --git a/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerRealExecutorTest.kt b/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerRealExecutorTest.kt
index 848dd44..78b5732 100644
--- a/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerRealExecutorTest.kt
+++ b/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerRealExecutorTest.kt
@@ -29,8 +29,10 @@
 import androidx.work.OneTimeWorkRequestBuilder
 import androidx.work.PeriodicWorkRequestBuilder
 import androidx.work.WorkInfo
+import androidx.work.WorkInfo.State.ENQUEUED
 import androidx.work.impl.WorkManagerImpl
 import androidx.work.impl.model.WorkSpec
+import androidx.work.impl.utils.taskexecutor.SerialExecutor
 import androidx.work.testing.workers.CountingTestWorker
 import androidx.work.testing.workers.RetryWorker
 import androidx.work.testing.workers.TestWorker
@@ -81,13 +83,14 @@
         // TODO: specifically removing deduplication for periodic workers
         // so runs aren't dedupped. We need periodicity data in workinfo
         val workInfo = wm.workDatabase.workSpecDao().getWorkStatusPojoLiveDataForIds(
-            listOf("${request.id}"))
+            listOf("${request.id}")
+        )
         var expectedCounter = 1
         val maxCount = 5
         handler.post {
             workInfo.observeForever {
                 val info = it.first()
-                val isEnqueued = info.state == WorkInfo.State.ENQUEUED
+                val isEnqueued = info.state == ENQUEUED
                 val counter = CountingTestWorker.COUNT.get()
                 if (isEnqueued && counter == maxCount) {
                     periodicLatch.countDown()
@@ -107,6 +110,10 @@
         wm.enqueue(request).result.get()
         driver.setInitialDelayMet(request.id)
         awaitPeriodicRunOnce(request.id)
+        driver.setPeriodDelayMet(request.id)
+        awaitCondition(request.id) {
+            it.state == WorkInfo.State.ENQUEUED && CountingTestWorker.COUNT.get() == 2
+        }
     }
 
     @Test
@@ -160,6 +167,30 @@
     }
 
     @Test
+    fun testSetAllConstraintsDontTriggerSecondRun() {
+        val request = PeriodicWorkRequestBuilder<CountingTestWorker>(10, TimeUnit.DAYS)
+            .setConstraints(Constraints(requiresCharging = true)).build()
+        wm.enqueue(request).result.get()
+        val latch = CountDownLatch(1)
+        wm.workTaskExecutor.serialTaskExecutor.execute {
+            latch.await()
+        }
+        // double call to setAllConstraint. It shouldn't lead to double execution of worker.
+        // It should run once, but second time it shouldn't run because "setPeriodDelayMet" wasn't
+        // called.
+        driver.setAllConstraintsMet(request.id)
+        driver.setAllConstraintsMet(request.id)
+        latch.countDown()
+        awaitCondition(request.id) {
+            it.state == ENQUEUED && CountingTestWorker.COUNT.get() > 0
+        }
+
+        drainSerialExecutor()
+        assertThat(wm.getWorkInfoById(request.id).get().state).isEqualTo(ENQUEUED)
+        assertThat(CountingTestWorker.COUNT.get()).isEqualTo(1)
+    }
+
+    @Test
     fun testOneTimeWorkerRetry() {
         val request = OneTimeWorkRequest.from(RetryWorker::class.java)
         wm.enqueue(request).result.get()
@@ -176,11 +207,11 @@
     private fun awaitSuccess(id: UUID) = awaitCondition(id) { it.state == WorkInfo.State.SUCCEEDED }
 
     private fun awaitPeriodicRunOnce(id: UUID) = awaitCondition(id) {
-        it.state == WorkInfo.State.ENQUEUED && CountingTestWorker.COUNT.get() == 1
+        it.state == ENQUEUED && CountingTestWorker.COUNT.get() == 1
     }
 
     private fun awaitReenqueuedAfterRetry(id: UUID) = awaitCondition(id) {
-        it.state == WorkInfo.State.ENQUEUED && it.runAttemptCount == 1
+        it.state == ENQUEUED && it.runAttemptCount == 1
     }
 
     private fun awaitCondition(id: UUID, predicate: (WorkSpec.WorkInfoPojo) -> Boolean) {
@@ -198,4 +229,22 @@
         }
         assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue()
     }
+
+    private fun drainSerialExecutor() {
+        val latch = CountDownLatch(1)
+
+        class DrainTask(val executor: SerialExecutor) : Runnable {
+            override fun run() {
+                if (executor.hasPendingTasks()) {
+                    executor.execute(this)
+                } else {
+                    latch.countDown()
+                }
+            }
+        }
+
+        val executor = wm.workTaskExecutor.serialTaskExecutor
+        executor.execute(DrainTask(executor))
+        latch.await()
+    }
 }
\ No newline at end of file
diff --git a/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java b/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
index 83f6878..2e44ffd 100644
--- a/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
+++ b/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
@@ -198,6 +198,8 @@
         assertThat(CountingTestWorker.COUNT.get(), is(0));
         mTestDriver.setInitialDelayMet(request.getId());
         assertThat(CountingTestWorker.COUNT.get(), is(1));
+        mTestDriver.setPeriodDelayMet(request.getId());
+        assertThat(CountingTestWorker.COUNT.get(), is(2));
     }
 
     @Test
diff --git a/work/work-testing/src/main/java/androidx/work/testing/TestScheduler.kt b/work/work-testing/src/main/java/androidx/work/testing/TestScheduler.kt
index 7369589..84d9918 100644
--- a/work/work-testing/src/main/java/androidx/work/testing/TestScheduler.kt
+++ b/work/work-testing/src/main/java/androidx/work/testing/TestScheduler.kt
@@ -23,7 +23,6 @@
 import androidx.work.impl.StartStopTokens
 import androidx.work.impl.WorkDatabase
 import androidx.work.impl.WorkManagerImpl
-import androidx.work.impl.model.WorkGenerationalId
 import androidx.work.impl.model.WorkSpec
 import androidx.work.impl.model.WorkSpecDao
 import androidx.work.impl.model.generationalId
@@ -52,25 +51,19 @@
         val toSchedule = mutableMapOf<WorkSpec, InternalWorkState>()
         synchronized(lock) {
             workSpecs.forEach {
-                val state = pendingWorkStates.getOrPut(it.generationalId().workSpecId) {
-                    InternalWorkState(it, true)
-                }
-                toSchedule[it] = state.copy(isScheduled = true)
+                val oldState = pendingWorkStates[it.id] ?: InternalWorkState()
+                val state = oldState.copy(isScheduled = true)
+                pendingWorkStates[it.id] = state
+                toSchedule[it] = state
             }
         }
-        toSchedule.forEach { (originalSpec, state) ->
-            // this spec is attempted to run for the first time
-            // so we have to rewind the time, because we have to override flex.
-            val spec = if (originalSpec.isPeriodic && state.periodDelayMet) {
-                workManagerImpl.rewindLastEnqueueTime(originalSpec.id)
-            } else originalSpec
+        toSchedule.forEach { (spec, state) ->
             // don't even try to run a worker that WorkerWrapper won't execute anyway.
             // similar to logic in WorkerWrapper
-            if ((spec.isPeriodic || spec.isBackedOff) &&
-                (spec.calculateNextRunTime() > System.currentTimeMillis())) {
+            if (spec.isBackedOff && spec.calculateNextRunTime() > System.currentTimeMillis()) {
                 return@forEach
             }
-            scheduleInternal(spec.generationalId(), state)
+            scheduleInternal(spec, state)
         }
     }
 
@@ -95,11 +88,11 @@
         val spec = loadSpec(id)
         val state: InternalWorkState
         synchronized(lock) {
-            val oldState = pendingWorkStates[id] ?: InternalWorkState(spec, false)
+            val oldState = pendingWorkStates[id] ?: InternalWorkState(initialDelayMet = false)
             state = oldState.copy(constraintsMet = true)
             pendingWorkStates[id] = state
         }
-        scheduleInternal(WorkGenerationalId(id, state.generation), state)
+        scheduleInternal(spec, state)
     }
 
     /**
@@ -114,12 +107,11 @@
         val state: InternalWorkState
         val spec = loadSpec(id)
         synchronized(lock) {
-            val oldState = pendingWorkStates[id] ?: InternalWorkState(spec, false)
+            val oldState = pendingWorkStates[id] ?: InternalWorkState()
             state = oldState.copy(initialDelayMet = true)
             pendingWorkStates[id] = state
         }
-        workManagerImpl.rewindLastEnqueueTime(id)
-        scheduleInternal(WorkGenerationalId(id, state.generation), state)
+        scheduleInternal(spec, state)
     }
 
     /**
@@ -136,20 +128,21 @@
 
         val state: InternalWorkState
         synchronized(lock) {
-            val oldState = pendingWorkStates[id] ?: InternalWorkState(spec, false)
+            val oldState = pendingWorkStates[id] ?: InternalWorkState()
             state = oldState.copy(periodDelayMet = true)
             pendingWorkStates[id] = state
         }
-        workManagerImpl.rewindLastEnqueueTime(id)
-        scheduleInternal(WorkGenerationalId(id, state.generation), state)
+        scheduleInternal(spec, state)
     }
 
-    private fun scheduleInternal(generationalId: WorkGenerationalId, state: InternalWorkState) {
-        if (state.isRunnable) {
+    private fun scheduleInternal(spec: WorkSpec, state: InternalWorkState) {
+        val generationalId = spec.generationalId()
+        if (isRunnable(spec, state)) {
             val token = synchronized(lock) {
                 pendingWorkStates.remove(generationalId.workSpecId)
                 startStopTokens.tokenFor(generationalId)
             }
+            workManagerImpl.rewindLastEnqueueTime(spec.id)
             workManagerImpl.startWork(token)
         }
     }
@@ -162,29 +155,21 @@
 }
 
 internal data class InternalWorkState(
-    val generation: Int,
-    val constraintsMet: Boolean,
-    val initialDelayMet: Boolean,
-    val periodDelayMet: Boolean,
-    val hasConstraints: Boolean,
-    val isPeriodic: Boolean,
+    val constraintsMet: Boolean = false,
+    val initialDelayMet: Boolean = false,
+    val periodDelayMet: Boolean = false,
     /* means that TestScheduler received this workrequest in schedule(....) function */
-    val isScheduled: Boolean
+    val isScheduled: Boolean = false,
 )
 
-internal val InternalWorkState.isRunnable: Boolean
-    get() = constraintsMet && initialDelayMet && periodDelayMet && isScheduled
+internal fun isRunnable(spec: WorkSpec, state: InternalWorkState): Boolean {
+    val constraints = !spec.hasConstraints() || state.constraintsMet
+    val initialDelay = spec.initialDelay == 0L || state.initialDelayMet || !spec.isFirstPeriodicRun
+    val periodic = if (spec.isPeriodic) (state.periodDelayMet || spec.isFirstPeriodicRun) else true
+    return state.isScheduled && constraints && periodic && initialDelay
+}
 
-internal fun InternalWorkState(spec: WorkSpec, isScheduled: Boolean): InternalWorkState =
-    InternalWorkState(
-        generation = spec.generation,
-        constraintsMet = !spec.hasConstraints(),
-        initialDelayMet = spec.initialDelay == 0L,
-        periodDelayMet = spec.periodCount == 0 && spec.runAttemptCount == 0,
-        hasConstraints = spec.hasConstraints(),
-        isPeriodic = spec.isPeriodic,
-        isScheduled = isScheduled,
-    )
+private val WorkSpec.isFirstPeriodicRun get() = periodCount == 0 && runAttemptCount == 0
 
 private fun WorkManagerImpl.rewindLastEnqueueTime(id: String): WorkSpec {
     // We need to pass check that mWorkSpec.calculateNextRunTime() < now