Merge "Update SelectableButton to RadioButton, combining the earlier SelectableButton and radio control." into androidx-main
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index ed0d2fe..ba2a326 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -250,11 +250,11 @@
 
   public abstract class ActivityResultLauncher<I> {
     ctor public ActivityResultLauncher();
-    method public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object!> getContract();
+    method public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object?> getContract();
     method public void launch(I input);
     method public abstract void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
     method @MainThread public abstract void unregister();
-    property public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object!> contract;
+    property public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object?> contract;
   }
 
   public final class ActivityResultLauncherKt {
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index c5dda21..8f087e4 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -249,11 +249,11 @@
 
   public abstract class ActivityResultLauncher<I> {
     ctor public ActivityResultLauncher();
-    method public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object!> getContract();
+    method public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object?> getContract();
     method public void launch(I input);
     method public abstract void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
     method @MainThread public abstract void unregister();
-    property public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object!> contract;
+    property public abstract androidx.activity.result.contract.ActivityResultContract<I,? extends java.lang.Object?> contract;
   }
 
   public final class ActivityResultLauncherKt {
diff --git a/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/RegressionTestJava313686921.java b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/RegressionTestJava313686921.java
index c944de7..aa19a43 100644
--- a/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/RegressionTestJava313686921.java
+++ b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/RegressionTestJava313686921.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,8 +27,7 @@
     /**
      * Unsafe usage due to the experimental annotation on the annotation
      */
-    public Object unsafeAnnotatedAnnotationUsageOnParam(@AnnotatedJavaAnnotation Object param) {
-        return param;
+    public void unsafeAnnotatedAnnotationUsageOnParam(@AnnotatedJavaAnnotation Object param) {
     }
 
     /**
diff --git a/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/RegressionTestJava344616929.java b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/RegressionTestJava344616929.java
new file mode 100644
index 0000000..cf7239a
--- /dev/null
+++ b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/RegressionTestJava344616929.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.optin;
+
+import android.annotation.SuppressLint;
+
+import androidx.annotation.OptIn;
+
+/** @noinspection unused*/
+@SuppressLint("UnknownNullness")
+public class RegressionTestJava344616929 {
+    @ExperimentalJavaAnnotation
+    public @interface AnnotatedJavaAnnotation {}
+
+    /**
+     * Safe usage due to the opt-in annotation
+     */
+    @OptIn(markerClass = ExperimentalJavaAnnotation.class)
+    public Object safeAnnotatedAnnotationUsageOnParam(@AnnotatedJavaAnnotation Object param) {
+        return param;
+    }
+
+    /**
+     * Safe usage due to the opt-in annotation
+     */
+    @OptIn(markerClass = ExperimentalJavaAnnotation.class)
+    @AnnotatedJavaAnnotation
+    public Object safeAnnotatedAnnotationUsageOnMethod(Object param) {
+        return param;
+    }
+
+    void usage() {
+        safeAnnotatedAnnotationUsageOnMethod("param");
+    }
+
+    @AnnotatedJavaAnnotation
+    static class UnsafeAnnotatedAnnotationUsageOnClass {}
+}
diff --git a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
index a3e960e..635afda 100644
--- a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
+++ b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
@@ -576,7 +576,7 @@
         annotationFqName: String,
     ): Boolean {
         // Is the element itself experimental?
-        if (isDeclarationAnnotatedWith(context.evaluator, annotationFqName)) {
+        if (isDeclarationAnnotatedWith(annotationFqName)) {
             return true
         }
 
@@ -596,10 +596,7 @@
         // which is landed on the backing field if any
         if (sourcePsi is KtProperty && this is UMethod) {
             val backingField = (uastParent as? UClass)?.fields?.find { it.sourcePsi == sourcePsi }
-            if (
-                backingField?.isDeclarationAnnotatedWith(context.evaluator, annotationFqName) ==
-                    true
-            ) {
+            if (backingField?.isDeclarationAnnotatedWith(annotationFqName) == true) {
                 return true
             }
         }
@@ -624,7 +621,7 @@
         return config.getOption(ISSUE_ERROR, "opt-in")?.contains(annotationFqName) == true ||
             config.getOption(ISSUE_WARNING, "opt-in")?.contains(annotationFqName) == true ||
             anyParentMatches({ element ->
-                element.isDeclarationAnnotatedWith(context.evaluator, annotationFqName) ||
+                element.isDeclarationAnnotatedWith(annotationFqName) ||
                     element.isDeclarationAnnotatedWithOptInOf(annotationFqName, optInFqNames)
             }) ||
             context.evaluator.getPackage(this)?.let { element ->
@@ -900,23 +897,13 @@
         }
     }
 
-/**
- * Returns whether the element declaration is annotated with the specified annotation or annotated
- * with annotation that is annotated with the specified annotation
- */
+/** Returns whether the element declaration is annotated with the specified annotation */
 private fun UElement.isDeclarationAnnotatedWith(
-    evaluator: JavaEvaluator,
     annotationFqName: String,
 ): Boolean {
     return (this as? UAnnotated)?.uAnnotations?.firstOrNull { uAnnotation ->
         // Directly annotated
-        if (uAnnotation.qualifiedName == annotationFqName) return@firstOrNull true
-
-        // Annotated with an annotation that is annotated with the specified annotation
-        val cls = uAnnotation.resolve()
-        if (cls == null || !cls.isAnnotationType) return@firstOrNull false
-        val metaAnnotations = evaluator.getAllAnnotations(cls, inHierarchy = false)
-        metaAnnotations.find { it.qualifiedName == annotationFqName } != null
+        uAnnotation.qualifiedName == annotationFqName
     } != null
 }
 
diff --git a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt
index 7c97b58..5af3222 100644
--- a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt
+++ b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt
@@ -23,6 +23,7 @@
 import com.android.tools.lint.checks.infrastructure.TestFiles.kotlin
 import com.android.tools.lint.checks.infrastructure.TestLintResult
 import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
@@ -560,6 +561,7 @@
      * experimentally-annotated annotations.
      */
     @Test
+    @Ignore("b/313686921")
     fun regressionTestJava313686921() {
         val input =
             arrayOf(
@@ -587,6 +589,7 @@
      * experimentally-annotated annotations.
      */
     @Test
+    @Ignore("b/313686921")
     fun regressionTestKotlin313686921() {
         val input =
             arrayOf(
@@ -606,6 +609,18 @@
         check(*input).expect(expected)
     }
 
+    /** Regression test for b/344616929 that shows where to put @OptIn: use-site! */
+    @Test
+    @Ignore("b/313686921")
+    fun regressionTestJava344616929() {
+        val input =
+            arrayOf(
+                javaSample("sample.optin.ExperimentalJavaAnnotation"),
+                javaSample("sample.optin.RegressionTestJava344616929")
+            )
+        check(*input).expectClean()
+    }
+
     companion object {
         /**
          * [TestFile] containing RequiresOptIn.kt from the experimental annotation library.
diff --git a/benchmark/benchmark-common/api/1.3.0-beta01.txt b/benchmark/benchmark-common/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..9df6fae
--- /dev/null
+++ b/benchmark/benchmark-common/api/1.3.0-beta01.txt
@@ -0,0 +1,139 @@
+// Signature format: 4.0
+package androidx.benchmark {
+
+  public final class BenchmarkState {
+    ctor @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkStateApi public BenchmarkState(optional Integer? warmupCount, optional Integer? repeatCount);
+    method @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkStateApi public java.util.List<java.lang.Double> getMeasurementTimeNs();
+    method public boolean keepRunning();
+    method public void pauseTiming();
+    method @SuppressCompatibility @androidx.benchmark.BenchmarkState.Companion.ExperimentalExternalReport public static void reportData(String className, String testName, @IntRange(from=0L) long totalRunTimeNs, java.util.List<java.lang.Long> dataNs, @IntRange(from=0L) int warmupIterations, @IntRange(from=0L) long thermalThrottleSleepSeconds, @IntRange(from=1L) int repeatIterations);
+    method public void resumeTiming();
+    field public static final androidx.benchmark.BenchmarkState.Companion Companion;
+  }
+
+  public static final class BenchmarkState.Companion {
+    method @SuppressCompatibility @androidx.benchmark.BenchmarkState.Companion.ExperimentalExternalReport public void reportData(String className, String testName, @IntRange(from=0L) long totalRunTimeNs, java.util.List<java.lang.Long> dataNs, @IntRange(from=0L) int warmupIterations, @IntRange(from=0L) long thermalThrottleSleepSeconds, @IntRange(from=1L) int repeatIterations);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public static @interface BenchmarkState.Companion.ExperimentalExternalReport {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBlackHoleApi public final class BlackHole {
+    method public static void consume(boolean value);
+    method public static void consume(byte value);
+    method public static void consume(char value);
+    method public static void consume(double value);
+    method public static void consume(float value);
+    method public static void consume(int value);
+    method public static void consume(Object value);
+    method public static void consume(long value);
+    method public static void consume(short value);
+    field public static final androidx.benchmark.BlackHole INSTANCE;
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalBenchmarkConfigApi {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalBenchmarkStateApi {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalBlackHoleApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public abstract class MetricCapture {
+    ctor public MetricCapture(java.util.List<java.lang.String> names);
+    method public abstract void capturePaused();
+    method public abstract void captureResumed();
+    method public abstract void captureStart(long timeNs);
+    method public abstract void captureStop(long timeNs, long[] output, int offset);
+    method public final java.util.List<java.lang.String> getNames();
+    property public final java.util.List<java.lang.String> names;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public final class MicrobenchmarkConfig {
+    ctor public MicrobenchmarkConfig(optional java.util.List<? extends androidx.benchmark.MetricCapture> metrics, optional boolean traceAppTagEnabled, optional boolean perfettoSdkTracingEnabled, optional androidx.benchmark.ProfilerConfig? profiler);
+    method public java.util.List<androidx.benchmark.MetricCapture> getMetrics();
+    method public androidx.benchmark.ProfilerConfig? getProfiler();
+    method public boolean isPerfettoSdkTracingEnabled();
+    method public boolean isTraceAppTagEnabled();
+    property public final java.util.List<androidx.benchmark.MetricCapture> metrics;
+    property public final boolean perfettoSdkTracingEnabled;
+    property public final androidx.benchmark.ProfilerConfig? profiler;
+    property public final boolean traceAppTagEnabled;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public abstract sealed class ProfilerConfig {
+  }
+
+  public static final class ProfilerConfig.MethodTracing extends androidx.benchmark.ProfilerConfig {
+    ctor public ProfilerConfig.MethodTracing();
+    field public static final boolean AFFECTS_MEASUREMENTS_ON_THIS_DEVICE;
+    field public static final androidx.benchmark.ProfilerConfig.MethodTracing.Companion Companion;
+  }
+
+  public static final class ProfilerConfig.MethodTracing.Companion {
+  }
+
+  public static final class ProfilerConfig.StackSampling extends androidx.benchmark.ProfilerConfig {
+    ctor public ProfilerConfig.StackSampling();
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public final class TimeCapture extends androidx.benchmark.MetricCapture {
+    ctor public TimeCapture();
+    ctor public TimeCapture(optional String name);
+    method public void capturePaused();
+    method public void captureResumed();
+    method public void captureStart(long timeNs);
+    method public void captureStop(long timeNs, long[] output, int offset);
+  }
+
+}
+
+package androidx.benchmark.perfetto {
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalPerfettoCaptureApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public abstract sealed class PerfettoConfig {
+  }
+
+  public static final class PerfettoConfig.Binary extends androidx.benchmark.perfetto.PerfettoConfig {
+    ctor public PerfettoConfig.Binary(byte[] bytes);
+    method public byte[] getBytes();
+    property public final byte[] bytes;
+  }
+
+  public static final class PerfettoConfig.Text extends androidx.benchmark.perfetto.PerfettoConfig {
+    ctor public PerfettoConfig.Text(String text);
+    method public String getText();
+    property public final String text;
+  }
+
+  @SuppressCompatibility @RequiresApi(23) @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public final class PerfettoTrace {
+    ctor public PerfettoTrace(String path);
+    method public String getPath();
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    property public final String path;
+    field public static final androidx.benchmark.perfetto.PerfettoTrace.Companion Companion;
+  }
+
+  public static final class PerfettoTrace.Companion {
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+  }
+
+}
+
diff --git a/benchmark/benchmark-common/api/res-1.3.0-beta01.txt b/benchmark/benchmark-common/api/res-1.3.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/benchmark/benchmark-common/api/res-1.3.0-beta01.txt
diff --git a/benchmark/benchmark-common/api/restricted_1.3.0-beta01.txt b/benchmark/benchmark-common/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..e2bfb40
--- /dev/null
+++ b/benchmark/benchmark-common/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,141 @@
+// Signature format: 4.0
+package androidx.benchmark {
+
+  public final class BenchmarkState {
+    ctor @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkStateApi public BenchmarkState(optional Integer? warmupCount, optional Integer? repeatCount);
+    method @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkStateApi public java.util.List<java.lang.Double> getMeasurementTimeNs();
+    method public boolean keepRunning();
+    method @kotlin.PublishedApi internal boolean keepRunningInternal();
+    method public void pauseTiming();
+    method @SuppressCompatibility @androidx.benchmark.BenchmarkState.Companion.ExperimentalExternalReport public static void reportData(String className, String testName, @IntRange(from=0L) long totalRunTimeNs, java.util.List<java.lang.Long> dataNs, @IntRange(from=0L) int warmupIterations, @IntRange(from=0L) long thermalThrottleSleepSeconds, @IntRange(from=1L) int repeatIterations);
+    method public void resumeTiming();
+    field public static final androidx.benchmark.BenchmarkState.Companion Companion;
+    field @kotlin.PublishedApi internal int iterationsRemaining;
+  }
+
+  public static final class BenchmarkState.Companion {
+    method @SuppressCompatibility @androidx.benchmark.BenchmarkState.Companion.ExperimentalExternalReport public void reportData(String className, String testName, @IntRange(from=0L) long totalRunTimeNs, java.util.List<java.lang.Long> dataNs, @IntRange(from=0L) int warmupIterations, @IntRange(from=0L) long thermalThrottleSleepSeconds, @IntRange(from=1L) int repeatIterations);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public static @interface BenchmarkState.Companion.ExperimentalExternalReport {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBlackHoleApi public final class BlackHole {
+    method public static void consume(boolean value);
+    method public static void consume(byte value);
+    method public static void consume(char value);
+    method public static void consume(double value);
+    method public static void consume(float value);
+    method public static void consume(int value);
+    method public static void consume(Object value);
+    method public static void consume(long value);
+    method public static void consume(short value);
+    field public static final androidx.benchmark.BlackHole INSTANCE;
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalBenchmarkConfigApi {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalBenchmarkStateApi {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalBlackHoleApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public abstract class MetricCapture {
+    ctor public MetricCapture(java.util.List<java.lang.String> names);
+    method public abstract void capturePaused();
+    method public abstract void captureResumed();
+    method public abstract void captureStart(long timeNs);
+    method public abstract void captureStop(long timeNs, long[] output, int offset);
+    method public final java.util.List<java.lang.String> getNames();
+    property public final java.util.List<java.lang.String> names;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public final class MicrobenchmarkConfig {
+    ctor public MicrobenchmarkConfig(optional java.util.List<? extends androidx.benchmark.MetricCapture> metrics, optional boolean traceAppTagEnabled, optional boolean perfettoSdkTracingEnabled, optional androidx.benchmark.ProfilerConfig? profiler);
+    method public java.util.List<androidx.benchmark.MetricCapture> getMetrics();
+    method public androidx.benchmark.ProfilerConfig? getProfiler();
+    method public boolean isPerfettoSdkTracingEnabled();
+    method public boolean isTraceAppTagEnabled();
+    property public final java.util.List<androidx.benchmark.MetricCapture> metrics;
+    property public final boolean perfettoSdkTracingEnabled;
+    property public final androidx.benchmark.ProfilerConfig? profiler;
+    property public final boolean traceAppTagEnabled;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public abstract sealed class ProfilerConfig {
+  }
+
+  public static final class ProfilerConfig.MethodTracing extends androidx.benchmark.ProfilerConfig {
+    ctor public ProfilerConfig.MethodTracing();
+    field public static final boolean AFFECTS_MEASUREMENTS_ON_THIS_DEVICE;
+    field public static final androidx.benchmark.ProfilerConfig.MethodTracing.Companion Companion;
+  }
+
+  public static final class ProfilerConfig.MethodTracing.Companion {
+  }
+
+  public static final class ProfilerConfig.StackSampling extends androidx.benchmark.ProfilerConfig {
+    ctor public ProfilerConfig.StackSampling();
+  }
+
+  @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public final class TimeCapture extends androidx.benchmark.MetricCapture {
+    ctor public TimeCapture();
+    ctor public TimeCapture(optional String name);
+    method public void capturePaused();
+    method public void captureResumed();
+    method public void captureStart(long timeNs);
+    method public void captureStop(long timeNs, long[] output, int offset);
+  }
+
+}
+
+package androidx.benchmark.perfetto {
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalPerfettoCaptureApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public abstract sealed class PerfettoConfig {
+  }
+
+  public static final class PerfettoConfig.Binary extends androidx.benchmark.perfetto.PerfettoConfig {
+    ctor public PerfettoConfig.Binary(byte[] bytes);
+    method public byte[] getBytes();
+    property public final byte[] bytes;
+  }
+
+  public static final class PerfettoConfig.Text extends androidx.benchmark.perfetto.PerfettoConfig {
+    ctor public PerfettoConfig.Text(String text);
+    method public String getText();
+    property public final String text;
+  }
+
+  @SuppressCompatibility @RequiresApi(23) @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public final class PerfettoTrace {
+    ctor public PerfettoTrace(String path);
+    method public String getPath();
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static void record(String fileLabel, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    property public final String path;
+    field public static final androidx.benchmark.perfetto.PerfettoTrace.Companion Companion;
+  }
+
+  public static final class PerfettoTrace.Companion {
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void record(String fileLabel, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+  }
+
+}
+
diff --git a/benchmark/benchmark-junit4/api/1.3.0-beta01.txt b/benchmark/benchmark-junit4/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..fc4b392
--- /dev/null
+++ b/benchmark/benchmark-junit4/api/1.3.0-beta01.txt
@@ -0,0 +1,36 @@
+// Signature format: 4.0
+package androidx.benchmark.junit4 {
+
+  public class AndroidBenchmarkRunner extends androidx.test.runner.AndroidJUnitRunner {
+    ctor public AndroidBenchmarkRunner();
+  }
+
+  public final class BenchmarkRule implements org.junit.rules.TestRule {
+    ctor public BenchmarkRule();
+    ctor @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public BenchmarkRule(androidx.benchmark.MicrobenchmarkConfig config);
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public androidx.benchmark.BenchmarkState getState();
+  }
+
+  public final class BenchmarkRule.Scope {
+    method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+  public final class BenchmarkRuleKt {
+    method public static inline void measureRepeated(androidx.benchmark.junit4.BenchmarkRule, kotlin.jvm.functions.Function1<? super androidx.benchmark.junit4.BenchmarkRule.Scope,kotlin.Unit> block);
+    method public static inline void measureRepeatedOnMainThread(androidx.benchmark.junit4.BenchmarkRule, kotlin.jvm.functions.Function1<? super androidx.benchmark.junit4.BenchmarkRule.Scope,kotlin.Unit> block);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public final class PerfettoTraceRule implements org.junit.rules.TestRule {
+    ctor public PerfettoTraceRule(optional boolean enableAppTagTracing, optional boolean enableUserspaceTracing, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback);
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public boolean getEnableAppTagTracing();
+    method public boolean getEnableUserspaceTracing();
+    method public kotlin.jvm.functions.Function1<androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? getTraceCallback();
+    property public final boolean enableAppTagTracing;
+    property public final boolean enableUserspaceTracing;
+    property public final kotlin.jvm.functions.Function1<androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback;
+  }
+
+}
+
diff --git a/benchmark/benchmark-junit4/api/res-1.3.0-beta01.txt b/benchmark/benchmark-junit4/api/res-1.3.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/benchmark/benchmark-junit4/api/res-1.3.0-beta01.txt
diff --git a/benchmark/benchmark-junit4/api/restricted_1.3.0-beta01.txt b/benchmark/benchmark-junit4/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..6aac49d
--- /dev/null
+++ b/benchmark/benchmark-junit4/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,37 @@
+// Signature format: 4.0
+package androidx.benchmark.junit4 {
+
+  public class AndroidBenchmarkRunner extends androidx.test.runner.AndroidJUnitRunner {
+    ctor public AndroidBenchmarkRunner();
+  }
+
+  public final class BenchmarkRule implements org.junit.rules.TestRule {
+    ctor public BenchmarkRule();
+    ctor @SuppressCompatibility @androidx.benchmark.ExperimentalBenchmarkConfigApi public BenchmarkRule(androidx.benchmark.MicrobenchmarkConfig config);
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public androidx.benchmark.BenchmarkState getState();
+  }
+
+  public final class BenchmarkRule.Scope {
+    method @kotlin.PublishedApi internal androidx.benchmark.BenchmarkState getOuterState();
+    method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+  public final class BenchmarkRuleKt {
+    method public static inline void measureRepeated(androidx.benchmark.junit4.BenchmarkRule, kotlin.jvm.functions.Function1<? super androidx.benchmark.junit4.BenchmarkRule.Scope,kotlin.Unit> block);
+    method public static inline void measureRepeatedOnMainThread(androidx.benchmark.junit4.BenchmarkRule, kotlin.jvm.functions.Function1<? super androidx.benchmark.junit4.BenchmarkRule.Scope,kotlin.Unit> block);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public final class PerfettoTraceRule implements org.junit.rules.TestRule {
+    ctor public PerfettoTraceRule(optional boolean enableAppTagTracing, optional boolean enableUserspaceTracing, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback);
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public boolean getEnableAppTagTracing();
+    method public boolean getEnableUserspaceTracing();
+    method public kotlin.jvm.functions.Function1<androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? getTraceCallback();
+    property public final boolean enableAppTagTracing;
+    property public final boolean enableUserspaceTracing;
+    property public final kotlin.jvm.functions.Function1<androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback;
+  }
+
+}
+
diff --git a/benchmark/benchmark-macro-junit4/api/1.3.0-beta01.txt b/benchmark/benchmark-macro-junit4/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..e06bf57
--- /dev/null
+++ b/benchmark/benchmark-macro-junit4/api/1.3.0-beta01.txt
@@ -0,0 +1,30 @@
+// Signature format: 4.0
+package androidx.benchmark.macro.junit4 {
+
+  @RequiresApi(28) public final class BaselineProfileRule implements org.junit.rules.TestRule {
+    ctor public BaselineProfileRule();
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional boolean strictStability, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional boolean strictStability, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean> filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+  }
+
+  public final class MacrobenchmarkRule implements org.junit.rules.TestRule {
+    ctor public MacrobenchmarkRule();
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, @IntRange(from=1L) int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, @IntRange(from=1L) int iterations, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> setupBlock, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, optional androidx.benchmark.macro.CompilationMode compilationMode, @IntRange(from=1L) int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> setupBlock, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, optional androidx.benchmark.macro.CompilationMode compilationMode, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+  }
+
+}
+
diff --git a/benchmark/benchmark-macro-junit4/api/res-1.3.0-beta01.txt b/benchmark/benchmark-macro-junit4/api/res-1.3.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/benchmark/benchmark-macro-junit4/api/res-1.3.0-beta01.txt
diff --git a/benchmark/benchmark-macro-junit4/api/restricted_1.3.0-beta01.txt b/benchmark/benchmark-macro-junit4/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..e06bf57
--- /dev/null
+++ b/benchmark/benchmark-macro-junit4/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,30 @@
+// Signature format: 4.0
+package androidx.benchmark.macro.junit4 {
+
+  @RequiresApi(28) public final class BaselineProfileRule implements org.junit.rules.TestRule {
+    ctor public BaselineProfileRule();
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional boolean strictStability, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional boolean strictStability, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean> filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, optional String? outputFilePrefix, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, optional int stableIterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, optional int maxIterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collect(String packageName, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+  }
+
+  public final class MacrobenchmarkRule implements org.junit.rules.TestRule {
+    ctor public MacrobenchmarkRule();
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, @IntRange(from=1L) int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, @IntRange(from=1L) int iterations, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> setupBlock, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, optional androidx.benchmark.macro.CompilationMode compilationMode, @IntRange(from=1L) int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, optional androidx.benchmark.macro.CompilationMode compilationMode, optional androidx.benchmark.macro.StartupMode? startupMode, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> setupBlock, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, optional androidx.benchmark.macro.CompilationMode compilationMode, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, androidx.benchmark.perfetto.PerfettoConfig perfettoConfig, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+    method public void measureRepeated(String packageName, java.util.List<? extends androidx.benchmark.macro.Metric> metrics, @IntRange(from=1L) int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> measureBlock);
+  }
+
+}
+
diff --git a/benchmark/benchmark-macro/api/1.3.0-beta01.txt b/benchmark/benchmark-macro/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..ad9fb40
--- /dev/null
+++ b/benchmark/benchmark-macro/api/1.3.0-beta01.txt
@@ -0,0 +1,281 @@
+// Signature format: 4.0
+package androidx.benchmark.macro {
+
+  public enum BaselineProfileMode {
+    enum_constant public static final androidx.benchmark.macro.BaselineProfileMode Disable;
+    enum_constant public static final androidx.benchmark.macro.BaselineProfileMode Require;
+    enum_constant public static final androidx.benchmark.macro.BaselineProfileMode UseIfAvailable;
+  }
+
+  public abstract sealed class CompilationMode {
+    field public static final androidx.benchmark.macro.CompilationMode.Companion Companion;
+    field public static final androidx.benchmark.macro.CompilationMode DEFAULT;
+  }
+
+  public static final class CompilationMode.Companion {
+  }
+
+  public static final class CompilationMode.Full extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.Full();
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMacrobenchmarkApi public static final class CompilationMode.Ignore extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.Ignore();
+  }
+
+  @RequiresApi(24) public static final class CompilationMode.None extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.None();
+  }
+
+  @RequiresApi(24) public static final class CompilationMode.Partial extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.Partial();
+    ctor public CompilationMode.Partial(optional androidx.benchmark.macro.BaselineProfileMode baselineProfileMode);
+    ctor public CompilationMode.Partial(optional androidx.benchmark.macro.BaselineProfileMode baselineProfileMode, optional @IntRange(from=0L) int warmupIterations);
+    method public androidx.benchmark.macro.BaselineProfileMode getBaselineProfileMode();
+    method public int getWarmupIterations();
+    property public final androidx.benchmark.macro.BaselineProfileMode baselineProfileMode;
+    property public final int warmupIterations;
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This Macrobenchmark API is experimental.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalMacrobenchmarkApi {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This Metric API is experimental.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalMetricApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class FrameTimingGfxInfoMetric extends androidx.benchmark.macro.Metric {
+    ctor public FrameTimingGfxInfoMetric();
+  }
+
+  public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
+    ctor public FrameTimingMetric();
+  }
+
+  public final class MacrobenchmarkScope {
+    ctor public MacrobenchmarkScope(String packageName, boolean launchWithClearTask);
+    method public void dropKernelPageCache();
+    method public void dropShaderCache();
+    method public androidx.test.uiautomator.UiDevice getDevice();
+    method public Integer? getIteration();
+    method public String getPackageName();
+    method public void killProcess();
+    method @Deprecated public void killProcess(optional boolean useKillAll);
+    method public void pressHome();
+    method public void pressHome(optional long delayDurationMs);
+    method public void startActivityAndWait();
+    method public void startActivityAndWait(android.content.Intent intent);
+    method public void startActivityAndWait(optional kotlin.jvm.functions.Function1<? super android.content.Intent,kotlin.Unit> block);
+    property public final androidx.test.uiautomator.UiDevice device;
+    property public final Integer? iteration;
+    property public final String packageName;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class MemoryCountersMetric extends androidx.benchmark.macro.TraceMetric {
+    ctor public MemoryCountersMetric();
+    method public java.util.List<androidx.benchmark.macro.Metric.Measurement> getMeasurements(androidx.benchmark.macro.Metric.CaptureInfo captureInfo, androidx.benchmark.perfetto.PerfettoTraceProcessor.Session traceSession);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class MemoryUsageMetric extends androidx.benchmark.macro.TraceMetric {
+    ctor public MemoryUsageMetric(androidx.benchmark.macro.MemoryUsageMetric.Mode mode, optional java.util.List<? extends androidx.benchmark.macro.MemoryUsageMetric.SubMetric> subMetrics);
+    method public java.util.List<androidx.benchmark.macro.Metric.Measurement> getMeasurements(androidx.benchmark.macro.Metric.CaptureInfo captureInfo, androidx.benchmark.perfetto.PerfettoTraceProcessor.Session traceSession);
+  }
+
+  public enum MemoryUsageMetric.Mode {
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.Mode Last;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.Mode Max;
+  }
+
+  public enum MemoryUsageMetric.SubMetric {
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric Gpu;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric HeapSize;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric RssAnon;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric RssFile;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric RssShmem;
+  }
+
+  public abstract sealed class Metric {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public static final class Metric.CaptureInfo {
+    ctor public Metric.CaptureInfo(int apiLevel, String targetPackageName, String testPackageName, androidx.benchmark.macro.StartupMode? startupMode);
+    method public int component1();
+    method public String component2();
+    method public String component3();
+    method public androidx.benchmark.macro.StartupMode? component4();
+    method public androidx.benchmark.macro.Metric.CaptureInfo copy(int apiLevel, String targetPackageName, String testPackageName, androidx.benchmark.macro.StartupMode? startupMode);
+    method public int getApiLevel();
+    method public androidx.benchmark.macro.StartupMode? getStartupMode();
+    method public String getTargetPackageName();
+    method public String getTestPackageName();
+    property public final int apiLevel;
+    property public final androidx.benchmark.macro.StartupMode? startupMode;
+    property public final String targetPackageName;
+    property public final String testPackageName;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public static final class Metric.Measurement {
+    ctor public Metric.Measurement(String name, double data);
+    ctor public Metric.Measurement(String name, java.util.List<java.lang.Double> dataSamples);
+    method public String component1();
+    method public java.util.List<java.lang.Double> component2();
+    method public boolean component3();
+    method public androidx.benchmark.macro.Metric.Measurement copy(String name, java.util.List<java.lang.Double> data, boolean requireSingleValue);
+    method public java.util.List<java.lang.Double> getData();
+    method public String getName();
+    method public boolean getRequireSingleValue();
+    property public final java.util.List<java.lang.Double> data;
+    property public final String name;
+    property public final boolean requireSingleValue;
+  }
+
+  public final class MetricResultExtensionsKt {
+    method @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public static void assertEqualMeasurements(java.util.List<androidx.benchmark.macro.Metric.Measurement> expected, java.util.List<androidx.benchmark.macro.Metric.Measurement> observed, double threshold);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public enum PowerCategory {
+    enum_constant public static final androidx.benchmark.macro.PowerCategory CPU;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory DISPLAY;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory GPS;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory GPU;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory MACHINE_LEARNING;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory MEMORY;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory NETWORK;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory UNCATEGORIZED;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public enum PowerCategoryDisplayLevel {
+    enum_constant public static final androidx.benchmark.macro.PowerCategoryDisplayLevel BREAKDOWN;
+    enum_constant public static final androidx.benchmark.macro.PowerCategoryDisplayLevel TOTAL;
+  }
+
+  @SuppressCompatibility @RequiresApi(29) @androidx.benchmark.macro.ExperimentalMetricApi public final class PowerMetric extends androidx.benchmark.macro.Metric {
+    ctor public PowerMetric(androidx.benchmark.macro.PowerMetric.Type type);
+    method public static androidx.benchmark.macro.PowerMetric.Type.Battery Battery();
+    method public static androidx.benchmark.macro.PowerMetric.Type.Energy Energy(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public static androidx.benchmark.macro.PowerMetric.Type.Power Power(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public static boolean deviceBatteryHasMinimumCharge();
+    method public static boolean deviceSupportsHighPrecisionTracking();
+    field public static final androidx.benchmark.macro.PowerMetric.Companion Companion;
+  }
+
+  public static final class PowerMetric.Companion {
+    method public androidx.benchmark.macro.PowerMetric.Type.Battery Battery();
+    method public androidx.benchmark.macro.PowerMetric.Type.Energy Energy(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public androidx.benchmark.macro.PowerMetric.Type.Power Power(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public boolean deviceBatteryHasMinimumCharge();
+    method public boolean deviceSupportsHighPrecisionTracking();
+  }
+
+  public abstract static sealed class PowerMetric.Type {
+    method public final java.util.Map<androidx.benchmark.macro.PowerCategory,androidx.benchmark.macro.PowerCategoryDisplayLevel> getCategories();
+    method public final void setCategories(java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel>);
+    property public final java.util.Map<androidx.benchmark.macro.PowerCategory,androidx.benchmark.macro.PowerCategoryDisplayLevel> categories;
+  }
+
+  public static final class PowerMetric.Type.Battery extends androidx.benchmark.macro.PowerMetric.Type {
+    ctor public PowerMetric.Type.Battery();
+  }
+
+  public static final class PowerMetric.Type.Energy extends androidx.benchmark.macro.PowerMetric.Type {
+    ctor public PowerMetric.Type.Energy(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> energyCategories);
+  }
+
+  public static final class PowerMetric.Type.Power extends androidx.benchmark.macro.PowerMetric.Type {
+    ctor public PowerMetric.Type.Power(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> powerCategories);
+  }
+
+  public enum StartupMode {
+    enum_constant public static final androidx.benchmark.macro.StartupMode COLD;
+    enum_constant public static final androidx.benchmark.macro.StartupMode HOT;
+    enum_constant public static final androidx.benchmark.macro.StartupMode WARM;
+  }
+
+  public final class StartupTimingMetric extends androidx.benchmark.macro.Metric {
+    ctor public StartupTimingMetric();
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public abstract class TraceMetric extends androidx.benchmark.macro.Metric {
+    ctor public TraceMetric();
+    method public abstract java.util.List<androidx.benchmark.macro.Metric.Measurement> getMeasurements(androidx.benchmark.macro.Metric.CaptureInfo captureInfo, androidx.benchmark.perfetto.PerfettoTraceProcessor.Session traceSession);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class TraceSectionMetric extends androidx.benchmark.macro.Metric {
+    ctor public TraceSectionMetric(String sectionName);
+    ctor public TraceSectionMetric(String sectionName, optional androidx.benchmark.macro.TraceSectionMetric.Mode mode);
+    ctor public TraceSectionMetric(String sectionName, optional androidx.benchmark.macro.TraceSectionMetric.Mode mode, optional String label);
+    ctor public TraceSectionMetric(String sectionName, optional androidx.benchmark.macro.TraceSectionMetric.Mode mode, optional String label, optional boolean targetPackageOnly);
+  }
+
+  public abstract static sealed class TraceSectionMetric.Mode {
+  }
+
+  public static final class TraceSectionMetric.Mode.Average extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Average INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Count extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Count INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.First extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.First INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Max extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Max INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Min extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Min INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Sum extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Sum INSTANCE;
+  }
+
+}
+
+package androidx.benchmark.perfetto {
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalPerfettoTraceProcessorApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public final class PerfettoTraceProcessor {
+    ctor public PerfettoTraceProcessor();
+    method public <T> T loadTrace(androidx.benchmark.perfetto.PerfettoTrace trace, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor.Session,? extends T> block);
+    method public static <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    method public static <T> T runServer(long timeout, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    field public static final androidx.benchmark.perfetto.PerfettoTraceProcessor.Companion Companion;
+  }
+
+  public static final class PerfettoTraceProcessor.Companion {
+    method public <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    method public static <T> T runServer(long timeout, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+  }
+
+  public static final class PerfettoTraceProcessor.Session {
+    method public kotlin.sequences.Sequence<androidx.benchmark.perfetto.Row> query(@org.intellij.lang.annotations.Language("sql") String query);
+    method public String queryMetricsJson(java.util.List<java.lang.String> metrics);
+    method public byte[] queryMetricsProtoBinary(java.util.List<java.lang.String> metrics);
+    method public String queryMetricsProtoText(java.util.List<java.lang.String> metrics);
+    method public byte[] rawQuery(@org.intellij.lang.annotations.Language("sql") String query);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public final class Row implements kotlin.jvm.internal.markers.KMappedMarker java.util.Map<java.lang.String,java.lang.Object?> {
+    ctor public Row(java.util.Map<java.lang.String,? extends java.lang.Object?> map);
+    method public byte[] bytes(String columnName);
+    method public double double(String columnName);
+    method public long long(String columnName);
+    method public byte[]? nullableBytes(String columnName);
+    method public Double? nullableDouble(String columnName);
+    method public Long? nullableLong(String columnName);
+    method public String? nullableString(String columnName);
+    method public String string(String columnName);
+  }
+
+  public final class RowKt {
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public static androidx.benchmark.perfetto.Row rowOf(kotlin.Pair<java.lang.String,? extends java.lang.Object?>... pairs);
+  }
+
+}
+
diff --git a/benchmark/benchmark-macro/api/res-1.3.0-beta01.txt b/benchmark/benchmark-macro/api/res-1.3.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/benchmark/benchmark-macro/api/res-1.3.0-beta01.txt
diff --git a/benchmark/benchmark-macro/api/restricted_1.3.0-beta01.txt b/benchmark/benchmark-macro/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..4c883fb
--- /dev/null
+++ b/benchmark/benchmark-macro/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,303 @@
+// Signature format: 4.0
+package androidx.benchmark.macro {
+
+  public enum BaselineProfileMode {
+    enum_constant public static final androidx.benchmark.macro.BaselineProfileMode Disable;
+    enum_constant public static final androidx.benchmark.macro.BaselineProfileMode Require;
+    enum_constant public static final androidx.benchmark.macro.BaselineProfileMode UseIfAvailable;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class BatteryCharge {
+    method public boolean hasMinimumCharge(optional boolean throwOnMissingMetrics);
+    field public static final androidx.benchmark.macro.BatteryCharge INSTANCE;
+  }
+
+  public abstract sealed class CompilationMode {
+    field public static final androidx.benchmark.macro.CompilationMode.Companion Companion;
+    field public static final androidx.benchmark.macro.CompilationMode DEFAULT;
+  }
+
+  public static final class CompilationMode.Companion {
+  }
+
+  public static final class CompilationMode.Full extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.Full();
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMacrobenchmarkApi public static final class CompilationMode.Ignore extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.Ignore();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final class CompilationMode.Interpreted extends androidx.benchmark.macro.CompilationMode {
+    field public static final androidx.benchmark.macro.CompilationMode.Interpreted INSTANCE;
+  }
+
+  @RequiresApi(24) public static final class CompilationMode.None extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.None();
+  }
+
+  @RequiresApi(24) public static final class CompilationMode.Partial extends androidx.benchmark.macro.CompilationMode {
+    ctor public CompilationMode.Partial();
+    ctor public CompilationMode.Partial(optional androidx.benchmark.macro.BaselineProfileMode baselineProfileMode);
+    ctor public CompilationMode.Partial(optional androidx.benchmark.macro.BaselineProfileMode baselineProfileMode, optional @IntRange(from=0L) int warmupIterations);
+    method public androidx.benchmark.macro.BaselineProfileMode getBaselineProfileMode();
+    method public int getWarmupIterations();
+    property public final androidx.benchmark.macro.BaselineProfileMode baselineProfileMode;
+    property public final int warmupIterations;
+  }
+
+  public final class CompilationModeKt {
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static boolean isSupportedWithVmSettings(androidx.benchmark.macro.CompilationMode);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This Macrobenchmark API is experimental.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalMacrobenchmarkApi {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This Metric API is experimental.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalMetricApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class FrameTimingGfxInfoMetric extends androidx.benchmark.macro.Metric {
+    ctor public FrameTimingGfxInfoMetric();
+  }
+
+  public final class FrameTimingMetric extends androidx.benchmark.macro.Metric {
+    ctor public FrameTimingMetric();
+  }
+
+  public final class MacrobenchmarkScope {
+    ctor public MacrobenchmarkScope(String packageName, boolean launchWithClearTask);
+    method public void dropKernelPageCache();
+    method public void dropShaderCache();
+    method public androidx.test.uiautomator.UiDevice getDevice();
+    method public Integer? getIteration();
+    method public String getPackageName();
+    method public void killProcess();
+    method @Deprecated public void killProcess(optional boolean useKillAll);
+    method public void pressHome();
+    method public void pressHome(optional long delayDurationMs);
+    method public void startActivityAndWait();
+    method public void startActivityAndWait(android.content.Intent intent);
+    method public void startActivityAndWait(optional kotlin.jvm.functions.Function1<? super android.content.Intent,kotlin.Unit> block);
+    property public final androidx.test.uiautomator.UiDevice device;
+    property public final Integer? iteration;
+    property public final String packageName;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class MemoryCountersMetric extends androidx.benchmark.macro.TraceMetric {
+    ctor public MemoryCountersMetric();
+    method public java.util.List<androidx.benchmark.macro.Metric.Measurement> getMeasurements(androidx.benchmark.macro.Metric.CaptureInfo captureInfo, androidx.benchmark.perfetto.PerfettoTraceProcessor.Session traceSession);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class MemoryUsageMetric extends androidx.benchmark.macro.TraceMetric {
+    ctor public MemoryUsageMetric(androidx.benchmark.macro.MemoryUsageMetric.Mode mode, optional java.util.List<? extends androidx.benchmark.macro.MemoryUsageMetric.SubMetric> subMetrics);
+    method public java.util.List<androidx.benchmark.macro.Metric.Measurement> getMeasurements(androidx.benchmark.macro.Metric.CaptureInfo captureInfo, androidx.benchmark.perfetto.PerfettoTraceProcessor.Session traceSession);
+  }
+
+  public enum MemoryUsageMetric.Mode {
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.Mode Last;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.Mode Max;
+  }
+
+  public enum MemoryUsageMetric.SubMetric {
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric Gpu;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric HeapSize;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric RssAnon;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric RssFile;
+    enum_constant public static final androidx.benchmark.macro.MemoryUsageMetric.SubMetric RssShmem;
+  }
+
+  public abstract sealed class Metric {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public static final class Metric.CaptureInfo {
+    ctor public Metric.CaptureInfo(int apiLevel, String targetPackageName, String testPackageName, androidx.benchmark.macro.StartupMode? startupMode);
+    method public int component1();
+    method public String component2();
+    method public String component3();
+    method public androidx.benchmark.macro.StartupMode? component4();
+    method public androidx.benchmark.macro.Metric.CaptureInfo copy(int apiLevel, String targetPackageName, String testPackageName, androidx.benchmark.macro.StartupMode? startupMode);
+    method public int getApiLevel();
+    method public androidx.benchmark.macro.StartupMode? getStartupMode();
+    method public String getTargetPackageName();
+    method public String getTestPackageName();
+    property public final int apiLevel;
+    property public final androidx.benchmark.macro.StartupMode? startupMode;
+    property public final String targetPackageName;
+    property public final String testPackageName;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public static final class Metric.Measurement {
+    ctor public Metric.Measurement(String name, double data);
+    ctor public Metric.Measurement(String name, java.util.List<java.lang.Double> dataSamples);
+    method public String component1();
+    method public java.util.List<java.lang.Double> component2();
+    method public boolean component3();
+    method public androidx.benchmark.macro.Metric.Measurement copy(String name, java.util.List<java.lang.Double> data, boolean requireSingleValue);
+    method public java.util.List<java.lang.Double> getData();
+    method public String getName();
+    method public boolean getRequireSingleValue();
+    property public final java.util.List<java.lang.Double> data;
+    property public final String name;
+    property public final boolean requireSingleValue;
+  }
+
+  public final class MetricResultExtensionsKt {
+    method @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public static void assertEqualMeasurements(java.util.List<androidx.benchmark.macro.Metric.Measurement> expected, java.util.List<androidx.benchmark.macro.Metric.Measurement> observed, double threshold);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public enum PowerCategory {
+    enum_constant public static final androidx.benchmark.macro.PowerCategory CPU;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory DISPLAY;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory GPS;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory GPU;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory MACHINE_LEARNING;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory MEMORY;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory NETWORK;
+    enum_constant public static final androidx.benchmark.macro.PowerCategory UNCATEGORIZED;
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public enum PowerCategoryDisplayLevel {
+    enum_constant public static final androidx.benchmark.macro.PowerCategoryDisplayLevel BREAKDOWN;
+    enum_constant public static final androidx.benchmark.macro.PowerCategoryDisplayLevel TOTAL;
+  }
+
+  @SuppressCompatibility @RequiresApi(29) @androidx.benchmark.macro.ExperimentalMetricApi public final class PowerMetric extends androidx.benchmark.macro.Metric {
+    ctor public PowerMetric(androidx.benchmark.macro.PowerMetric.Type type);
+    method public static androidx.benchmark.macro.PowerMetric.Type.Battery Battery();
+    method public static androidx.benchmark.macro.PowerMetric.Type.Energy Energy(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public static androidx.benchmark.macro.PowerMetric.Type.Power Power(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public static boolean deviceBatteryHasMinimumCharge();
+    method public static boolean deviceSupportsHighPrecisionTracking();
+    field public static final androidx.benchmark.macro.PowerMetric.Companion Companion;
+  }
+
+  public static final class PowerMetric.Companion {
+    method public androidx.benchmark.macro.PowerMetric.Type.Battery Battery();
+    method public androidx.benchmark.macro.PowerMetric.Type.Energy Energy(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public androidx.benchmark.macro.PowerMetric.Type.Power Power(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> categories);
+    method public boolean deviceBatteryHasMinimumCharge();
+    method public boolean deviceSupportsHighPrecisionTracking();
+  }
+
+  public abstract static sealed class PowerMetric.Type {
+    method public final java.util.Map<androidx.benchmark.macro.PowerCategory,androidx.benchmark.macro.PowerCategoryDisplayLevel> getCategories();
+    method public final void setCategories(java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel>);
+    property public final java.util.Map<androidx.benchmark.macro.PowerCategory,androidx.benchmark.macro.PowerCategoryDisplayLevel> categories;
+  }
+
+  public static final class PowerMetric.Type.Battery extends androidx.benchmark.macro.PowerMetric.Type {
+    ctor public PowerMetric.Type.Battery();
+  }
+
+  public static final class PowerMetric.Type.Energy extends androidx.benchmark.macro.PowerMetric.Type {
+    ctor public PowerMetric.Type.Energy(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> energyCategories);
+  }
+
+  public static final class PowerMetric.Type.Power extends androidx.benchmark.macro.PowerMetric.Type {
+    ctor public PowerMetric.Type.Power(optional java.util.Map<androidx.benchmark.macro.PowerCategory,? extends androidx.benchmark.macro.PowerCategoryDisplayLevel> powerCategories);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class PowerRail {
+    method public boolean hasMetrics(optional boolean throwOnMissingMetrics);
+    field public static final androidx.benchmark.macro.PowerRail INSTANCE;
+  }
+
+  public enum StartupMode {
+    enum_constant public static final androidx.benchmark.macro.StartupMode COLD;
+    enum_constant public static final androidx.benchmark.macro.StartupMode HOT;
+    enum_constant public static final androidx.benchmark.macro.StartupMode WARM;
+  }
+
+  @RequiresApi(29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class StartupTimingLegacyMetric extends androidx.benchmark.macro.Metric {
+    ctor public StartupTimingLegacyMetric();
+  }
+
+  public final class StartupTimingMetric extends androidx.benchmark.macro.Metric {
+    ctor public StartupTimingMetric();
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public abstract class TraceMetric extends androidx.benchmark.macro.Metric {
+    ctor public TraceMetric();
+    method public abstract java.util.List<androidx.benchmark.macro.Metric.Measurement> getMeasurements(androidx.benchmark.macro.Metric.CaptureInfo captureInfo, androidx.benchmark.perfetto.PerfettoTraceProcessor.Session traceSession);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.macro.ExperimentalMetricApi public final class TraceSectionMetric extends androidx.benchmark.macro.Metric {
+    ctor public TraceSectionMetric(String sectionName);
+    ctor public TraceSectionMetric(String sectionName, optional androidx.benchmark.macro.TraceSectionMetric.Mode mode);
+    ctor public TraceSectionMetric(String sectionName, optional androidx.benchmark.macro.TraceSectionMetric.Mode mode, optional String label);
+    ctor public TraceSectionMetric(String sectionName, optional androidx.benchmark.macro.TraceSectionMetric.Mode mode, optional String label, optional boolean targetPackageOnly);
+  }
+
+  public abstract static sealed class TraceSectionMetric.Mode {
+  }
+
+  public static final class TraceSectionMetric.Mode.Average extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Average INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Count extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Count INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.First extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.First INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Max extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Max INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Min extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Min INSTANCE;
+  }
+
+  public static final class TraceSectionMetric.Mode.Sum extends androidx.benchmark.macro.TraceSectionMetric.Mode {
+    field public static final androidx.benchmark.macro.TraceSectionMetric.Mode.Sum INSTANCE;
+  }
+
+}
+
+package androidx.benchmark.perfetto {
+
+  @SuppressCompatibility @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalPerfettoTraceProcessorApi {
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public final class PerfettoTraceProcessor {
+    ctor public PerfettoTraceProcessor();
+    method public <T> T loadTrace(androidx.benchmark.perfetto.PerfettoTrace trace, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor.Session,? extends T> block);
+    method public static <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    method public static <T> T runServer(long timeout, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    field public static final androidx.benchmark.perfetto.PerfettoTraceProcessor.Companion Companion;
+  }
+
+  public static final class PerfettoTraceProcessor.Companion {
+    method public <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    method public static <T> T runServer(long timeout, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+  }
+
+  public static final class PerfettoTraceProcessor.Session {
+    method public kotlin.sequences.Sequence<androidx.benchmark.perfetto.Row> query(@org.intellij.lang.annotations.Language("sql") String query);
+    method public String queryMetricsJson(java.util.List<java.lang.String> metrics);
+    method public byte[] queryMetricsProtoBinary(java.util.List<java.lang.String> metrics);
+    method public String queryMetricsProtoText(java.util.List<java.lang.String> metrics);
+    method public byte[] rawQuery(@org.intellij.lang.annotations.Language("sql") String query);
+  }
+
+  @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public final class Row implements kotlin.jvm.internal.markers.KMappedMarker java.util.Map<java.lang.String,java.lang.Object?> {
+    ctor public Row(java.util.Map<java.lang.String,? extends java.lang.Object?> map);
+    method public byte[] bytes(String columnName);
+    method public double double(String columnName);
+    method public long long(String columnName);
+    method public byte[]? nullableBytes(String columnName);
+    method public Double? nullableDouble(String columnName);
+    method public Long? nullableLong(String columnName);
+    method public String? nullableString(String columnName);
+    method public String string(String columnName);
+  }
+
+  public final class RowKt {
+    method @SuppressCompatibility @androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public static androidx.benchmark.perfetto.Row rowOf(kotlin.Pair<java.lang.String,? extends java.lang.Object?>... pairs);
+  }
+
+}
+
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt b/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt
index 386f1d4..6a9c795 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt
@@ -18,6 +18,7 @@
 
 import com.android.build.api.dsl.KotlinMultiplatformAndroidTarget
 import com.android.build.api.dsl.Lint
+import com.android.build.api.variant.KotlinMultiplatformAndroidComponentsExtension
 import com.android.build.gradle.AppPlugin
 import com.android.build.gradle.LibraryPlugin
 import com.android.build.gradle.api.KotlinMultiplatformAndroidPlugin
@@ -46,7 +47,8 @@
             is LibraryPlugin -> configureAndroidProjectForLint(isLibrary = true)
             is KotlinMultiplatformAndroidPlugin ->
                 configureAndroidMultiplatformProjectForLint(
-                    extensions.getByType<AndroidXMultiplatformExtension>().agpKmpExtension
+                    extensions.getByType<AndroidXMultiplatformExtension>().agpKmpExtension,
+                    extensions.getByType<KotlinMultiplatformAndroidComponentsExtension>()
                 )
             // Only configure non-multiplatform Java projects via JavaPlugin. Multiplatform
             // projects targeting Java (e.g. `jvm { withJava() }`) are configured via
@@ -81,11 +83,14 @@
     }
 
 private fun Project.configureAndroidMultiplatformProjectForLint(
-    extension: KotlinMultiplatformAndroidTarget
+    extension: KotlinMultiplatformAndroidTarget,
+    componentsExtension: KotlinMultiplatformAndroidComponentsExtension
 ) {
-    // The lintAnalyze task is used by `androidx-studio-integration-lint.sh`.
-    tasks.register("lintAnalyze") { task -> task.enabled = false }
-    configureLint(extension.lint, true)
+    componentsExtension.finalizeDsl {
+        // The lintAnalyze task is used by `androidx-studio-integration-lint.sh`.
+        tasks.register("lintAnalyze") { task -> task.enabled = false }
+        configureLint(extension.lint, isLibrary = true)
+    }
 }
 
 /** Android Lint configuration entry point for non-Android projects. */
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CameraControlImplDeviceTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CameraControlImplDeviceTest.java
index cda5192..c432941 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CameraControlImplDeviceTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CameraControlImplDeviceTest.java
@@ -1041,6 +1041,36 @@
         executor.assertExecutorIsCalled(5000);
     }
 
+    @Test
+    public void canUseVideoUsage() {
+        // No recording initially.
+        assertThat(mCamera2CameraControlImpl.isInVideoUsage()).isFalse();
+
+        // Case 1: Single video usage.
+        mCamera2CameraControlImpl.incrementVideoUsage();
+        assertThat(mCamera2CameraControlImpl.isInVideoUsage()).isTrue();
+
+        mCamera2CameraControlImpl.decrementVideoUsage();
+        assertThat(mCamera2CameraControlImpl.isInVideoUsage()).isFalse();
+
+        // Case 2: Multiple video usages.
+        mCamera2CameraControlImpl.incrementVideoUsage();
+        mCamera2CameraControlImpl.incrementVideoUsage();
+        assertThat(mCamera2CameraControlImpl.isInVideoUsage()).isTrue();
+
+        mCamera2CameraControlImpl.decrementVideoUsage();
+        // There should still be a video usage remaining two were set as true before
+        assertThat(mCamera2CameraControlImpl.isInVideoUsage()).isTrue();
+
+        mCamera2CameraControlImpl.decrementVideoUsage();
+        assertThat(mCamera2CameraControlImpl.isInVideoUsage()).isFalse();
+
+        // Case 3: video usage clearing when inactive.
+        mCamera2CameraControlImpl.incrementVideoUsage();
+        mCamera2CameraControlImpl.setActive(false);
+        assertThat(mCamera2CameraControlImpl.isInVideoUsage()).isFalse();
+    }
+
     private static class TestCameraCaptureCallback extends CameraCaptureCallback {
         private CountDownLatch mLatchForOnCaptureCompleted;
 
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java
index b70e2b6..cb73973 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java
@@ -76,6 +76,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -147,6 +148,9 @@
     @NonNull
     private volatile ListenableFuture<Void> mFlashModeChangeSessionUpdateFuture =
             Futures.immediateFuture(null);
+
+    private final AtomicInteger mVideoUsage = new AtomicInteger(0);
+
     //******************** Should only be accessed by executor *****************************//
     private int mTemplate = DEFAULT_TEMPLATE;
     // SessionUpdateId will auto-increment every time session updates.
@@ -308,6 +312,7 @@
      */
     @ExecutedBy("mExecutor")
     void setActive(boolean isActive) {
+        Logger.d(TAG, "setActive: isActive = " + isActive);
         mFocusMeteringControl.setActive(isActive);
         mZoomControl.setActive(isActive);
         mTorchControl.setActive(isActive);
@@ -315,6 +320,10 @@
         mCamera2CameraControl.setActive(isActive);
         if (!isActive) {
             mScreenFlash = null;
+            // Since the camera is no longer active, there should not be any recording ongoing with
+            // this camera. If something like persistent recording wants to resume recording with
+            // this camera again, it should update recording status again when being attached.
+            mVideoUsage.set(0);
         }
     }
 
@@ -830,6 +839,30 @@
         return mCurrentSessionUpdateId;
     }
 
+    @Override
+    public void incrementVideoUsage() {
+        int currentVal = mVideoUsage.incrementAndGet();
+        Logger.d(TAG, "incrementVideoUsage: mVideoUsage = " + currentVal);
+    }
+
+    @Override
+    public void decrementVideoUsage() {
+        int currentVal = mVideoUsage.decrementAndGet();
+        if (currentVal < 0) {
+            Logger.w(TAG, "decrementVideoUsage: mVideoUsage = " + currentVal
+                    + ", which is less than 0!");
+        } else {
+            Logger.d(TAG, "decrementVideoUsage: mVideoUsage = " + currentVal);
+        }
+    }
+
+    @Override
+    public boolean isInVideoUsage() {
+        int currentVal = mVideoUsage.get();
+        Logger.d(TAG, "isInVideoUsage: mVideoUsage = " + currentVal);
+        return currentVal > 0;
+    }
+
     /** An interface to listen to camera capture results. */
     public interface CaptureResultListener {
         /**
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
index f16ea98..2533cd6 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
@@ -168,8 +168,12 @@
         } else {
             if (mHasFlashUnit) {
                 if (isTorchAsFlash(flashType)) {
-                    pipeline.addTask(
-                            new TorchTask(mCameraControl, flashMode, mExecutor, mScheduler));
+                    // TODO: b/339846763 - Disable AE precap only for the quirks where AE precapture
+                    //  is problematic, instead of all TorchAsFlash quirks.
+                    boolean triggerAePrecapture = !mUseTorchAsFlash.shouldUseTorchAsFlash()
+                            && !mCameraControl.isInVideoUsage();
+                    pipeline.addTask(new TorchTask(mCameraControl, flashMode, mExecutor, mScheduler,
+                            triggerAePrecapture));
                 } else {
                     pipeline.addTask(new AePreCaptureTask(mCameraControl, flashMode, aeQuirk));
                 }
@@ -555,13 +559,16 @@
         @CameraExecutor
         private final Executor mExecutor;
         private final ScheduledExecutorService mScheduler;
+        private final boolean mTriggerAePrecapture;
 
         TorchTask(@NonNull Camera2CameraControlImpl cameraControl, @FlashMode int flashMode,
-                @NonNull Executor executor, ScheduledExecutorService scheduler) {
+                @NonNull Executor executor, ScheduledExecutorService scheduler,
+                boolean triggerAePrecapture) {
             mCameraControl = cameraControl;
             mFlashMode = flashMode;
             mExecutor = executor;
             mScheduler = scheduler;
+            mTriggerAePrecapture = triggerAePrecapture;
         }
 
         @ExecutedBy("mExecutor")
@@ -580,6 +587,15 @@
                         return "TorchOn";
                     });
                     return FutureChain.from(future).transformAsync(
+                            input -> {
+                                if (mTriggerAePrecapture) {
+                                    return mCameraControl.getFocusMeteringControl()
+                                            .triggerAePrecapture();
+                                }
+                                return Futures.immediateFuture(null);
+                            },
+                            mExecutor
+                    ).transformAsync(
                             input -> waitForResult(CHECK_3A_WITH_TORCH_TIMEOUT_IN_NS, mScheduler,
                                     mCameraControl, (result) -> is3AConverged(result, true)),
                             mExecutor).transform(input -> false, CameraXExecutors.directExecutor());
@@ -600,7 +616,10 @@
         public void postCapture() {
             if (mIsExecuted) {
                 mCameraControl.getTorchControl().enableTorchInternal(null, false);
-                Logger.d(TAG, "Turn off torch");
+                Logger.d(TAG, "Turning off torch");
+                if (mTriggerAePrecapture) {
+                    mCameraControl.getFocusMeteringControl().cancelAfAeTrigger(false, true);
+                }
             }
         }
     }
@@ -828,9 +847,9 @@
         }
     }
 
+    /** Whether torch flash should be used due to quirk or VideoCapture binding. */
     private boolean isTorchAsFlash(@FlashType int flashType) {
         return mUseTorchAsFlash.shouldUseTorchAsFlash() || mTemplate == CameraDevice.TEMPLATE_RECORD
                 || flashType == FLASH_TYPE_USE_TORCH_AS_FLASH;
     }
-
 }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/CaptureSession.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/CaptureSession.java
index e785b48..70d6935 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/CaptureSession.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/CaptureSession.java
@@ -128,19 +128,18 @@
      * Constructor for CaptureSession without CameraQuirk.
      */
     CaptureSession(@NonNull DynamicRangesCompat dynamicRangesCompat) {
-        this(dynamicRangesCompat, null);
+        this(dynamicRangesCompat, new Quirks(Collections.emptyList()));
     }
 
     /**
      * Constructor for CaptureSession.
      */
     CaptureSession(@NonNull DynamicRangesCompat dynamicRangesCompat,
-            @Nullable Quirks cameraQuirks) {
+            @NonNull Quirks cameraQuirks) {
         mState = State.INITIALIZED;
         mDynamicRangesCompat = dynamicRangesCompat;
         mCaptureSessionStateCallback = new StateCallback();
-        mRequestMonitor = new RequestMonitor(
-                cameraQuirks != null && cameraQuirks.contains(CaptureNoResponseQuirk.class));
+        mRequestMonitor = new RequestMonitor(cameraQuirks.contains(CaptureNoResponseQuirk.class));
         mTemplateParamsOverride = new TemplateParamsOverride(cameraQuirks);
     }
 
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/StateObservableTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/StateObservableTest.kt
index 1948944..54074e2 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/StateObservableTest.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/StateObservableTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.camera.core.impl
 
+import androidx.camera.core.impl.Observable.Observer
 import androidx.camera.testing.impl.asFlow
 import androidx.concurrent.futures.await
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -34,6 +35,7 @@
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeoutOrNull
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -115,7 +117,7 @@
     }
 
     @Test
-    public fun canObserveToRetrieveState_whenSetAfterObserve(): Unit = runBlocking {
+    fun canObserveToRetrieveState_whenSetAfterObserve(): Unit = runBlocking {
         val observable = MutableStateObservable.withInitialState(INITIAL_STATE)
 
         // Add the observer
@@ -190,4 +192,75 @@
         // Ensure receiveJob completes
         receiveJob.join()
     }
+
+    @Test
+    fun doesNotObserveNewState_whenSetAfterRemove(): Unit = runBlocking {
+        val observable = MutableStateObservable.withInitialState(INITIAL_STATE)
+
+        // Add the observer to remove later
+        val deferredCompletingObserver1 = observable.addObserver(MAGIC_STATE)
+
+        // Add another observer to know if state was notified
+        val deferredCompletingObserver2 = observable.addObserver(MAGIC_STATE)
+
+        // Remove first observer
+        observable.removeObserver(deferredCompletingObserver1.observer)
+
+        // Post the state
+        observable.setState(MAGIC_STATE)
+
+        // Wait for second observer to ensure observers were notified
+        assertThat(deferredCompletingObserver2.deferred.await()).isEqualTo(MAGIC_STATE)
+
+        // Check removed observer is not notified after waiting a small time
+        assertThat(withTimeoutOrNull(100) { deferredCompletingObserver1.deferred.await() }).isNull()
+    }
+
+    @Test
+    fun doesNotObserveNewState_whenSetAfterRemovingAll(): Unit = runBlocking {
+        val observable = MutableStateObservable.withInitialState(INITIAL_STATE)
+
+        // Add the first observer to remove later
+        val deferredCompletingObserver1 = observable.addObserver(MAGIC_STATE)
+
+        // Remove first observer
+        observable.removeObservers()
+
+        // Add the observer to know if state was notified
+        val deferredCompletingObserver2 = observable.addObserver(MAGIC_STATE)
+
+        // Post the state
+        observable.setState(MAGIC_STATE)
+
+        // Wait for second observer to ensure observers were notified
+        assertThat(deferredCompletingObserver2.deferred.await()).isEqualTo(MAGIC_STATE)
+
+        // Check the removed observer is not notified after waiting a small time
+        assertThat(withTimeoutOrNull(100) { deferredCompletingObserver1.deferred.await() }).isNull()
+    }
+
+    data class DeferredCompletingObserver<T>(
+        val observer: Observer<T>,
+        val deferred: CompletableDeferred<T>
+    )
+
+    private fun <T> Observable<T>.addObserver(targetState: T): DeferredCompletingObserver<T> {
+        val deferred = CompletableDeferred<T>()
+        val observer =
+            object : Observer<T> {
+                override fun onNewData(state: T?) {
+                    if (state == targetState) {
+                        deferred.complete(targetState)
+                    }
+                }
+
+                override fun onError(t: Throwable) {
+                    deferred.completeExceptionally(t)
+                }
+            }
+
+        addObserver(Dispatchers.IO.asExecutor(), observer)
+
+        return DeferredCompletingObserver(observer, deferred)
+    }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java
index c2c1709..f4af2b5 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java
@@ -22,6 +22,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.camera.core.CameraControl;
 import androidx.camera.core.FocusMeteringAction;
 import androidx.camera.core.FocusMeteringResult;
@@ -158,6 +159,18 @@
         return this;
     }
 
+    /** Increments the count of whether this camera is being used for a video output or not. */
+    default void incrementVideoUsage() {}
+
+    /** Decrements the count of whether this camera is being used for a video output or not. */
+    default void decrementVideoUsage() {}
+
+    /** Gets the information of whether the camera is being used in a video output or not. */
+    @VisibleForTesting
+    default boolean isInVideoUsage() {
+        return false;
+    }
+
     @NonNull
     CameraControlInternal DEFAULT_EMPTY_INSTANCE = new CameraControlInternal() {
         @FlashMode
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraControl.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraControl.java
index 898a248..8413f33 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraControl.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraControl.java
@@ -20,6 +20,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.camera.core.FocusMeteringAction;
 import androidx.camera.core.FocusMeteringResult;
 import androidx.camera.core.ImageCapture;
@@ -156,4 +157,20 @@
     public CameraControlInternal getImplementation() {
         return mCameraControlInternal.getImplementation();
     }
+
+    @Override
+    public void incrementVideoUsage() {
+        mCameraControlInternal.incrementVideoUsage();
+    }
+
+    @Override
+    public void decrementVideoUsage() {
+        mCameraControlInternal.decrementVideoUsage();
+    }
+
+    @VisibleForTesting
+    @Override
+    public boolean isInVideoUsage() {
+        return mCameraControlInternal.isInVideoUsage();
+    }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/StateObservable.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/StateObservable.java
index ed3ab43..4892359 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/StateObservable.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/StateObservable.java
@@ -26,6 +26,7 @@
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Objects;
@@ -171,6 +172,17 @@
         }
     }
 
+    /**
+     * Remove all the observers currently added.
+     */
+    public void removeObservers() {
+        synchronized (mLock) {
+            for (Observer<? super T> observer : new HashSet<>(mWrapperMap.keySet())) {
+                removeObserverLocked(observer);
+            }
+        }
+    }
+
     @GuardedBy("mLock")
     private void removeObserverLocked(@NonNull Observable.Observer<? super T> observer) {
         ObserverWrapper<T> wrapper = mWrapperMap.remove(observer);
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
index 1717d7b..7a239b7 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
@@ -77,10 +77,18 @@
     public static final String CAMERA2_IMPLEMENTATION_OPTION = "camera2";
     public static final String CAMERA_PIPE_IMPLEMENTATION_OPTION = "camera_pipe";
 
+    private static boolean isAdvancedExtender() {
+        ExtensionVersionImpl extensionVersion = new ExtensionVersionImpl();
+        if (ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_2)
+                && extensionVersion.isAdvancedExtenderImplemented()) {
+            return true;
+        }
+        return false;
+    }
+
     // Check if the OEM implementation class for the given mode exists or not.
     private static boolean doesOEMImplementationExistForMode(int extensionMode) {
-        ExtensionVersionImpl extensionVersion = new ExtensionVersionImpl();
-        if (extensionVersion.isAdvancedExtenderImplemented()) {
+        if (isAdvancedExtender()) {
             try {
                 switch (extensionMode) {
                     case HDR:
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtensionDisabledQuirk.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtensionDisabledQuirk.java
index b07856e..d934a6f 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtensionDisabledQuirk.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtensionDisabledQuirk.java
@@ -40,7 +40,7 @@
 public class ExtensionDisabledQuirk implements Quirk {
 
     static boolean load() {
-        return isPixel5() || isMoto();
+        return isPixel5() || isMoto() || isRealme();
     }
 
     /**
@@ -53,6 +53,11 @@
         } else if (isMoto() && ExtensionVersion.isMaximumCompatibleVersion(Version.VERSION_1_1)) {
             // 2. Disables Motorola extensions capability for version 1.1 and older.
             return true;
+        } else if (isRealme() && ExtensionVersion.isMaximumCompatibleVersion(Version.VERSION_1_1)) {
+            // 2. Disables RealMe extensions capability for version 1.1 and older. RealMe devices'
+            // implementation only set the specific effect mode and have one critical bug that the
+            // the output image's timestamp doesn't match the timestamp in onCaptureStarted.
+            return true;
         }
 
         return false;
@@ -66,6 +71,10 @@
         return "motorola".equalsIgnoreCase(Build.BRAND);
     }
 
+    private static boolean isRealme() {
+        return "realme".equalsIgnoreCase(Build.BRAND);
+    }
+
     private static boolean isAdvancedExtenderSupported() {
         return ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_2)
                 && ExtensionVersion.isAdvancedExtenderSupported();
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
index a76e679..723a83e 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
@@ -31,6 +31,7 @@
 import androidx.camera.core.AspectRatio.RATIO_16_9
 import androidx.camera.core.AspectRatio.RATIO_4_3
 import androidx.camera.core.Camera
+import androidx.camera.core.CameraControl
 import androidx.camera.core.CameraInfo
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.CameraXConfig
@@ -41,6 +42,7 @@
 import androidx.camera.core.Preview
 import androidx.camera.core.UseCase
 import androidx.camera.core.UseCaseGroup
+import androidx.camera.core.impl.CameraControlInternal
 import androidx.camera.core.impl.utils.AspectRatioUtil.ASPECT_RATIO_16_9
 import androidx.camera.core.impl.utils.AspectRatioUtil.ASPECT_RATIO_3_4
 import androidx.camera.core.impl.utils.AspectRatioUtil.ASPECT_RATIO_4_3
@@ -77,10 +79,15 @@
 import java.io.File
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
 import org.junit.After
 import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeTrue
+import org.junit.AssumptionViolatedException
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.TemporaryFolder
@@ -183,6 +190,8 @@
 
     private lateinit var latchForVideoSaved: CountDownLatch
     private lateinit var latchForVideoRecording: CountDownLatch
+    private lateinit var latchForRecordingPause: CountDownLatch
+    private lateinit var latchForRecordingResume: CountDownLatch
 
     private lateinit var finalize: VideoRecordEvent.Finalize
     private lateinit var mockVideoRecordEventConsumer: MockConsumer<VideoRecordEvent>
@@ -213,9 +222,17 @@
                     // Make sure the recording proceed for a while.
                     latchForVideoRecording.countDown()
                 }
-                is VideoRecordEvent.Pause,
+                is VideoRecordEvent.Pause -> {
+                    Log.d(TAG, "Recording pause")
+                    if (::latchForRecordingPause.isInitialized) {
+                        latchForRecordingPause.countDown()
+                    }
+                }
                 is VideoRecordEvent.Resume -> {
-                    // no op for this test, skip these event now.
+                    Log.d(TAG, "Recording resume")
+                    if (::latchForRecordingResume.isInitialized) {
+                        latchForRecordingResume.countDown()
+                    }
                 }
                 else -> {
                     throw IllegalStateException()
@@ -1134,6 +1151,294 @@
         file2.delete()
     }
 
+    @Test
+    fun propagatesRecordingIsOngoingOrNot_whenRecordingStartedPausedResumedStopped(): Unit =
+        runBlocking {
+            implName.ignoreTestForCameraPipe(
+                "TODO: b/339615736 - Enable when implemented at camera-pipe"
+            )
+
+            // Pre-check and arrange
+            val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
+            latchForVideoSaved = CountDownLatch(1)
+            latchForRecordingPause = CountDownLatch(1)
+            latchForRecordingResume = CountDownLatch(1)
+            latchForVideoRecording = CountDownLatch(5)
+
+            val camera = bindUseCases()
+            // Act 1 - isRecording is true after start.
+            val recording = startVideoRecording(videoCapture, file)
+            camera.cameraControl.verifyIfInVideoUsage(
+                true,
+                "Video started but camera still not in video usage"
+            )
+
+            // Act 2 - isRecording is false after pause.
+            pauseVideoRecording(videoCapture, file, recording)
+            camera.cameraControl.verifyIfInVideoUsage(
+                false,
+                "Video paused but camera still in video usage"
+            )
+
+            // Act 3 - isRecording is true after resume.
+            resumeVideoRecording(videoCapture, file, recording)
+            camera.cameraControl.verifyIfInVideoUsage(
+                true,
+                "Video resumed but camera still not in video usage"
+            )
+
+            // Act 4 - isRecording is false after stop.
+            completeVideoRecording(videoCapture, file, recording)
+            camera.cameraControl.verifyIfInVideoUsage(
+                false,
+                "Video stopped but camera still in video usage"
+            )
+
+            // Cleanup.
+            file.delete()
+        }
+
+    @Test
+    fun propagatesRecordingIsOngoingOrNot_whenUnboundBeforeCompletingAndNewVidStartedAfterRebind() =
+        runBlocking {
+            implName.ignoreTestForCameraPipe(
+                "TODO: b/339615736 - Enable when implemented at camera-pipe"
+            )
+
+            // Pre-check and arrange
+            val file1 = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
+            latchForVideoSaved = CountDownLatch(1)
+            latchForVideoRecording = CountDownLatch(5)
+
+            val camera = bindUseCases()
+            val recording1 = startVideoRecording(videoCapture, file1)
+
+            // Act 1 - unbind before recording completes and check if isRecording is false.
+            instrumentation.runOnMainSync { cameraProvider.unbind(videoCapture) }
+
+            camera.cameraControl.verifyIfInVideoUsage(
+                false,
+                "Video stopped but camera still in video usage"
+            )
+
+            // Cleanup.
+            // Unbind may lead to SOURCE_INACTIVE error while stop may lead to no error, but neither
+            // is important for this test, so allowError is set to true
+            completeVideoRecording(videoCapture, file1, recording1, allowError = true)
+            file1.delete()
+
+            // Pre-check and arrange
+            val file2 = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
+            latchForVideoSaved = CountDownLatch(1)
+            latchForVideoRecording = CountDownLatch(5)
+
+            // Act 2 - rebind and start new recording, check if isRecording is true now.
+            bindUseCases()
+
+            val recording2 = startVideoRecording(videoCapture, file2)
+            camera.cameraControl.verifyIfInVideoUsage(
+                true,
+                "Video started but camera still not in video usage"
+            )
+
+            // Cleanup.
+            completeVideoRecording(videoCapture, file2, recording2)
+            file2.delete()
+
+            Unit
+        }
+
+    @Test
+    fun propagatesRecordingIsNotOngoing_whenLifecycleStoppedBeforeCompletingRecording(): Unit =
+        runBlocking {
+            implName.ignoreTestForCameraPipe(
+                "TODO: b/339615736 - Enable when implemented at camera-pipe"
+            )
+
+            // Pre-check and arrange
+            val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
+            latchForVideoSaved = CountDownLatch(1)
+            latchForVideoRecording = CountDownLatch(5)
+
+            val camera = bindUseCases()
+            startVideoRecording(videoCapture, file)
+
+            // Act.
+            instrumentation.runOnMainSync { lifecycleOwner.pauseAndStop() }
+
+            camera.cameraControl.verifyIfInVideoUsage(
+                false,
+                "Lifecycle stopped but camera still in video usage"
+            )
+
+            // Cleanup.
+            file.delete()
+        }
+
+    @Ignore("TODO: b/342977497 - Temporarily ignored for persistent recording.")
+    @Test
+    fun propagatesRecordingIsOngoingOrNot_whenUseCaseUnboundAndReboundForPersistentRecording() =
+        runBlocking {
+            assumeFalse(
+                "TODO: b/340406044 - Temporarily ignored when stream sharing is enabled.",
+                forceEnableStreamSharing
+            )
+
+            implName.ignoreTestForCameraPipe(
+                "TODO: b/339615736 - Enable when implemented at camera-pipe"
+            )
+
+            // Pre-check and arrange
+            val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
+            latchForVideoSaved = CountDownLatch(1)
+            latchForVideoRecording = CountDownLatch(5)
+
+            val camera = bindUseCases()
+            val recording = startVideoRecording(videoCapture, file, isPersistentRecording = true)
+
+            // Act 1 - unbind VideoCapture before recording completes, isRecording should be false.
+            instrumentation.runOnMainSync { cameraProvider.unbind(videoCapture) }
+
+            camera.cameraControl.verifyIfInVideoUsage(
+                false,
+                "VideoCapture unbound but camera still in video usage"
+            )
+
+            // Act 2 - rebind VideoCapture, isRecording should be true.
+            bindUseCases(bindPreview = false)
+
+            camera.cameraControl.verifyIfInVideoUsage(
+                true,
+                "VideoCapture re-bound but camera still not in video usage"
+            )
+
+            // Cleanup.
+            completeVideoRecording(videoCapture, file, recording)
+            file.delete()
+
+            Unit
+        }
+
+    @Ignore("TODO: b/342977497 - Temporarily ignored for persistent recording.")
+    @Test
+    fun propagatesRecordingIsOngoingOrNot_whenUseCaseBoundToNewCameraForPersistentRecording() =
+        runBlocking {
+            assumeFalse(
+                "TODO: b/340406044 - Temporarily ignored when stream sharing is enabled.",
+                forceEnableStreamSharing
+            )
+
+            implName.ignoreTestForCameraPipe(
+                "TODO: b/339615736 - Enable when implemented at camera-pipe"
+            )
+
+            // Pre-check and arrange
+            val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
+            latchForVideoSaved = CountDownLatch(1)
+            latchForVideoRecording = CountDownLatch(5)
+
+            val camera1 = bindUseCases()
+            val recording = startVideoRecording(videoCapture, file, isPersistentRecording = true)
+
+            // Act 1 - unbind before recording completes, isRecording should be false.
+            instrumentation.runOnMainSync { cameraProvider.unbindAll() }
+
+            camera1.cameraControl.verifyIfInVideoUsage(
+                false,
+                "VideoCapture unbound but camera still in video usage"
+            )
+
+            // Act 2 - rebind VideoCapture to opposite camera, isRecording should be true.
+            val camera2 = bindUseCases(useOppositeCamera = true)
+
+            camera2.cameraControl.verifyIfInVideoUsage(
+                true,
+                "VideoCapture re-bound but camera still not in video usage"
+            )
+
+            // Cleanup.
+            completeVideoRecording(videoCapture, file, recording)
+            file.delete()
+
+            Unit
+        }
+
+    @Test
+    fun propagatesRecordingIsNotOngoing_whenLifecycleStoppedBeforeCompletingPersistentRecording() =
+        runBlocking {
+            assumeFalse(
+                "TODO: b/340406044 - Temporarily ignored when stream sharing is enabled.",
+                forceEnableStreamSharing
+            )
+
+            implName.ignoreTestForCameraPipe(
+                "TODO: b/339615736 - Enable when implemented at camera-pipe"
+            )
+
+            // Pre-check and arrange
+            val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
+            latchForVideoSaved = CountDownLatch(1)
+            latchForVideoRecording = CountDownLatch(5)
+
+            val camera = bindUseCases()
+            startVideoRecording(videoCapture, file, isPersistentRecording = true)
+
+            // Act.
+            instrumentation.runOnMainSync { lifecycleOwner.pauseAndStop() }
+
+            camera.cameraControl.verifyIfInVideoUsage(
+                false,
+                "Lifecycle stopped but camera still in video usage"
+            )
+
+            // Cleanup.
+            file.delete()
+
+            Unit
+        }
+
+    // TODO: b/341691683 - Add tests for multiple VideoCapture bound and recording concurrently
+
+    /**
+     * Binds VideoCapture use case to [cameraProvider] as per [cameraSelector].
+     *
+     * @param useOppositeCamera Whether to bind to [cameraSelector] or its opposite one.
+     * @throws AssumptionViolatedException When [useOppositeCamera] is true but can't be resolved.
+     */
+    private suspend fun bindUseCases(
+        bindPreview: Boolean = true,
+        useOppositeCamera: Boolean = false,
+    ): Camera {
+        val cameraSelector =
+            if (!useOppositeCamera) {
+                cameraSelector
+            } else {
+                when (cameraSelector.lensFacing) {
+                    CameraSelector.LENS_FACING_BACK -> CameraSelector.DEFAULT_FRONT_CAMERA
+                    CameraSelector.LENS_FACING_FRONT -> CameraSelector.DEFAULT_BACK_CAMERA
+                    else -> {
+                        throw AssumptionViolatedException(
+                            "Could not find opposite camera for $cameraSelector"
+                        )
+                    }
+                }
+            }
+
+        return withContext(Dispatchers.Main) {
+            cameraProvider.bindToLifecycle(
+                lifecycleOwner,
+                cameraSelector,
+                *mutableListOf<UseCase>(videoCapture)
+                    .apply {
+                        if (bindPreview) {
+                            add(preview)
+                        }
+                    }
+                    .toTypedArray()
+            )
+        }
+    }
+
     private fun performRecording(
         videoCapture: VideoCapture<Recorder>,
         file: File,
@@ -1196,10 +1501,19 @@
         }
     }
 
-    private fun startVideoRecording(videoCapture: VideoCapture<Recorder>, file: File): Recording {
+    private fun startVideoRecording(
+        videoCapture: VideoCapture<Recorder>,
+        file: File,
+        isPersistentRecording: Boolean = false,
+    ): Recording {
         val recording =
             videoCapture.output
                 .prepareRecording(context, FileOutputOptions.Builder(file).build())
+                .apply {
+                    if (isPersistentRecording) {
+                        asPersistentRecording()
+                    }
+                }
                 .start(CameraXExecutors.directExecutor(), videoRecordEventListener)
 
         try {
@@ -1213,17 +1527,22 @@
         return recording
     }
 
-    private fun completeVideoRecording(videoCapture: VideoCapture<Recorder>, file: File) {
-        val recording = startVideoRecording(videoCapture, file)
-
-        recording.stop()
+    private fun completeVideoRecording(
+        videoCapture: VideoCapture<Recorder>,
+        file: File,
+        recording: Recording = startVideoRecording(videoCapture, file),
+        allowError: Boolean = false,
+    ) {
+        recording.close()
         // Wait for finalize event to saved file.
         assertThat(latchForVideoSaved.await(VIDEO_TIMEOUT_SEC, TimeUnit.SECONDS)).isTrue()
 
         // Check if any error after recording finalized
-        assertWithMessage(TAG + "Finalize with error: ${finalize.error}, ${finalize.cause}.")
-            .that(finalize.hasError())
-            .isFalse()
+        if (!allowError) {
+            assertWithMessage(TAG + "Finalize with error: ${finalize.error}, ${finalize.cause}.")
+                .that(finalize.hasError())
+                .isFalse()
+        }
     }
 
     private fun completeImageCapture(
@@ -1255,6 +1574,38 @@
         imageCapture.screenFlash = null
     }
 
+    private fun pauseVideoRecording(
+        videoCapture: VideoCapture<Recorder>,
+        file: File,
+        recording: Recording = startVideoRecording(videoCapture, file)
+    ) {
+        recording.pause()
+
+        try {
+            // Wait for status event to proceed recording for a while.
+            assertThat(latchForRecordingPause.await(VIDEO_TIMEOUT_SEC, TimeUnit.SECONDS)).isTrue()
+        } catch (ex: Exception) {
+            recording.stop()
+            throw ex
+        }
+    }
+
+    private fun resumeVideoRecording(
+        videoCapture: VideoCapture<Recorder>,
+        file: File,
+        recording: Recording = startVideoRecording(videoCapture, file)
+    ) {
+        recording.resume()
+
+        try {
+            // Wait for status event to proceed recording for a while.
+            assertThat(latchForRecordingResume.await(VIDEO_TIMEOUT_SEC, TimeUnit.SECONDS)).isTrue()
+        } catch (ex: Exception) {
+            recording.stop()
+            throw ex
+        }
+    }
+
     data class ExpectedRotation(val contentRotation: Int, val metadataRotation: Int)
 
     private fun getExpectedRotation(
@@ -1414,6 +1765,20 @@
         output
             .prepareRecording(context, FileOutputOptions.Builder(file).build())
             .start(CameraXExecutors.directExecutor(), eventListener)
+
+    private fun CameraControl.verifyIfInVideoUsage(expected: Boolean, message: String = "") {
+        instrumentation.waitForIdleSync() // VideoCapture observes Recorder in main thread
+        assertWithMessage(message).that((this as CameraControlInternal).isInVideoUsage).apply {
+            if (expected) {
+                isTrue()
+            } else {
+                isFalse()
+            }
+        }
+    }
+
+    private fun String.ignoreTestForCameraPipe(message: String) =
+        assumeTrue(message, !this.contains(CameraPipeConfig::class.simpleName!!))
 }
 
 private class VideoCaptureMonitor : Consumer<VideoRecordEvent> {
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 4c4977a..aee88cb 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
@@ -354,6 +354,9 @@
     static long sRetrySetupVideoDelayMs = RETRY_SETUP_VIDEO_DELAY_MS;
 
     private final MutableStateObservable<StreamInfo> mStreamInfo;
+
+    private final MutableStateObservable<Boolean> mIsRecording;
+
     // Used only by getExecutor()
     private final Executor mUserProvidedExecutor;
     // May be equivalent to mUserProvidedExecutor or an internal executor if the user did not
@@ -508,6 +511,7 @@
         mVideoCapabilitiesSource = videoCapabilitiesSource;
         mStreamInfo = MutableStateObservable.withInitialState(
                 StreamInfo.of(mStreamId, internalStateToStreamState(mState)));
+        mIsRecording = MutableStateObservable.withInitialState(false);
         mVideoEncoderFactory = videoEncoderFactory;
         mAudioEncoderFactory = audioEncoderFactory;
         mVideoEncoderSession =
@@ -548,6 +552,13 @@
 
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @Override
+    @NonNull
+    public Observable<Boolean> isSourceStreamRequired() {
+        return mIsRecording;
+    }
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Override
     public void onSourceStateChanged(@NonNull SourceState newState) {
         mSequentialExecutor.execute(() -> onSourceStateChangedInternal(newState));
     }
@@ -2449,6 +2460,7 @@
                         + "finalize.");
             }
 
+            mActiveRecordingRecord.getRecordingState().removeObservers();
             mActiveRecordingRecord = null;
             switch (mState) {
                 case RESETTING:
@@ -2661,6 +2673,18 @@
         }
         // Swap the pending recording to the active recording and start it
         RecordingRecord recordingToStart = mActiveRecordingRecord = mPendingRecordingRecord;
+        mActiveRecordingRecord.getRecordingState().addObserver(CameraXExecutors.directExecutor(),
+                new Observable.Observer<Boolean>() {
+                    @Override
+                    public void onNewData(@Nullable Boolean value) {
+                        mIsRecording.setState(value);
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable t) {
+                        mIsRecording.setError(t);
+                    }
+                });
         mPendingRecordingRecord = null;
         // Start recording if start() has been called before video encoder is setup.
         if (startRecordingPaused) {
@@ -2938,6 +2962,10 @@
         private final AtomicBoolean mMuted = new AtomicBoolean(false);
 
         @NonNull
+        private final MutableStateObservable<Boolean> mRecordingState =
+                MutableStateObservable.withInitialState(false);
+
+        @NonNull
         static RecordingRecord from(@NonNull PendingRecording pendingRecording, long recordingId) {
             return new AutoValue_Recorder_RecordingRecord(
                     pendingRecording.getOutputOptions(),
@@ -3188,6 +3216,7 @@
                 }
             }
             Logger.d(TAG, message);
+            updateRecordingState(event);
             if (getCallbackExecutor() != null && getEventListener() != null) {
                 try {
                     getCallbackExecutor().execute(() -> getEventListener().accept(event));
@@ -3197,6 +3226,23 @@
             }
         }
 
+        private void updateRecordingState(@NonNull VideoRecordEvent event) {
+            if (event instanceof VideoRecordEvent.Start
+                    || event instanceof VideoRecordEvent.Resume) {
+                mRecordingState.setState(true);
+            } else if (event instanceof VideoRecordEvent.Pause
+                    || event instanceof VideoRecordEvent.Finalize) {
+                mRecordingState.setState(false);
+            }
+        }
+
+        // Provides only true/false i.e. whether recording or not right now. More states can be
+        // added later if ever required.
+        @NonNull
+        StateObservable<Boolean> getRecordingState() {
+            return mRecordingState;
+        }
+
         /**
          * Creates an {@link AudioSource} for this recording.
          *
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 a162e04..86165ee 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
@@ -89,6 +89,7 @@
 import androidx.camera.core.ViewPort;
 import androidx.camera.core.impl.CameraCaptureCallback;
 import androidx.camera.core.impl.CameraCaptureResult;
+import androidx.camera.core.impl.CameraControlInternal;
 import androidx.camera.core.impl.CameraInfoInternal;
 import androidx.camera.core.impl.CameraInternal;
 import androidx.camera.core.impl.CaptureConfig;
@@ -207,6 +208,8 @@
     private Rect mCropRect;
     private int mRotationDegrees;
     private boolean mHasCompensatingTransformation = false;
+    @Nullable
+    private SourceStreamRequirementObserver mSourceStreamRequirementObserver;
 
     /**
      * Create a VideoCapture associated with the given {@link VideoOutput}.
@@ -389,6 +392,9 @@
     @Override
     public void onStateAttached() {
         super.onStateAttached();
+
+        Logger.d(TAG, "VideoCapture#onStateAttached: cameraID = " + getCameraId());
+
         Preconditions.checkNotNull(getAttachedStreamSpec(), "The suggested stream "
                 + "specification should be already updated and shouldn't be null.");
         Preconditions.checkState(mSurfaceRequest == null, "The surface request should be null "
@@ -405,6 +411,15 @@
         notifyActive();
         getOutput().getStreamInfo().addObserver(CameraXExecutors.mainThreadExecutor(),
                 mStreamInfoObserver);
+        if (mSourceStreamRequirementObserver != null) {
+            // In case a previous observer was not closed, close it first
+            mSourceStreamRequirementObserver.close();
+        }
+        // Camera should be already bound by now, so calling getCameraControl() is ok
+        mSourceStreamRequirementObserver = new SourceStreamRequirementObserver(getCameraControl());
+        // Should automatically trigger once for latest data
+        getOutput().isSourceStreamRequired().addObserver(CameraXExecutors.mainThreadExecutor(),
+                mSourceStreamRequirementObserver);
         setSourceState(VideoOutput.SourceState.ACTIVE_NON_STREAMING);
     }
 
@@ -424,9 +439,22 @@
     @RestrictTo(Scope.LIBRARY_GROUP)
     @Override
     public void onStateDetached() {
+        Logger.d(TAG, "VideoCapture#onStateDetached");
+
         checkState(isMainThread(), "VideoCapture can only be detached on the main thread.");
+
+        // It's safer to remove and close mSourceStreamRequirementObserver before stopping recorder
+        // in case there is some bug leading to double video usage decrement updates (e.g. once for
+        // recorder stop and once for observer close)
+        if (mSourceStreamRequirementObserver != null) {
+            getOutput().isSourceStreamRequired().removeObserver(mSourceStreamRequirementObserver);
+            mSourceStreamRequirementObserver.close();
+            mSourceStreamRequirementObserver = null;
+        }
+
         setSourceState(VideoOutput.SourceState.INACTIVE);
         getOutput().getStreamInfo().removeObserver(mStreamInfoObserver);
+
         if (mSurfaceUpdateFuture != null) {
             if (mSurfaceUpdateFuture.cancel(false)) {
                 Logger.d(TAG, "VideoCapture is detached from the camera. Surface update "
@@ -866,6 +894,74 @@
         }
     };
 
+    /**
+     * Observes whether the source stream is required and updates source i.e. camera layer
+     * accordingly.
+     */
+    static class SourceStreamRequirementObserver implements Observer<Boolean> {
+        @Nullable
+        private CameraControlInternal mCameraControl;
+
+        private boolean mIsSourceStreamRequired = false;
+
+        SourceStreamRequirementObserver(@NonNull CameraControlInternal cameraControl) {
+            mCameraControl = cameraControl;
+        }
+
+        @MainThread
+        @Override
+        public void onNewData(@Nullable Boolean value) {
+            checkState(isMainThread(),
+                    "SourceStreamRequirementObserver can be updated from main thread only");
+            updateVideoUsageInCamera(Boolean.TRUE.equals(value));
+        }
+
+        @Override
+        public void onError(@NonNull Throwable t) {
+            Logger.w(TAG, "SourceStreamRequirementObserver#onError", t);
+        }
+
+        private void updateVideoUsageInCamera(boolean isRequired) {
+            if (mIsSourceStreamRequired == isRequired) {
+                return;
+            }
+            mIsSourceStreamRequired = isRequired;
+            if (mCameraControl != null) {
+                if (mIsSourceStreamRequired) {
+                    mCameraControl.incrementVideoUsage();
+                } else {
+                    mCameraControl.decrementVideoUsage();
+                }
+            } else {
+                Logger.d(TAG,
+                        "SourceStreamRequirementObserver#isSourceStreamRequired: Received"
+                                + " new data despite being closed already");
+            }
+        }
+
+        /**
+         * Closes this object to detach the association with camera and updates recording status if
+         * required.
+         */
+        @MainThread
+        public void close() {
+            checkState(isMainThread(),
+                    "SourceStreamRequirementObserver can be closed from main thread only");
+
+            Logger.d(TAG, "SourceStreamRequirementObserver#close: mIsSourceStreamRequired = "
+                    + mIsSourceStreamRequired);
+
+            if (mCameraControl == null) {
+                Logger.d(TAG, "SourceStreamRequirementObserver#close: Already closed!");
+                return;
+            }
+
+            // Before removing the camera, it should be updated about recording status
+            updateVideoUsageInCamera(false);
+            mCameraControl = null;
+        }
+    }
+
     @MainThread
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     void applyStreamInfoAndStreamSpecToSessionConfigBuilder(
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoOutput.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoOutput.java
index 41d2e01..cba733b 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoOutput.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoOutput.java
@@ -130,6 +130,20 @@
     }
 
     /**
+     * Returns an observable to know if the streaming from a video frame producer is required.
+     *
+     * <p> This should be true for cases like when user is starting a video recording or streaming
+     * and false when user has decided to stop the recording/streaming. The video frame producer
+     * will use this information to do know whether it's now safe to do operations which may disrupt
+     * video quality/consistency (e.g. AE precapture).
+     */
+    @RestrictTo(Scope.LIBRARY)
+    @NonNull
+    default Observable<Boolean> isSourceStreamRequired() {
+        return ConstantObservable.withValue(false);
+    }
+
+    /**
      * Called when the state of the video frame producer is changed.
      */
     @RestrictTo(Scope.LIBRARY)
diff --git a/camera/camera-viewfinder-core/api/current.txt b/camera/camera-viewfinder-core/api/current.txt
index 81f2ad3..31ea519 100644
--- a/camera/camera-viewfinder-core/api/current.txt
+++ b/camera/camera-viewfinder-core/api/current.txt
@@ -38,15 +38,15 @@
   }
 
   public static final class ZoomGestureDetector.ZoomEvent.End extends androidx.camera.viewfinder.core.ZoomGestureDetector.ZoomEvent {
-    ctor public ZoomGestureDetector.ZoomEvent.End(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float scaleFactor);
-    method public float getScaleFactor();
-    property public final float scaleFactor;
+    ctor public ZoomGestureDetector.ZoomEvent.End(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float incrementalScaleFactor);
+    method public float getIncrementalScaleFactor();
+    property public final float incrementalScaleFactor;
   }
 
   public static final class ZoomGestureDetector.ZoomEvent.Move extends androidx.camera.viewfinder.core.ZoomGestureDetector.ZoomEvent {
-    ctor public ZoomGestureDetector.ZoomEvent.Move(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float scaleFactor);
-    method public float getScaleFactor();
-    property public final float scaleFactor;
+    ctor public ZoomGestureDetector.ZoomEvent.Move(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float incrementalScaleFactor);
+    method public float getIncrementalScaleFactor();
+    property public final float incrementalScaleFactor;
   }
 
 }
diff --git a/camera/camera-viewfinder-core/api/restricted_current.txt b/camera/camera-viewfinder-core/api/restricted_current.txt
index 81f2ad3..31ea519 100644
--- a/camera/camera-viewfinder-core/api/restricted_current.txt
+++ b/camera/camera-viewfinder-core/api/restricted_current.txt
@@ -38,15 +38,15 @@
   }
 
   public static final class ZoomGestureDetector.ZoomEvent.End extends androidx.camera.viewfinder.core.ZoomGestureDetector.ZoomEvent {
-    ctor public ZoomGestureDetector.ZoomEvent.End(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float scaleFactor);
-    method public float getScaleFactor();
-    property public final float scaleFactor;
+    ctor public ZoomGestureDetector.ZoomEvent.End(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float incrementalScaleFactor);
+    method public float getIncrementalScaleFactor();
+    property public final float incrementalScaleFactor;
   }
 
   public static final class ZoomGestureDetector.ZoomEvent.Move extends androidx.camera.viewfinder.core.ZoomGestureDetector.ZoomEvent {
-    ctor public ZoomGestureDetector.ZoomEvent.Move(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float scaleFactor);
-    method public float getScaleFactor();
-    property public final float scaleFactor;
+    ctor public ZoomGestureDetector.ZoomEvent.Move(@IntRange(from=0L) long eventTime, @IntRange(from=0L) @Px int focusX, @IntRange(from=0L) @Px int focusY, @FloatRange(from=0.0, fromInclusive=false) float incrementalScaleFactor);
+    method public float getIncrementalScaleFactor();
+    property public final float incrementalScaleFactor;
   }
 
 }
diff --git a/camera/camera-viewfinder-core/samples/src/main/java/androidx/camera/viewfinder/core/samples/ZoomGestureDetectorSamples.kt b/camera/camera-viewfinder-core/samples/src/main/java/androidx/camera/viewfinder/core/samples/ZoomGestureDetectorSamples.kt
index bafee72c..4b87a61 100644
--- a/camera/camera-viewfinder-core/samples/src/main/java/androidx/camera/viewfinder/core/samples/ZoomGestureDetectorSamples.kt
+++ b/camera/camera-viewfinder-core/samples/src/main/java/androidx/camera/viewfinder/core/samples/ZoomGestureDetectorSamples.kt
@@ -37,7 +37,7 @@
             when (zoomEvent) {
                 is ZoomEvent.Move -> {
                     val zoomState = camera.cameraInfo.zoomState.value!!
-                    val ratio = zoomState.zoomRatio * zoomEvent.scaleFactor
+                    val ratio = zoomState.zoomRatio * zoomEvent.incrementalScaleFactor
                     val minRatio = zoomState.minZoomRatio
                     val maxRatio = zoomState.maxZoomRatio
                     val clampedRatio = min(max(ratio, minRatio), maxRatio)
diff --git a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/core/ZoomGestureDetector.kt b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/core/ZoomGestureDetector.kt
index 89352f7..c78c9a4 100644
--- a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/core/ZoomGestureDetector.kt
+++ b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/core/ZoomGestureDetector.kt
@@ -38,9 +38,9 @@
  *
  * To use this class to do pinch-to-zoom on the viewfinder:
  * - In the [OnZoomGestureListener.onZoomEvent], when receiving [ZoomEvent.Move], get the
- *   [ZoomEvent.Move.scaleFactor] and use the value with `CameraControl.setZoomRatio` if the factor
- *   is in the range of `ZoomState.getMinZoomRatio` and `ZoomState.getMaxZoomRatio`. Then create an
- *   instance of the `ZoomGestureDetector` with the [OnZoomGestureListener].
+ *   [ZoomEvent.Move.incrementalScaleFactor] and use the value with `CameraControl.setZoomRatio` if
+ *   the factor is in the range of `ZoomState.getMinZoomRatio` and `ZoomState.getMaxZoomRatio`. Then
+ *   create an instance of the `ZoomGestureDetector` with the [OnZoomGestureListener].
  * - In the [View.onTouchEvent], call [onTouchEvent] and pass the [MotionEvent]s to the
  *   `ZoomGestureDetector`.
  *
@@ -99,15 +99,15 @@
          *   [SystemClock.uptimeMillis] time base.
          * @param focusX The X coordinate of the current gesture's focal point in pixels.
          * @param focusY The Y coordinate of the current gesture's focal point in pixels.
-         * @param scaleFactor The scaling factor from the previous zoom event to the current event.
-         *   The value will be less than `1.0` when zooming out (larger FOV) and will be larger than
-         *   `1.0` when zooming in (narrower FOV).
+         * @param incrementalScaleFactor The scaling factor from the previous zoom event to the
+         *   current event. The value will be less than `1.0` when zooming out (larger FOV) and will
+         *   be larger than `1.0` when zooming in (narrower FOV).
          */
         class Move(
             @IntRange(from = 0) eventTime: Long,
             @Px @IntRange(from = 0) focusX: Int,
             @Px @IntRange(from = 0) focusY: Int,
-            @FloatRange(from = 0.0, fromInclusive = false) val scaleFactor: Float
+            @FloatRange(from = 0.0, fromInclusive = false) val incrementalScaleFactor: Float
         ) : ZoomEvent(eventTime, focusX, focusY)
 
         /**
@@ -117,15 +117,15 @@
          *   [SystemClock.uptimeMillis] time base.
          * @param focusX The X coordinate of the current gesture's focal point in pixels.
          * @param focusY The Y coordinate of the current gesture's focal point in pixels.
-         * @param scaleFactor The scaling factor from the previous zoom event to the current event.
-         *   The value will be less than `1.0` when zooming out (larger FOV) and will be larger than
-         *   `1.0` when zooming in (narrower FOV).
+         * @param incrementalScaleFactor The scaling factor from the previous zoom event to the
+         *   current event. The value will be less than `1.0` when zooming out (larger FOV) and will
+         *   be larger than `1.0` when zooming in (narrower FOV).
          */
         class End(
             @IntRange(from = 0) eventTime: Long,
             @Px @IntRange(from = 0) focusX: Int,
             @Px @IntRange(from = 0) focusY: Int,
-            @FloatRange(from = 0.0, fromInclusive = false) val scaleFactor: Float
+            @FloatRange(from = 0.0, fromInclusive = false) val incrementalScaleFactor: Float
         ) : ZoomEvent(eventTime, focusX, focusY)
     }
 
@@ -295,7 +295,9 @@
             // If it's an ACTION_DOWN we're beginning a new event stream.
             // This means the app probably didn't give us all the events.
             if (isInProgress) {
-                listener.onZoomEvent(ZoomEvent.End(eventTime, focusX, focusY, getScaleFactor()))
+                listener.onZoomEvent(
+                    ZoomEvent.End(eventTime, focusX, focusY, getIncrementalScaleFactor())
+                )
                 isInProgress = false
                 initialSpan = 0f
                 anchoredZoomMode = ANCHORED_ZOOM_MODE_NONE
@@ -391,7 +393,9 @@
         focusX = focusXFloat.roundToInt()
         focusY = focusYFloat.roundToInt()
         if (!inAnchoredZoomMode() && isInProgress && (span < minSpan || configChanged)) {
-            listener.onZoomEvent(ZoomEvent.End(eventTime, focusX, focusY, getScaleFactor()))
+            listener.onZoomEvent(
+                ZoomEvent.End(eventTime, focusX, focusY, getIncrementalScaleFactor())
+            )
             isInProgress = false
             initialSpan = span
         }
@@ -431,7 +435,7 @@
             if (isInProgress) {
                 updatePrev =
                     listener.onZoomEvent(
-                        ZoomEvent.Move(eventTime, focusX, focusY, getScaleFactor())
+                        ZoomEvent.Move(eventTime, focusX, focusY, getIncrementalScaleFactor())
                     )
             }
 
@@ -449,7 +453,7 @@
         return anchoredZoomMode != ANCHORED_ZOOM_MODE_NONE
     }
 
-    private fun getScaleFactor(): Float {
+    private fun getIncrementalScaleFactor(): Float {
         if (inAnchoredZoomMode()) {
             // Drag is moving up; the further away from the gesture start, the smaller the span
             // should be, the closer, the larger the span, and therefore the larger the scale
diff --git a/camera/integration-tests/avsynctestapp/build.gradle b/camera/integration-tests/avsynctestapp/build.gradle
index a6ed4ed..f0ab3dc 100644
--- a/camera/integration-tests/avsynctestapp/build.gradle
+++ b/camera/integration-tests/avsynctestapp/build.gradle
@@ -66,7 +66,7 @@
     // Align dependencies in debugRuntimeClasspath and debugAndroidTestRuntimeClasspath.
     androidTestImplementation("androidx.annotation:annotation-experimental:1.4.0")
     androidTestImplementation("androidx.annotation:annotation:1.8.0")
-    androidTestImplementation("androidx.lifecycle:lifecycle-common:2.8.0")
+    androidTestImplementation("androidx.lifecycle:lifecycle-common:2.8.2")
 
     // Testing framework
     testImplementation(libs.kotlinCoroutinesTest)
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index 2984c65..5c24553 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -882,7 +882,7 @@
     method public androidx.car.app.model.Header? getHeader();
   }
 
-  public static final class MediaPlaybackTemplate.Builder {
+  @SuppressCompatibility @androidx.car.app.annotations.ExperimentalCarApi public static final class MediaPlaybackTemplate.Builder {
     ctor public MediaPlaybackTemplate.Builder();
     ctor public MediaPlaybackTemplate.Builder(androidx.car.app.media.model.MediaPlaybackTemplate);
     method public androidx.car.app.media.model.MediaPlaybackTemplate build();
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index 2984c65..5c24553 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -882,7 +882,7 @@
     method public androidx.car.app.model.Header? getHeader();
   }
 
-  public static final class MediaPlaybackTemplate.Builder {
+  @SuppressCompatibility @androidx.car.app.annotations.ExperimentalCarApi public static final class MediaPlaybackTemplate.Builder {
     ctor public MediaPlaybackTemplate.Builder();
     ctor public MediaPlaybackTemplate.Builder(androidx.car.app.media.model.MediaPlaybackTemplate);
     method public androidx.car.app.media.model.MediaPlaybackTemplate build();
diff --git a/car/app/app/src/main/java/androidx/car/app/media/model/MediaPlaybackTemplate.java b/car/app/app/src/main/java/androidx/car/app/media/model/MediaPlaybackTemplate.java
index 5ac5643..507f249 100644
--- a/car/app/app/src/main/java/androidx/car/app/media/model/MediaPlaybackTemplate.java
+++ b/car/app/app/src/main/java/androidx/car/app/media/model/MediaPlaybackTemplate.java
@@ -87,6 +87,7 @@
     }
 
     /** Builder for the {@link MediaPlaybackTemplate} */
+    @ExperimentalCarApi
     public static final class Builder {
         @Nullable
         Header mHeader;
diff --git a/compose/animation/animation-core/api/current.txt b/compose/animation/animation-core/api/current.txt
index 8c561f6..985b8c6 100644
--- a/compose/animation/animation-core/api/current.txt
+++ b/compose/animation/animation-core/api/current.txt
@@ -158,7 +158,7 @@
     method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> copy(androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D>, optional float value, optional float velocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
     method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
     method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T value);
-    method public static boolean isFinished(androidx.compose.animation.core.AnimationState<? extends java.lang.Object!,? extends java.lang.Object!>);
+    method public static boolean isFinished(androidx.compose.animation.core.AnimationState<? extends java.lang.Object?,? extends java.lang.Object?>);
   }
 
   public abstract sealed class AnimationVector {
@@ -448,9 +448,9 @@
   }
 
   public final class InfiniteTransition {
-    method public java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> getAnimations();
+    method public java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> getAnimations();
     method public String getLabel();
-    property public final java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> animations;
+    property public final java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> animations;
     property public final String label;
   }
 
@@ -648,16 +648,16 @@
   }
 
   @androidx.compose.runtime.Stable public final class Transition<S> {
-    method public java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> getAnimations();
+    method public java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> getAnimations();
     method public S getCurrentState();
     method @SuppressCompatibility @androidx.compose.animation.core.InternalAnimationApi public boolean getHasInitialValueAnimations();
     method public String? getLabel();
     method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
     method public S getTargetState();
     method public long getTotalDurationNanos();
-    method public java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object!>> getTransitions();
+    method public java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object?>> getTransitions();
     method public boolean isRunning();
-    property public final java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> animations;
+    property public final java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> animations;
     property public final S currentState;
     property @SuppressCompatibility @androidx.compose.animation.core.InternalAnimationApi public final boolean hasInitialValueAnimations;
     property public final boolean isRunning;
@@ -665,7 +665,7 @@
     property public final androidx.compose.animation.core.Transition.Segment<S> segment;
     property public final S targetState;
     property public final long totalDurationNanos;
-    property public final java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object!>> transitions;
+    property public final java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object?>> transitions;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface Transition.Segment<S> {
diff --git a/compose/animation/animation-core/api/restricted_current.txt b/compose/animation/animation-core/api/restricted_current.txt
index 6e1c258..49922b8 100644
--- a/compose/animation/animation-core/api/restricted_current.txt
+++ b/compose/animation/animation-core/api/restricted_current.txt
@@ -158,7 +158,7 @@
     method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> copy(androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D>, optional float value, optional float velocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
     method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
     method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T value);
-    method public static boolean isFinished(androidx.compose.animation.core.AnimationState<? extends java.lang.Object!,? extends java.lang.Object!>);
+    method public static boolean isFinished(androidx.compose.animation.core.AnimationState<? extends java.lang.Object?,? extends java.lang.Object?>);
   }
 
   public abstract sealed class AnimationVector {
@@ -448,9 +448,9 @@
   }
 
   public final class InfiniteTransition {
-    method public java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> getAnimations();
+    method public java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> getAnimations();
     method public String getLabel();
-    property public final java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> animations;
+    property public final java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> animations;
     property public final String label;
   }
 
@@ -650,17 +650,17 @@
   @androidx.compose.runtime.Stable public final class Transition<S> {
     ctor @kotlin.PublishedApi internal Transition(androidx.compose.animation.core.MutableTransitionState<S> transitionState, optional String? label);
     ctor @kotlin.PublishedApi internal Transition(androidx.compose.animation.core.TransitionState<S> transitionState, optional String? label);
-    method public java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> getAnimations();
+    method public java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> getAnimations();
     method public S getCurrentState();
     method @SuppressCompatibility @androidx.compose.animation.core.InternalAnimationApi public boolean getHasInitialValueAnimations();
     method public String? getLabel();
     method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
     method public S getTargetState();
     method public long getTotalDurationNanos();
-    method public java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object!>> getTransitions();
+    method public java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object?>> getTransitions();
     method public boolean isRunning();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void seek(S initialState, S targetState, long playTimeNanos);
-    property public final java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object!,? extends java.lang.Object!>> animations;
+    property public final java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<? extends java.lang.Object?,? extends java.lang.Object?>> animations;
     property public final S currentState;
     property @SuppressCompatibility @androidx.compose.animation.core.InternalAnimationApi public final boolean hasInitialValueAnimations;
     property public final boolean isRunning;
@@ -668,7 +668,7 @@
     property public final androidx.compose.animation.core.Transition.Segment<S> segment;
     property public final S targetState;
     property public final long totalDurationNanos;
-    property public final java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object!>> transitions;
+    property public final java.util.List<androidx.compose.animation.core.Transition<? extends java.lang.Object?>> transitions;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface Transition.Segment<S> {
diff --git a/compose/foundation/foundation-layout/OWNERS b/compose/foundation/foundation-layout/OWNERS
index 74ae12a..9b30ce2 100644
--- a/compose/foundation/foundation-layout/OWNERS
+++ b/compose/foundation/foundation-layout/OWNERS
@@ -4,3 +4,4 @@
 [email protected]
 [email protected]
 [email protected]
[email protected]
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AlignmentLine.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AlignmentLine.kt
index 4a646db..2d4fadd4 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AlignmentLine.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AlignmentLine.kt
@@ -49,16 +49,16 @@
  * modified layout will satisfy the min constraint and the content will be positioned to satisfy the
  * [before] requirement if specified, or the [after] requirement otherwise.
  *
+ * Example usage:
+ *
+ * @sample androidx.compose.foundation.layout.samples.PaddingFromSample
+ *
  * @param alignmentLine the alignment line relative to which the padding is defined
  * @param before the distance between the container's top edge and the horizontal alignment line, or
  *   the container's start edge and the vertical alignment line
  * @param after the distance between the container's bottom edge and the horizontal alignment line,
  *   or the container's end edge and the vertical alignment line
  * @see paddingFromBaseline
- *
- * Example usage:
- *
- * @sample androidx.compose.foundation.layout.samples.PaddingFromSample
  */
 @Stable
 fun Modifier.paddingFrom(
@@ -94,16 +94,16 @@
  * modified layout will satisfy the min constraint and the content will be positioned to satisfy the
  * [before] requirement if specified, or the [after] requirement otherwise.
  *
+ * Example usage:
+ *
+ * @sample androidx.compose.foundation.layout.samples.PaddingFromSample
+ *
  * @param alignmentLine the alignment line relative to which the padding is defined
  * @param before the distance between the container's top edge and the horizontal alignment line, or
  *   the container's start edge and the vertical alignment line
  * @param after the distance between the container's bottom edge and the horizontal alignment line,
  *   or the container's end edge and the vertical alignment line
  * @see paddingFromBaseline
- *
- * Example usage:
- *
- * @sample androidx.compose.foundation.layout.samples.PaddingFromSample
  */
 @Stable
 fun Modifier.paddingFrom(
@@ -135,11 +135,11 @@
  * constraint, the modified layout will satisfy the min constraint and the content will be
  * positioned to satisfy the [top] requirement if specified, or the [bottom] requirement otherwise.
  *
- * @see paddingFrom
- *
  * Example usage:
  *
  * @sample androidx.compose.foundation.layout.samples.PaddingFromBaselineSampleDp
+ *
+ * @see paddingFrom
  */
 @Stable
 fun Modifier.paddingFromBaseline(top: Dp = Dp.Unspecified, bottom: Dp = Dp.Unspecified) =
@@ -168,11 +168,11 @@
  * constraint, the modified layout will satisfy the min constraint and the content will be
  * positioned to satisfy the [top] requirement if specified, or the [bottom] requirement otherwise.
  *
- * @see paddingFrom
- *
  * Example usage:
  *
  * @sample androidx.compose.foundation.layout.samples.PaddingFromBaselineSampleTextUnit
+ *
+ * @see paddingFrom
  */
 @Stable
 fun Modifier.paddingFromBaseline(
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Offset.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Offset.kt
index 32aef27..b4fde0e 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Offset.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Offset.kt
@@ -41,11 +41,11 @@
  * when the layout direction is RTL, positive [x] offsets will move the content to the left. For a
  * modifier that offsets without considering layout direction, see [absoluteOffset].
  *
- * @see absoluteOffset
- *
  * Example usage:
  *
  * @sample androidx.compose.foundation.layout.samples.OffsetModifier
+ *
+ * @see absoluteOffset
  */
 @Stable
 fun Modifier.offset(x: Dp = 0.dp, y: Dp = 0.dp) =
@@ -70,11 +70,11 @@
  * positive [x] offset will always move the content to the right. For a modifier that considers the
  * layout direction when applying the offset, see [offset].
  *
- * @see offset
- *
  * Example usage:
  *
  * @sample androidx.compose.foundation.layout.samples.AbsoluteOffsetModifier
+ *
+ * @see offset
  */
 @Stable
 fun Modifier.absoluteOffset(x: Dp = 0.dp, y: Dp = 0.dp) =
@@ -104,11 +104,11 @@
  * LD is RTL, positive horizontal offsets will move the content to the left. For a modifier that
  * offsets without considering layout direction, see [absoluteOffset].
  *
- * @see [absoluteOffset]
- *
  * Example usage:
  *
  * @sample androidx.compose.foundation.layout.samples.OffsetPxModifier
+ *
+ * @see [absoluteOffset]
  */
 fun Modifier.offset(offset: Density.() -> IntOffset) =
     this then
@@ -134,11 +134,11 @@
  * positive horizontal offset will always move the content to the right. For a modifier that
  * considers layout direction when applying the offset, see [offset].
  *
- * @see offset
- *
  * Example usage:
  *
  * @sample androidx.compose.foundation.layout.samples.AbsoluteOffsetPxModifier
+ *
+ * @see offset
  */
 fun Modifier.absoluteOffset(offset: Density.() -> IntOffset) =
     this then
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
index 5825b16..8b27c92 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
@@ -339,11 +339,11 @@
      * that if only one element in a [Row] has the [alignBy] modifier specified the element will be
      * positioned as if it had [Alignment.Top] align.
      *
-     * @see alignByBaseline
-     *
      * Example usage:
      *
      * @sample androidx.compose.foundation.layout.samples.SimpleAlignByInRow
+     *
+     * @see alignByBaseline
      */
     @Stable fun Modifier.alignBy(alignmentLine: HorizontalAlignmentLine): Modifier
 
@@ -353,11 +353,11 @@
      * both modifiers will not work together if specified for the same layout. [alignByBaseline] is
      * a particular case of [alignBy]. See [alignBy] for more details.
      *
-     * @see alignBy
-     *
      * Example usage:
      *
      * @sample androidx.compose.foundation.layout.samples.SimpleAlignByInRow
+     *
+     * @see alignBy
      */
     @Stable fun Modifier.alignByBaseline(): Modifier
 
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index 258debb..d2cd478 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -275,8 +275,8 @@
   }
 
   public static final class ScrollState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object?> Saver;
   }
 
   public interface SurfaceCoroutineScope extends androidx.compose.foundation.SurfaceScope kotlinx.coroutines.CoroutineScope {
@@ -913,8 +913,8 @@
   }
 
   public static final class LazyListState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object?> Saver;
   }
 
   public final class LazyListStateKt {
@@ -1076,8 +1076,8 @@
   }
 
   public static final class LazyGridState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object?> Saver;
   }
 
   public final class LazyGridStateKt {
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index 31c521d..cda6bbb 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -277,8 +277,8 @@
   }
 
   public static final class ScrollState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,? extends java.lang.Object?> Saver;
   }
 
   public interface SurfaceCoroutineScope extends androidx.compose.foundation.SurfaceScope kotlinx.coroutines.CoroutineScope {
@@ -915,8 +915,8 @@
   }
 
   public static final class LazyListState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,? extends java.lang.Object?> Saver;
   }
 
   public final class LazyListStateKt {
@@ -1078,8 +1078,8 @@
   }
 
   public static final class LazyGridState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,? extends java.lang.Object?> Saver;
   }
 
   public final class LazyGridStateKt {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt
index 24c5110..15eed3a 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt
@@ -33,6 +33,7 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.ReusableContent
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.key
 import androidx.compose.runtime.movableContentOf
@@ -66,6 +67,7 @@
 import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.KeyInjectionScope
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.assert
@@ -410,6 +412,335 @@
     }
 
     @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun longClickWithEnterKey() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            BasicText(
+                "ClickableText",
+                modifier =
+                    Modifier.testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .combinedClickable(
+                            onLongClick = { ++longClickCounter },
+                            onClick = { ++clickCounter }
+                        )
+            )
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            longPressKey(Key.Enter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(1)
+            assertThat(clickCounter).isEqualTo(0)
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun longClickWithNumPadEnterKey() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            BasicText(
+                "ClickableText",
+                modifier =
+                    Modifier.testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .combinedClickable(
+                            onLongClick = { ++longClickCounter },
+                            onClick = { ++clickCounter }
+                        )
+            )
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            longPressKey(Key.NumPadEnter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(1)
+            assertThat(clickCounter).isEqualTo(0)
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun longClickWithDPadCenter() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            BasicText(
+                "ClickableText",
+                modifier =
+                    Modifier.testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .combinedClickable(
+                            onLongClick = { ++longClickCounter },
+                            onClick = { ++clickCounter }
+                        )
+            )
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            longPressKey(Key.DirectionCenter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(1)
+            assertThat(clickCounter).isEqualTo(0)
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun longClickWithEnterKeyThenDPadCenter_triggersListenerTwice() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            BasicText(
+                "ClickableText",
+                modifier =
+                    Modifier.testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .combinedClickable(
+                            onLongClick = { ++longClickCounter },
+                            onClick = { ++clickCounter }
+                        )
+            )
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            longPressKey(Key.Enter)
+            longPressKey(Key.DirectionCenter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(2)
+            assertThat(clickCounter).isEqualTo(0)
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun longClickWithEnterKeyConcurrentlyWithDPadCenter_triggersListenerForEach() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            BasicText(
+                "ClickableText",
+                modifier =
+                    Modifier.testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .combinedClickable(
+                            onLongClick = { ++longClickCounter },
+                            onClick = { ++clickCounter }
+                        )
+            )
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            // The press duration is 100ms longer than the minimum required for a long press.
+            val durationMillis: Long = viewConfiguration.longPressTimeoutMillis + 100
+            keyDown(Key.Enter)
+            advanceEventTime(durationMillis / 2)
+            keyDown(Key.DirectionCenter)
+            advanceEventTime(durationMillis / 2)
+            keyUp(Key.Enter)
+            advanceEventTime(durationMillis / 2)
+            keyUp(Key.DirectionCenter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(2)
+            assertThat(clickCounter).isEqualTo(0)
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun longClickWithEnterKeyConcurrentlyWithShortClickDPadCenter_triggersListenerForEach() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            BasicText(
+                "ClickableText",
+                modifier =
+                    Modifier.testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .combinedClickable(
+                            onLongClick = { ++longClickCounter },
+                            onClick = { ++clickCounter }
+                        )
+            )
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            // The press duration is 100ms longer than the minimum required for a long press.
+            val durationMillis: Long = viewConfiguration.longPressTimeoutMillis + 100
+            keyDown(Key.Enter)
+            advanceEventTime(durationMillis / 2)
+            keyDown(Key.DirectionCenter)
+            advanceEventTime(durationMillis / 2)
+            keyUp(Key.Enter)
+            keyUp(Key.DirectionCenter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(1)
+            assertThat(clickCounter).isEqualTo(1)
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun updateOnLongClickListenerBetweenEnterKeyDownAndUp_callsNewListener() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        var newLongClickCounter = 0
+        var mutableOnLongClick: () -> Unit by mutableStateOf({ ++longClickCounter })
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            BasicText(
+                "ClickableText",
+                modifier =
+                    Modifier.testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .combinedClickable(
+                            onLongClick = mutableOnLongClick,
+                            onClick = { ++clickCounter }
+                        )
+            )
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            keyDown(Key.Enter)
+            advanceEventTime(100)
+        }
+        mutableOnLongClick = { ++newLongClickCounter }
+        rule.waitForIdle()
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            // The press duration is 100ms longer than the minimum required for a long press.
+            val durationMillis: Long = viewConfiguration.longPressTimeoutMillis + 100
+            advanceEventTime(durationMillis)
+            keyUp(Key.Enter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(0)
+            assertThat(newLongClickCounter).isEqualTo(1)
+            assertThat(clickCounter).isEqualTo(0)
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
+    fun modifierReusedBetweenEnterKeyDownAndKeyUp_doesNotCallListeners() {
+        var clickCounter = 0
+        var longClickCounter = 0
+        var reuseKey by mutableStateOf(0)
+        val focusRequester = FocusRequester()
+        lateinit var inputModeManager: InputModeManager
+        rule.setContent {
+            inputModeManager = LocalInputModeManager.current
+            ReusableContent(reuseKey) {
+                BasicText(
+                    "ClickableText",
+                    modifier =
+                        Modifier.testTag("myClickable")
+                            .focusRequester(focusRequester)
+                            .combinedClickable(
+                                onLongClick = { ++longClickCounter },
+                                onClick = { ++clickCounter }
+                            )
+                )
+            }
+        }
+        rule.runOnIdle {
+            inputModeManager.requestInputMode(Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            assertThat(inputModeManager.inputMode).isEqualTo(Keyboard)
+            keyDown(Key.Enter)
+            // Press the Enter key down for 100ms less than the required long press duration.
+            val durationMillis: Long = viewConfiguration.longPressTimeoutMillis - 100
+            advanceEventTime(durationMillis)
+        }
+        rule.runOnIdle { reuseKey = 1 }
+        rule.waitForIdle()
+        rule.onNodeWithTag("myClickable").performKeyInput {
+            // Press the key down for another 200ms to reach the required long press duration.
+            advanceEventTime(200)
+            keyUp(Key.Enter)
+        }
+
+        rule.runOnIdle {
+            assertThat(longClickCounter).isEqualTo(0)
+            assertThat(clickCounter).isEqualTo(0)
+        }
+    }
+
+    @Test
     fun click_withLongClick() {
         var clickCounter = 0
         var longClickCounter = 0
@@ -2304,3 +2635,9 @@
         }
     )
 }
+
+private fun KeyInjectionScope.longPressKey(key: Key) {
+    // The press duration is 100ms longer than the minimum required for a long press.
+    val durationMillis: Long = viewConfiguration.longPressTimeoutMillis + 100
+    pressKey(key, durationMillis)
+}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextLinkTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextLinkTest.kt
index eb1c29c..fee426a 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextLinkTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextLinkTest.kt
@@ -21,6 +21,7 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.rememberScrollState
@@ -41,6 +42,7 @@
 import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.focus.focusTarget
 import androidx.compose.ui.focus.onFocusChanged
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.input.InputMode
 import androidx.compose.ui.input.InputModeManager
@@ -54,21 +56,26 @@
 import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.MouseInjectionScope
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
+import androidx.compose.ui.test.TouchInjectionScope
 import androidx.compose.ui.test.assertIsFocused
 import androidx.compose.ui.test.assertIsNotFocused
 import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.click
+import androidx.compose.ui.test.getPartialBoundsOfLinks
 import androidx.compose.ui.test.hasClickAction
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onAllNodesWithText
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onNodeWithText
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performMouseInput
 import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.test.requestFocus
+import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.LinkAnnotation
 import androidx.compose.ui.text.LinkAnnotation.Url
 import androidx.compose.ui.text.Placeholder
@@ -165,9 +172,8 @@
         setupContent { TextWithLinks() }
 
         rule.runOnIdle { assertThat(layoutResult).isNotNull() }
-        rule.onFirstText().performTouchInput {
-            val boundingBox = layoutResult!!.getBoundingBox(7)
-            click(boundingBox.center)
+        rule.onFirstText().performTouchInputOnFirstLink({ (it.item as? Url)?.url == Url1 }) {
+            click(it)
         }
 
         rule.runOnIdle { assertThat(openedUri).isEqualTo(Url1) }
@@ -178,11 +184,9 @@
         setupContent { TextWithLinks() }
 
         rule.runOnIdle { assertThat(layoutResult).isNotNull() }
-        rule.onFirstText().performTouchInput {
-            val boundingBox = layoutResult!!.getBoundingBox(20)
-            click(boundingBox.center)
+        rule.onFirstText().performTouchInputOnFirstLink({ (it.item as? Url)?.url == Url2 }) {
+            click(it)
         }
-
         rule.runOnIdle { assertThat(openedUri).isEqualTo(Url2) }
     }
 
@@ -230,10 +234,9 @@
         setupContent { RtlTextWithLinks() }
 
         rule.runOnIdle { assertThat(layoutResult).isNotNull() }
-        rule.onNode(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text)).performTouchInput {
-            val boundingBox = layoutResult!!.getBoundingBox(3)
-            click(boundingBox.center)
-        }
+        rule
+            .onNode(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text))
+            .performTouchInputOnFirstLink({ (it.item as? Url)?.url == Url1 }) { click(it) }
 
         rule.runOnIdle { assertThat(openedUri).isEqualTo(Url1) }
     }
@@ -243,10 +246,9 @@
         setupContent { RtlTextWithLinks() }
 
         rule.runOnIdle { assertThat(layoutResult).isNotNull() }
-        rule.onNode(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text)).performTouchInput {
-            val boundingBox = layoutResult!!.getBoundingBox(30)
-            click(boundingBox.center)
-        }
+        rule
+            .onNode(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text))
+            .performTouchInputOnFirstLink({ (it.item as? Url)?.url == Url2 }) { click(it) }
 
         rule.runOnIdle { assertThat(openedUri).isEqualTo(Url2) }
     }
@@ -282,10 +284,9 @@
         setupContent { BidiTextWithLinks() }
 
         rule.runOnIdle { assertThat(layoutResult).isNotNull() }
-        rule.onNode(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text)).performTouchInput {
-            val boundingBox = layoutResult!!.getBoundingBox(8)
-            click(boundingBox.center)
-        }
+        rule
+            .onNode(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text))
+            .performTouchInputOnFirstLink({ (it.item as? Url)?.url == Url1 }) { click(it) }
 
         rule.runOnIdle { assertThat(openedUri).isEqualTo(Url1) }
     }
@@ -322,7 +323,11 @@
             BasicText(text = text, inlineContent = mapOf("box" to inlineTextContent))
         }
 
-        rule.onAllNodes(hasClickAction(), useUnmergedTree = true)[0].performClick()
+        rule.onNodeWithText("text", substring = true).performTouchInputOnFirstLink({
+            (it.item as? Url)?.url == Url1
+        }) {
+            click(it)
+        }
 
         rule.onNodeWithTag("box", useUnmergedTree = true).assertExists()
         rule.runOnIdle { assertThat(openedUri).isEqualTo(Url1) }
@@ -410,10 +415,7 @@
         }
         setupContent { BasicText(text = textWithLink, style = TextStyle(color = Color.White)) }
 
-        rule
-            .onNode(hasClickAction(), useUnmergedTree = true)
-            .captureToImage()
-            .assertContainsColor(Color.Red)
+        rule.onNodeWithText("text").captureToImage().assertContainsColor(Color.Red)
     }
 
     @Test
@@ -429,7 +431,7 @@
         setupContent { BasicText(text = textWithLink, style = TextStyle(color = Color.White)) }
 
         rule
-            .onNode(hasClickAction(), useUnmergedTree = true)
+            .onNodeWithText("text")
             .captureToImage()
             .assertContainsColor(Color.Green)
             .assertContainsColor(Color.Red)
@@ -455,8 +457,8 @@
         setupContent { BasicText(text = textWithLink, style = TextStyle(color = Color.White)) }
 
         rule
-            .onNode(hasClickAction(), useUnmergedTree = true)
-            .performMouseInput { moveTo(this.center) }
+            .onNodeWithText("text")
+            .performMouseInputOnFirstLink { moveTo(it) }
             .captureToImage()
             .assertContainsColor(Color.Green)
             .assertDoesNotContainColor(Color.Red)
@@ -484,8 +486,8 @@
         setupContent { BasicText(text = textWithLink, style = TextStyle(color = Color.White)) }
 
         rule
-            .onNode(hasClickAction(), useUnmergedTree = true)
-            .performMouseInput { moveTo(this.center) }
+            .onNodeWithText("text")
+            .performMouseInputOnFirstLink { moveTo(it) }
             .captureToImage()
             .assertContainsColor(Color.Green)
             .assertDoesNotContainColor(Color.Red)
@@ -512,8 +514,8 @@
         setupContent { BasicText(text = textWithLink, style = TextStyle(color = Color.White)) }
 
         rule
-            .onNode(hasClickAction(), useUnmergedTree = true)
-            .performMouseInput { moveTo(this.center) }
+            .onNodeWithText("text")
+            .performMouseInputOnFirstLink { moveTo(it) }
             .captureToImage()
             .assertContainsColor(Color.Green)
             .assertContainsColor(Color.Red)
@@ -695,8 +697,8 @@
         setupContent { BasicText(text = textWithLink, style = TextStyle(color = Color.White)) }
 
         rule
-            .onNode(hasClickAction(), useUnmergedTree = true)
-            .performTouchInput { longPress(this.center) }
+            .onNodeWithText("text")
+            .performTouchInputOnFirstLink { longPress(it) }
             .captureToImage()
             .assertContainsColor(Color.Green)
     }
@@ -716,8 +718,8 @@
         setupContent { BasicText(text = textWithLink, style = TextStyle(color = Color.White)) }
 
         rule
-            .onNode(hasClickAction(), useUnmergedTree = true)
-            .performTouchInput { longPress(this.center) }
+            .onNodeWithText("text")
+            .performTouchInputOnFirstLink { longPress(it) }
             .captureToImage()
             .assertDoesNotContainColor(Color.Green)
             .assertContainsColor(Color.Blue)
@@ -829,7 +831,7 @@
     @Composable
     private fun TextWithLinks() =
         with(rule.density) {
-            Column {
+            Column(Modifier.padding(87.dp)) {
                 /**
                  * +-----------------------+ | text link text a long | | link text | | text link | |
                  * [ ] | +-----------------------+
@@ -908,6 +910,23 @@
 
     private fun SemanticsNodeInteractionsProvider.onFirstText(): SemanticsNodeInteraction =
         onAllNodesWithText("text", substring = true)[0]
+
+    @OptIn(ExperimentalTestApi::class)
+    private fun SemanticsNodeInteraction.performMouseInputOnFirstLink(
+        predicate: (AnnotatedString.Range<LinkAnnotation>) -> Boolean = { true },
+        block: MouseInjectionScope.(offsetInLink: Offset) -> Unit
+    ): SemanticsNodeInteraction {
+        val linkBounds = getPartialBoundsOfLinks(predicate).first()
+        return this.performMouseInput { block(linkBounds.center) }
+    }
+
+    private fun SemanticsNodeInteraction.performTouchInputOnFirstLink(
+        predicate: (AnnotatedString.Range<LinkAnnotation>) -> Boolean = { true },
+        block: TouchInjectionScope.(offsetInLink: Offset) -> Unit
+    ): SemanticsNodeInteraction {
+        val linkBounds = getPartialBoundsOfLinks(predicate).first()
+        return this.performTouchInput { block(linkBounds.center) }
+    }
 }
 
 private class DelegatedViewConfiguration(
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationDurationTest.kt b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationDurationTest.kt
new file mode 100644
index 0000000..9baf30f
--- /dev/null
+++ b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationDurationTest.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.text.input.internal
+
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(JUnit4::class)
+class CursorAnimationDurationTest {
+
+    @Test
+    fun whenNeverBlink_cursorAlwaysOn() = runTest {
+        val subject = CursorAnimationState(false)
+        val job = launch { subject.snapToVisibleAndAnimate() }
+        assertNotAnimating(subject, 1f)
+        job.cancel()
+    }
+
+    @Test
+    fun default_blinksForever() = runTest {
+        val subject = CursorAnimationState(true)
+        val job = launch { subject.snapToVisibleAndAnimate() }
+        // note, don't approach large portions of Long.MAX_VALUE advance here as it has to "blink""
+        // every 500 and if it runs longer than 10s the coroutine framework faults
+        advanceTimeBy(500 * 10_000) // 10 thousand blinks
+        val cur = subject.cursorAlpha
+        advanceTimeBy(500)
+        assertThat(cur).isNotEqualTo(subject.cursorAlpha)
+        job.cancel()
+    }
+
+    private fun TestScope.assertNotAnimating(animationState: CursorAnimationState, alpha: Float) {
+        // Allow the cancellation to process.
+        advanceUntilIdle()
+
+        // Verify a few blinks.
+        repeat(10) {
+            assertThat(animationState.cursorAlpha).isEqualTo(alpha)
+            testScheduler.advanceTimeBy(490)
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
index 9c0e34d..44a564c 100644
--- a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
+++ b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
@@ -32,7 +32,7 @@
 @RunWith(JUnit4::class)
 class CursorAnimationStateTest {
 
-    private val animationState = CursorAnimationState()
+    private val animationState = CursorAnimationState(true)
 
     @Test fun alphaNotAnimatingInitially() = runTest { assertNotAnimating() }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
index ffe74a9..e2c326c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
@@ -16,6 +16,8 @@
 
 package androidx.compose.foundation
 
+import androidx.collection.mutableLongObjectMapOf
+import androidx.collection.mutableLongSetOf
 import androidx.compose.foundation.gestures.PressGestureScope
 import androidx.compose.foundation.gestures.ScrollableContainerNode
 import androidx.compose.foundation.gestures.detectTapAndPress
@@ -38,15 +40,18 @@
 import androidx.compose.ui.input.pointer.PointerEventType
 import androidx.compose.ui.input.pointer.PointerInputScope
 import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
 import androidx.compose.ui.node.DelegatableNode
 import androidx.compose.ui.node.DelegatingNode
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.node.PointerInputModifierNode
 import androidx.compose.ui.node.SemanticsModifierNode
 import androidx.compose.ui.node.TraversableNode
+import androidx.compose.ui.node.currentValueOf
 import androidx.compose.ui.node.invalidateSemantics
 import androidx.compose.ui.node.traverseAncestors
 import androidx.compose.ui.platform.InspectorInfo
+import androidx.compose.ui.platform.LocalViewConfiguration
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.SemanticsPropertyReceiver
@@ -57,6 +62,7 @@
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.center
 import androidx.compose.ui.unit.toOffset
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.cancelAndJoin
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
@@ -210,6 +216,9 @@
  * other overload and explicitly passing `LocalIndication.current` for improved performance. For
  * more information see the documentation on the other overload.
  *
+ * Note, if the modifier instance gets re-used between a key down and key up events, the ongoing
+ * input will be aborted.
+ *
  * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a
  * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do
  * not need to do this when removing a composable because Compose guarantees it completes via the
@@ -300,6 +309,9 @@
  * [MutableInteractionSource] as a parameter for [interactionSource] instead of `null`, as this
  * cannot be lazily created inside clickable.
  *
+ * Note, if the modifier instance gets re-used between a key down and key up events, the ongoing
+ * input will be aborted.
+ *
  * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a
  * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do
  * not need to do this when removing a composable because Compose guarantees it completes via the
@@ -599,6 +611,13 @@
         // so no need need to reset pointer input handling when they change
         updateCommon(interactionSource, indicationNodeFactory, enabled, onClickLabel, role, onClick)
     }
+
+    final override fun onClickKeyDownEvent(event: KeyEvent) = false
+
+    final override fun onClickKeyUpEvent(event: KeyEvent): Boolean {
+        onClick()
+        return true
+    }
 }
 
 /**
@@ -708,6 +727,7 @@
     role: Role?,
 ) :
     CombinedClickableNode,
+    CompositionLocalConsumerModifierNode,
     AbstractClickableNode(
         interactionSource,
         indicationNodeFactory,
@@ -716,6 +736,9 @@
         role,
         onClick
     ) {
+    private val pressedDownKeys = mutableLongSetOf()
+    private val longKeyPressJobs = mutableLongObjectMapOf<Job>()
+
     override suspend fun PointerInputScope.clickPointerInput() {
         detectTapGestures(
             onDoubleTap =
@@ -802,6 +825,53 @@
             )
         }
     }
+
+    override fun onClickKeyDownEvent(event: KeyEvent): Boolean {
+        val keyCode = event.key.keyCode
+        pressedDownKeys.add(keyCode)
+        if (onLongClick != null) {
+            if (longKeyPressJobs[keyCode] == null) {
+                longKeyPressJobs[keyCode] =
+                    coroutineScope.launch {
+                        delay(currentValueOf(LocalViewConfiguration).longPressTimeoutMillis)
+                        onLongClick?.invoke()
+                    }
+                return true
+            }
+        }
+        return false
+    }
+
+    override fun onClickKeyUpEvent(event: KeyEvent): Boolean {
+        val keyCode = event.key.keyCode
+        if (!pressedDownKeys.contains(keyCode)) {
+            // If the node is reused while a key is pressed down (which resets the set of pressed
+            // down keys), we shouldn't interpret the key up event as a click.
+            return false
+        }
+        pressedDownKeys.remove(keyCode)
+        if (longKeyPressJobs[keyCode] != null) {
+            longKeyPressJobs[keyCode]?.let {
+                if (it.isActive) {
+                    it.cancel()
+                    onClick()
+                }
+            }
+            longKeyPressJobs.remove(keyCode)
+        } else {
+            onClick()
+        }
+        return true
+    }
+
+    override fun onReset() {
+        super.onReset()
+        longKeyPressJobs.apply {
+            forEachValue { it.cancel() }
+            clear()
+        }
+        pressedDownKeys.clear()
+    }
 }
 
 internal abstract class AbstractClickableNode(
@@ -1012,6 +1082,7 @@
             enabled && event.isPress -> {
                 // If the key already exists in the map, keyEvent is a repeat event.
                 // We ignore it as we only want to emit an interaction for the initial key press.
+                var wasInteractionHandled = false
                 if (!currentKeyPressInteractions.containsKey(event.key)) {
                     val press = PressInteraction.Press(centerOffset)
                     currentKeyPressInteractions[event.key] = press
@@ -1020,10 +1091,9 @@
                     if (interactionSource != null) {
                         coroutineScope.launch { interactionSource?.emit(press) }
                     }
-                    true
-                } else {
-                    false
+                    wasInteractionHandled = true
                 }
+                onClickKeyDownEvent(event) || wasInteractionHandled
             }
             enabled && event.isClick -> {
                 currentKeyPressInteractions.remove(event.key)?.let {
@@ -1033,13 +1103,17 @@
                         }
                     }
                 }
-                onClick()
+                onClickKeyUpEvent(event)
                 true
             }
             else -> false
         }
     }
 
+    protected abstract fun onClickKeyDownEvent(event: KeyEvent): Boolean
+
+    protected abstract fun onClickKeyUpEvent(event: KeyEvent): Boolean
+
     final override fun onPreKeyEvent(event: KeyEvent) = false
 
     final override fun onFocusEvent(focusState: FocusState) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
index 5b47636..607ba3b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
@@ -16,14 +16,10 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.animation.core.AnimationSpec
-import androidx.compose.animation.core.infiniteRepeatable
-import androidx.compose.animation.core.keyframes
 import androidx.compose.foundation.text.input.internal.CursorAnimationState
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.MotionDurationScale
 import androidx.compose.ui.composed
 import androidx.compose.ui.draw.drawWithContent
 import androidx.compose.ui.geometry.Offset
@@ -31,6 +27,7 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.SolidColor
 import androidx.compose.ui.graphics.isUnspecified
+import androidx.compose.ui.platform.LocalCursorBlinkEnabled
 import androidx.compose.ui.platform.LocalWindowInfo
 import androidx.compose.ui.text.input.OffsetMapping
 import androidx.compose.ui.text.input.TextFieldValue
@@ -45,7 +42,8 @@
 ) =
     if (enabled)
         composed {
-            val cursorAnimation = remember { CursorAnimationState() }
+            val animateCursor = LocalCursorBlinkEnabled.current
+            val cursorAnimation = remember(animateCursor) { CursorAnimationState(animateCursor) }
             // Don't bother animating the cursor if it wouldn't draw any pixels.
             val isBrushSpecified = !(cursorBrush is SolidColor && cursorBrush.value.isUnspecified)
             // Only animate the cursor when its window is actually focused. This also disables the
@@ -92,21 +90,4 @@
         }
     else this
 
-private val cursorAnimationSpec: AnimationSpec<Float> =
-    infiniteRepeatable(
-        animation =
-            keyframes {
-                durationMillis = 1000
-                1f at 0
-                1f at 499
-                0f at 500
-                0f at 999
-            }
-    )
-
 internal val DefaultCursorThickness = 2.dp
-
-private object FixedMotionDurationScale : MotionDurationScale {
-    override val scaleFactor: Float
-        get() = 1f
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationState.kt
index 6bb37a8..58dca60 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationState.kt
@@ -21,6 +21,7 @@
 import androidx.compose.runtime.mutableFloatStateOf
 import androidx.compose.runtime.setValue
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.cancelAndJoin
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
@@ -33,7 +34,7 @@
  * spends most of its time delayed so that's a ton of wasted frames. Pure coroutine delays, however,
  * will not cause any work to be done until the delay is over.
  */
-internal class CursorAnimationState {
+internal class CursorAnimationState(val animate: Boolean) {
 
     private var animationJob = AtomicReference<Job?>(null)
 
@@ -72,14 +73,13 @@
 
                     // Start the new animation and run until cancelled.
                     try {
+                        cursorAlpha = 1f
+                        if (!animate) awaitCancellation()
                         while (true) {
-                            cursorAlpha = 1f
-                            // Ignore MotionDurationScale – the cursor should blink even when
-                            // animations
-                            // are disabled by the system.
                             delay(500)
                             cursorAlpha = 0f
                             delay(500)
+                            cursorAlpha = 1f
                         }
                     } finally {
                         // Hide cursor when the animation is cancelled.
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt
index 93b79e60..f36aa89 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt
@@ -47,8 +47,10 @@
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.node.SemanticsModifierNode
 import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.node.invalidateDraw
 import androidx.compose.ui.node.invalidateMeasurement
 import androidx.compose.ui.platform.InspectorInfo
+import androidx.compose.ui.platform.LocalCursorBlinkEnabled
 import androidx.compose.ui.platform.LocalWindowInfo
 import androidx.compose.ui.semantics.SemanticsPropertyReceiver
 import androidx.compose.ui.text.TextLayoutResult
@@ -145,7 +147,7 @@
      * another half a second when TextField is focused and editable. Initial value should be 0f so
      * that when cursor needs to be drawn for the first time, change to 1f invalidates draw.
      */
-    private val cursorAnimation = CursorAnimationState()
+    private var cursorAnimation: CursorAnimationState? = null
 
     /**
      * Whether to show cursor at all when TextField has focus. This depends on enabled, read only,
@@ -235,7 +237,7 @@
         if (!showCursor) {
             changeObserverJob?.cancel()
             changeObserverJob = null
-            cursorAnimation.cancelAndHide()
+            cursorAnimation?.cancelAndHide()
         } else if (!wasFocused || previousTextFieldState != textFieldState || !previousShowCursor) {
             // this node is writeable, focused and gained that focus just now.
             // start the state value observation
@@ -505,7 +507,7 @@
         // Only draw cursor if it can be shown and its alpha is higher than 0f
         // Alpha is checked before showCursor purposefully to make sure that we read
         // cursorAlpha in draw phase. So, when the alpha value changes, draw phase invalidates.
-        val cursorAlphaValue = cursorAnimation.cursorAlpha
+        val cursorAlphaValue = cursorAnimation?.cursorAlpha ?: 0f
         if (cursorAlphaValue == 0f || !showCursor) return
 
         val cursorRect = textFieldSelectionState.getCursorRect()
@@ -525,6 +527,10 @@
      * visibility snaps back to "visible".
      */
     private fun startCursorJob() {
+        if (cursorAnimation == null) {
+            cursorAnimation = CursorAnimationState(currentValueOf(LocalCursorBlinkEnabled))
+            invalidateDraw() // draw did not previously have a read observer on alpha, restart it
+        }
         changeObserverJob =
             coroutineScope.launch {
                 // A flag to oscillate the reported isWindowFocused value in snapshotFlow.
@@ -553,7 +559,7 @@
                     }
                     .collectLatest { isWindowFocused ->
                         if (isWindowFocused.absoluteValue == 1) {
-                            cursorAnimation.snapToVisibleAndAnimate()
+                            cursorAnimation?.snapToVisibleAndAnimate()
                         }
                     }
             }
diff --git a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt
index ee19108..c64d2036 100644
--- a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt
+++ b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt
@@ -37,6 +37,7 @@
 import androidx.compose.integration.demos.common.DemoCategory
 import androidx.compose.integration.demos.common.FragmentDemo
 import androidx.compose.integration.demos.common.allLaunchableDemos
+import androidx.compose.integration.demos.settings.CursorBlinkSetting
 import androidx.compose.material.LocalContentColor
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.automirrored.filled.ArrowBack
@@ -63,6 +64,7 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.platform.LocalCursorBlinkEnabled
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.viewinterop.AndroidView
@@ -131,7 +133,11 @@
                     onNavigate = onNavigate
                 )
             } else {
-                DisplayDemo(demo, onNavigate, onNavigateUp)
+                CompositionLocalProvider(
+                    LocalCursorBlinkEnabled provides CursorBlinkSetting.asState().value
+                ) {
+                    DisplayDemo(demo, onNavigate, onNavigateUp)
+                }
             }
         }
     }
diff --git a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoSettingsActivity.kt b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoSettingsActivity.kt
index 5e2d80c..79dabaf 100644
--- a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoSettingsActivity.kt
+++ b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoSettingsActivity.kt
@@ -19,6 +19,7 @@
 import android.os.Bundle
 import androidx.appcompat.app.AppCompatActivity
 import androidx.compose.integration.demos.DemoSettingsActivity.SettingsFragment
+import androidx.compose.integration.demos.settings.CursorBlinkSetting
 import androidx.compose.integration.demos.settings.DecorFitsSystemWindowsSetting
 import androidx.compose.integration.demos.settings.DynamicThemeSetting
 import androidx.compose.integration.demos.settings.LayoutDirectionSetting
@@ -33,6 +34,7 @@
         DynamicThemeSetting,
         SoftInputModeSetting,
         DecorFitsSystemWindowsSetting,
+        CursorBlinkSetting,
     )
 
 /**
diff --git a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/settings/CursorBlinkSetting.kt b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/settings/CursorBlinkSetting.kt
new file mode 100644
index 0000000..4fa434c
--- /dev/null
+++ b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/settings/CursorBlinkSetting.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.integration.demos.settings
+
+import android.content.Context
+import androidx.compose.runtime.Composable
+import androidx.preference.CheckBoxPreference
+
+/** Set the cursor blink timeout for the demo app (useful for reducing animations). */
+internal object CursorBlinkSetting : DemoSetting<Boolean> {
+    private const val Key = "cursorBlinkSetting"
+    private const val DefaultValue = true
+
+    override fun createPreference(context: Context) =
+        CheckBoxPreference(context).apply {
+            title = "Enable or disable text cursor blink"
+            key = Key
+            summaryOn = "Blink cursor like normal"
+            summaryOff = "Disable cursor blinks"
+            setDefaultValue(DefaultValue)
+        }
+
+    @Composable fun asState() = preferenceAsState(Key) { getBoolean(Key, DefaultValue) }
+}
diff --git a/compose/integration-tests/hero/benchmark/src/androidTest/java/androidx/compose/integration/hero/benchmark/jetsnack/JetsnackCaseFactory.kt b/compose/integration-tests/hero/benchmark/src/androidTest/java/androidx/compose/integration/hero/benchmark/jetsnack/JetsnackCaseFactory.kt
index 339092f..cd4680a 100644
--- a/compose/integration-tests/hero/benchmark/src/androidTest/java/androidx/compose/integration/hero/benchmark/jetsnack/JetsnackCaseFactory.kt
+++ b/compose/integration-tests/hero/benchmark/src/androidTest/java/androidx/compose/integration/hero/benchmark/jetsnack/JetsnackCaseFactory.kt
@@ -16,8 +16,8 @@
 
 package androidx.compose.integration.hero.benchmark.jetsnack
 
-import androidx.compose.integration.hero.implementation.jetsnack.Feed
-import androidx.compose.integration.hero.implementation.jetsnack.theme.JetsnackTheme
+import androidx.compose.integration.hero.implementation.jetsnack.compose.Feed
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.JetsnackTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.testutils.LayeredComposeTestCase
 
diff --git a/compose/integration-tests/hero/hero-implementation/build.gradle b/compose/integration-tests/hero/hero-implementation/build.gradle
index 361a49e..690088e 100644
--- a/compose/integration-tests/hero/hero-implementation/build.gradle
+++ b/compose/integration-tests/hero/hero-implementation/build.gradle
@@ -43,6 +43,11 @@
 }
 
 dependencies {
+    implementation("androidx.appcompat:appcompat:1.6.1")
+    implementation("androidx.recyclerview:recyclerview:1.2.1")
+    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+    implementation("androidx.cardview:cardview:1.0.0")
+
     implementation(libs.kotlinStdlib)
     implementation(project(":activity:activity-compose"))
     implementation(project(":compose:foundation:foundation-layout"))
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Card.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Card.kt
similarity index 91%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Card.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Card.kt
index 0106a549..7afdaab 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Card.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Card.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack
+package androidx.compose.integration.hero.implementation.jetsnack.compose
 
 import androidx.compose.foundation.BorderStroke
-import androidx.compose.integration.hero.implementation.jetsnack.theme.JetsnackTheme
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.JetsnackTheme
 import androidx.compose.material.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/DestinationBar.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/DestinationBar.kt
similarity index 93%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/DestinationBar.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/DestinationBar.kt
index 707996c..6f8bb305 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/DestinationBar.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/DestinationBar.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack
+package androidx.compose.integration.hero.implementation.jetsnack.compose
 
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.statusBarsPadding
 import androidx.compose.integration.hero.implementation.R
-import androidx.compose.integration.hero.implementation.jetsnack.theme.AlphaNearOpaque
-import androidx.compose.integration.hero.implementation.jetsnack.theme.JetsnackTheme
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.AlphaNearOpaque
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.JetsnackTheme
 import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Divider.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Divider.kt
similarity index 92%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Divider.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Divider.kt
index d2f11a4..60bc979 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Divider.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Divider.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack
+package androidx.compose.integration.hero.implementation.jetsnack.compose
 
 import android.content.res.Configuration
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
-import androidx.compose.integration.hero.implementation.jetsnack.theme.JetsnackTheme
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.JetsnackTheme
 import androidx.compose.material.Divider
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Feed.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Feed.kt
similarity index 92%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Feed.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Feed.kt
index 467148f..623847e 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Feed.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Feed.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack
+package androidx.compose.integration.hero.implementation.jetsnack.compose
 
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Spacer
@@ -25,6 +25,8 @@
 import androidx.compose.foundation.layout.windowInsetsTopHeight
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.integration.hero.implementation.jetsnack.SnackCollection
+import androidx.compose.integration.hero.implementation.jetsnack.SnackRepo
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.ExperimentalComposeUiApi
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Snacks.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Snacks.kt
similarity index 95%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Snacks.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Snacks.kt
index 8ec6916..ded0679 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Snacks.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Snacks.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack
+package androidx.compose.integration.hero.implementation.jetsnack.compose
 
 import androidx.activity.compose.ReportDrawn
 import androidx.annotation.DrawableRes
@@ -38,7 +38,10 @@
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.lazy.itemsIndexed
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.integration.hero.implementation.jetsnack.theme.JetsnackTheme
+import androidx.compose.integration.hero.implementation.jetsnack.CollectionType
+import androidx.compose.integration.hero.implementation.jetsnack.Snack
+import androidx.compose.integration.hero.implementation.jetsnack.SnackCollection
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.JetsnackTheme
 import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Surface.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Surface.kt
similarity index 95%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Surface.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Surface.kt
index fad5966..7c73a2a 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/Surface.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/Surface.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack
+package androidx.compose.integration.hero.implementation.jetsnack.compose
 
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.layout.Box
-import androidx.compose.integration.hero.implementation.jetsnack.theme.JetsnackTheme
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.JetsnackTheme
 import androidx.compose.material.LocalContentColor
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Color.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Color.kt
similarity index 99%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Color.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Color.kt
index 095e027..ef03991 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Color.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Color.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack.theme
+package androidx.compose.integration.hero.implementation.jetsnack.compose.theme
 
 import androidx.compose.ui.graphics.Color
 
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Shape.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Shape.kt
similarity index 98%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Shape.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Shape.kt
index b80a838..c9f4f51 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Shape.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Shape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack.theme
+package androidx.compose.integration.hero.implementation.jetsnack.compose.theme
 
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.Shapes
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Theme.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Theme.kt
similarity index 98%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Theme.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Theme.kt
index 3182729..034d06b 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Theme.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Theme.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack.theme
+package androidx.compose.integration.hero.implementation.jetsnack.compose.theme
 
 import androidx.compose.foundation.isSystemInDarkTheme
 import androidx.compose.material.Colors
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Type.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Type.kt
similarity index 96%
rename from compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Type.kt
rename to compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Type.kt
index baca1762..c7c8d89 100644
--- a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/theme/Type.kt
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/compose/theme/Type.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     https://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.compose.integration.hero.implementation.jetsnack.theme
+package androidx.compose.integration.hero.implementation.jetsnack.compose.theme
 
 import androidx.compose.integration.hero.implementation.R
 import androidx.compose.material.Typography
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/views/DessertAdapter.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/views/DessertAdapter.kt
new file mode 100644
index 0000000..3894b89
--- /dev/null
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/views/DessertAdapter.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.integration.hero.implementation.jetsnack.views
+
+import android.graphics.drawable.GradientDrawable
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.compose.integration.hero.implementation.R
+import androidx.compose.integration.hero.implementation.jetsnack.Snack
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.toArgb
+import androidx.recyclerview.widget.RecyclerView.Adapter
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+
+val gradients: List<Color> =
+    listOf(
+        Color(0xff7057f5),
+        Color(0xff86f7fa),
+        Color(0xffc8bbfd),
+        Color(0xff86f7fa),
+        Color(0xff7057f5)
+    )
+
+val gradientColors = gradients.map { it.toArgb() }.toIntArray()
+
+class DessertAdapter(private val snacks: List<Snack>) :
+    Adapter<DessertAdapter.DessertViewHolder>() {
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DessertViewHolder {
+        val inflater = LayoutInflater.from(parent.context)
+        val root = inflater.inflate(R.layout.item_snack_card_view, parent, false)
+        return DessertViewHolder(root)
+    }
+
+    override fun onBindViewHolder(holder: DessertViewHolder, position: Int) {
+        holder.bind(snacks[position])
+    }
+
+    override fun getItemCount(): Int {
+        return snacks.size
+    }
+
+    class DessertViewHolder(rootView: View) : ViewHolder(rootView) {
+        private val collectionBox = rootView.findViewById<View>(R.id.collectionBox)
+        private val snackImageView = rootView.findViewById<ImageView>(R.id.snackImageView)
+        private val snackNameTextView = rootView.findViewById<TextView>(R.id.snackNameTextView)
+        private val snackTagLineTextView =
+            rootView.findViewById<TextView>(R.id.snackTagLineTextView)
+
+        private val drawable =
+            GradientDrawable().apply {
+                colors = gradientColors
+                orientation = GradientDrawable.Orientation.LEFT_RIGHT
+                gradientType = GradientDrawable.LINEAR_GRADIENT
+                shape = GradientDrawable.RECTANGLE
+            }
+
+        fun bind(snack: Snack) {
+            collectionBox.background = drawable
+            snackImageView.setImageResource(snack.imageDrawable)
+            snackNameTextView.text = snack.name
+            snackTagLineTextView.text = snack.tagline
+        }
+    }
+}
+
+class SnackAdapter(private val snacks: List<Snack>) : Adapter<SnackAdapter.SnackViewHolder>() {
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SnackViewHolder {
+        val inflater = LayoutInflater.from(parent.context)
+        val root = inflater.inflate(R.layout.item_snack_view, parent, false)
+        return SnackViewHolder(root)
+    }
+
+    override fun onBindViewHolder(holder: SnackViewHolder, position: Int) {
+        holder.bind(snacks[position])
+    }
+
+    override fun getItemCount(): Int {
+        return snacks.size
+    }
+
+    class SnackViewHolder(rootView: View) : ViewHolder(rootView) {
+        private val snackImageView = rootView.findViewById<ImageView>(R.id.snackImageView)
+        private val snackNameTextView = rootView.findViewById<TextView>(R.id.snackNameTextView)
+
+        fun bind(snack: Snack) {
+            snackImageView.setImageResource(snack.imageDrawable)
+            snackNameTextView.text = snack.name
+        }
+    }
+}
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/views/FeedAdapter.kt b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/views/FeedAdapter.kt
new file mode 100644
index 0000000..07c13e2
--- /dev/null
+++ b/compose/integration-tests/hero/hero-implementation/src/main/java/androidx/compose/integration/hero/implementation/jetsnack/views/FeedAdapter.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.integration.hero.implementation.jetsnack.views
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.compose.integration.hero.implementation.R
+import androidx.compose.integration.hero.implementation.jetsnack.CollectionType
+import androidx.compose.integration.hero.implementation.jetsnack.SnackCollection
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.Adapter
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+
+class FeedAdapter(private val snackCollection: List<SnackCollection>) :
+    Adapter<FeedAdapter.FeedViewHolder>() {
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FeedViewHolder {
+        val inflater = LayoutInflater.from(parent.context)
+        val root = inflater.inflate(R.layout.snack_feed, parent, false)
+        return FeedViewHolder(root)
+    }
+
+    override fun onBindViewHolder(holder: FeedViewHolder, position: Int) {
+        holder.bind(snackCollection[position])
+    }
+
+    override fun getItemCount(): Int {
+        return snackCollection.size
+    }
+
+    class FeedViewHolder(rootView: View) : ViewHolder(rootView) {
+        private val nameTextView = rootView.findViewById<TextView>(R.id.nameTextView)
+        private val feedRecyclerView = rootView.findViewById<RecyclerView>(R.id.feedRecyclerView)
+
+        fun bind(snackCollection: SnackCollection) {
+            nameTextView.text = snackCollection.name
+            val feedAdapter =
+                if (snackCollection.type == CollectionType.Highlight)
+                    DessertAdapter(snackCollection.snacks)
+                else SnackAdapter(snackCollection.snacks)
+            feedRecyclerView.adapter = feedAdapter
+        }
+    }
+}
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/res/drawable/arrow_forward_24.xml b/compose/integration-tests/hero/hero-implementation/src/main/res/drawable/arrow_forward_24.xml
new file mode 100644
index 0000000..77e4f24
--- /dev/null
+++ b/compose/integration-tests/hero/hero-implementation/src/main/res/drawable/arrow_forward_24.xml
@@ -0,0 +1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+      
+    <path android:fillColor="@android:color/white" android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
+    
+</vector>
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/res/layout/item_snack_card_view.xml b/compose/integration-tests/hero/hero-implementation/src/main/res/layout/item_snack_card_view.xml
new file mode 100644
index 0000000..bda5a6d
--- /dev/null
+++ b/compose/integration-tests/hero/hero-implementation/src/main/res/layout/item_snack_card_view.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/cupcakeCardView"
+    android:layout_width="170dp"
+    android:layout_height="250dp"
+    android:padding="16dp"
+    app:layout_constraintStart_toStartOf="parent"
+    app:layout_constraintTop_toTopOf="parent"
+    android:layout_margin="8dp"
+    app:cardCornerRadius="16dp"
+    app:cardElevation="6dp">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cupcakeView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <androidx.constraintlayout.widget.Guideline
+            android:id="@+id/guideline"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            app:layout_constraintGuide_begin="160dp" />
+
+        <View
+            android:id="@+id/collectionBox"
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            android:background="@color/cardview_dark_background"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.constraintlayout.utils.widget.ImageFilterView
+            android:id="@+id/snackImageView"
+            android:layout_width="120dp"
+            android:layout_height="120dp"
+            android:scaleType="centerCrop"
+            android:src="@drawable/donut"
+            app:layout_constraintBottom_toBottomOf="@id/guideline"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:roundPercent="1" />
+
+
+        <TextView
+            android:id="@+id/snackNameTextView"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:fontFamily="@font/karla_regular"
+            android:textColor="@android:color/black"
+            android:textSize="20sp"
+            android:textStyle="bold"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/guideline"
+            tools:text="Cupcake" />
+
+        <TextView
+            android:id="@+id/snackTagLineTextView"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/snackNameTextView"
+            tools:text="A tag line" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.cardview.widget.CardView>
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/res/layout/item_snack_view.xml b/compose/integration-tests/hero/hero-implementation/src/main/res/layout/item_snack_view.xml
new file mode 100644
index 0000000..8420b56
--- /dev/null
+++ b/compose/integration-tests/hero/hero-implementation/src/main/res/layout/item_snack_view.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_margin="8dp">
+
+    <androidx.constraintlayout.utils.widget.ImageFilterView
+        android:id="@+id/snackImageView"
+        android:layout_width="120dp"
+        android:layout_height="120dp"
+        android:elevation="4dp"
+        android:scaleType="fitXY"
+        android:src="@drawable/donut"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:roundPercent="1" />
+
+    <TextView
+        android:id="@+id/snackNameTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:textColor="@android:color/black"
+        android:textSize="20sp"
+        android:textStyle="bold"
+        android:fontFamily="@font/karla_regular"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/snackImageView"
+        tools:text="Cupcake" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/compose/integration-tests/hero/hero-implementation/src/main/res/layout/snack_feed.xml b/compose/integration-tests/hero/hero-implementation/src/main/res/layout/snack_feed.xml
new file mode 100644
index 0000000..9e48a24
--- /dev/null
+++ b/compose/integration-tests/hero/hero-implementation/src/main/res/layout/snack_feed.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_margin="8dp">
+
+    <TextView
+        android:id="@+id/nameTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@android:color/holo_blue_dark"
+        android:textSize="20sp"
+        android:textStyle="bold"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="Android pick" />
+
+    <ImageView
+        android:id="@+id/arrowImageView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:contentDescription="@null"
+        android:src="@drawable/arrow_forward_24"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/feedRecyclerView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:orientation="horizontal"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/arrowImageView"
+        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/compose/integration-tests/hero/macrobenchmark-target/build.gradle b/compose/integration-tests/hero/macrobenchmark-target/build.gradle
index 609eb0b..bcecd70 100644
--- a/compose/integration-tests/hero/macrobenchmark-target/build.gradle
+++ b/compose/integration-tests/hero/macrobenchmark-target/build.gradle
@@ -45,6 +45,7 @@
     implementation(project(":activity:activity-compose"))
     implementation("androidx.appcompat:appcompat:1.4.1")
     implementation("androidx.cardview:cardview:1.0.0")
+    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
     implementation(project(":compose:foundation:foundation-layout"))
     implementation(project(":compose:foundation:foundation"))
     implementation(project(":compose:material:material"))
diff --git a/compose/integration-tests/hero/macrobenchmark-target/src/main/AndroidManifest.xml b/compose/integration-tests/hero/macrobenchmark-target/src/main/AndroidManifest.xml
index f8d2deb..5149689 100644
--- a/compose/integration-tests/hero/macrobenchmark-target/src/main/AndroidManifest.xml
+++ b/compose/integration-tests/hero/macrobenchmark-target/src/main/AndroidManifest.xml
@@ -47,5 +47,19 @@
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
+        <activity
+            android:name=".jetsnack.JetsnackViewActivity"
+            android:label="Jetsnack"
+            android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="androidx.compose.integration.hero.macrobenchmark.target.jetsnack.JETSNACK_VIEWS_ACTIVITY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
\ No newline at end of file
diff --git a/compose/integration-tests/hero/macrobenchmark-target/src/main/java/androidx/compose/integration/hero/macrobenchmark/target/jetsnack/JetsnackActivity.kt b/compose/integration-tests/hero/macrobenchmark-target/src/main/java/androidx/compose/integration/hero/macrobenchmark/target/jetsnack/JetsnackActivity.kt
index 0fbdab1..6ab9490 100644
--- a/compose/integration-tests/hero/macrobenchmark-target/src/main/java/androidx/compose/integration/hero/macrobenchmark/target/jetsnack/JetsnackActivity.kt
+++ b/compose/integration-tests/hero/macrobenchmark-target/src/main/java/androidx/compose/integration/hero/macrobenchmark/target/jetsnack/JetsnackActivity.kt
@@ -19,8 +19,8 @@
 import android.os.Bundle
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
-import androidx.compose.integration.hero.implementation.jetsnack.Feed
-import androidx.compose.integration.hero.implementation.jetsnack.theme.JetsnackTheme
+import androidx.compose.integration.hero.implementation.jetsnack.compose.Feed
+import androidx.compose.integration.hero.implementation.jetsnack.compose.theme.JetsnackTheme
 import androidx.compose.integration.hero.macrobenchmark.target.launchIdlenessTracking
 
 class JetsnackActivity : ComponentActivity() {
diff --git a/compose/integration-tests/hero/macrobenchmark-target/src/main/java/androidx/compose/integration/hero/macrobenchmark/target/jetsnack/JetsnackViewActivity.kt b/compose/integration-tests/hero/macrobenchmark-target/src/main/java/androidx/compose/integration/hero/macrobenchmark/target/jetsnack/JetsnackViewActivity.kt
new file mode 100644
index 0000000..9e14dee
--- /dev/null
+++ b/compose/integration-tests/hero/macrobenchmark-target/src/main/java/androidx/compose/integration/hero/macrobenchmark/target/jetsnack/JetsnackViewActivity.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.integration.hero.macrobenchmark.target.jetsnack
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.compose.integration.hero.implementation.jetsnack.SnackRepo
+import androidx.compose.integration.hero.implementation.jetsnack.views.FeedAdapter
+import androidx.compose.integration.hero.macrobenchmark.target.R
+import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+
+class JetsnackViewActivity : AppCompatActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        setContentView(R.layout.activity_jetsnack_view)
+        val feedAdapter = FeedAdapter(SnackRepo.getSnacks())
+
+        val recycler = findViewById<RecyclerView>(R.id.snackFeedRecyclerView)
+        with(recycler) {
+            layoutManager = LinearLayoutManager(context!!)
+            adapter = feedAdapter
+            addItemDecoration(
+                DividerItemDecoration(context!!, (layoutManager as LinearLayoutManager).orientation)
+            )
+        }
+
+        reportFullyDrawn()
+    }
+}
diff --git a/compose/integration-tests/hero/macrobenchmark-target/src/main/res/layout/activity_jetsnack_view.xml b/compose/integration-tests/hero/macrobenchmark-target/src/main/res/layout/activity_jetsnack_view.xml
new file mode 100644
index 0000000..f649d2c
--- /dev/null
+++ b/compose/integration-tests/hero/macrobenchmark-target/src/main/res/layout/activity_jetsnack_view.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/deliveryAddressTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:drawableEnd="@android:drawable/arrow_down_float"
+        android:drawablePadding="4dp"
+        android:padding="16dp"
+        android:text="Delivery to 1600 Amphitheater Way"
+        android:textSize="16sp"
+        android:textStyle="bold"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/divider"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@android:color/darker_gray"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/deliveryAddressTextView" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/snackFeedRecyclerView"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/divider" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackScrollBenchmark.kt b/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackScrollBenchmark.kt
index 70ac8aa..72aea3d 100644
--- a/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackScrollBenchmark.kt
+++ b/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackScrollBenchmark.kt
@@ -41,37 +41,59 @@
     @get:Rule val benchmarkRule = MacrobenchmarkRule()
 
     @Test
-    fun scrollHome() {
-        val ACTION = "$PACKAGE_NAME.jetsnack.JETSNACK_ACTIVITY"
+    fun scrollHome() =
+        benchmarkScroll(
+            action = "$PACKAGE_NAME.jetsnack.JETSNACK_ACTIVITY",
+            measureBlock = {
+                val searchCondition = Until.hasObject(By.res("snack_collection"))
+                // Wait until a snack collection item within the list is rendered
+                device.wait(searchCondition, 3_000)
+
+                val contentList = device.findObject(By.res("snack_list"))
+                scrollActions(contentList, idleMethod = { device.waitForComposeIdle() })
+            }
+        )
+
+    @Test
+    fun scrollViewsHome() =
+        benchmarkScroll(
+            action = "$PACKAGE_NAME.jetsnack.JETSNACK_VIEWS_ACTIVITY",
+            measureBlock = {
+                val resPkg = "androidx.compose.integration.hero.macrobenchmark.target"
+                val searchCondition = Until.hasObject(By.res(resPkg, "snackImageView"))
+                // Wait until a snack collection item within the list is rendered
+                device.wait(searchCondition, 3_000)
+
+                val contentList = device.findObject(By.res(resPkg, "snackFeedRecyclerView"))
+                scrollActions(contentList, idleMethod = { device.waitForIdle() })
+            }
+        )
+
+    private fun benchmarkScroll(action: String, measureBlock: MacrobenchmarkScope.() -> Unit) =
         benchmarkRule.measureRepeated(
             packageName = PACKAGE_NAME,
             metrics = listOf(FrameTimingMetric()),
             compilationMode = compilationMode,
-            iterations = ITERATIONS
-        ) {
-            val intent = Intent()
-            intent.action = ACTION
-            startActivityAndWait(intent)
+            iterations = ITERATIONS,
+            measureBlock = {
+                val intent = Intent()
+                intent.action = action
+                startActivityAndWait(intent)
 
-            val searchCondition = Until.hasObject(By.res("snack_collection"))
-            // Wait until a snack collection item within the list is rendered
-            device.wait(searchCondition, 3_000)
+                measureBlock()
+            }
+        )
 
-            val contentList = device.findObject(By.res("snack_list"))
-            scrollActions(contentList)
-        }
-    }
-
-    private fun MacrobenchmarkScope.scrollActions(contentList: UiObject2) {
+    private fun MacrobenchmarkScope.scrollActions(contentList: UiObject2, idleMethod: () -> Unit) {
         // Set gesture margin to avoid triggering gesture navigation
         contentList.setGestureMargin(device.displayWidth / 5)
 
         contentList.fling(Direction.DOWN)
-        device.waitForComposeIdle()
+        idleMethod()
         contentList.fling(Direction.UP)
-        device.waitForComposeIdle()
+        idleMethod()
         contentList.fling(Direction.DOWN)
-        device.waitForComposeIdle()
+        idleMethod()
     }
 
     companion object {
diff --git a/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackStartupBenchmark.kt b/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackStartupBenchmark.kt
index 089b999..6315cdc 100644
--- a/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackStartupBenchmark.kt
+++ b/compose/integration-tests/hero/macrobenchmark/src/main/java/androidx/compose/integration/hero/macrobenchmark/jetsnack/JetsnackStartupBenchmark.kt
@@ -33,16 +33,19 @@
 class JetsnackStartupBenchmark(val startupMode: StartupMode, val compilationMode: CompilationMode) {
     @get:Rule val benchmarkRule = MacrobenchmarkRule()
 
-    @Test
-    fun startup() =
+    private fun measureStartup(action: String) =
         benchmarkRule.measureStartup(
             compilationMode = compilationMode,
             startupMode = startupMode,
-            packageName = PACKAGE_NAME,
+            packageName = PACKAGE_NAME
         ) {
-            action = "$PACKAGE_NAME.jetsnack.JETSNACK_ACTIVITY"
+            this.action = action
         }
 
+    @Test fun startup() = measureStartup("$PACKAGE_NAME.jetsnack.JETSNACK_ACTIVITY")
+
+    @Test fun startupViews() = measureStartup("$PACKAGE_NAME.jetsnack.JETSNACK_VIEWS_ACTIVITY")
+
     companion object {
         @Parameterized.Parameters(name = "startup={0},compilationMode={1}")
         @JvmStatic
diff --git a/compose/material/material/api/current.txt b/compose/material/material/api/current.txt
index 1bd3768..b5452f5 100644
--- a/compose/material/material/api/current.txt
+++ b/compose/material/material/api/current.txt
@@ -79,7 +79,7 @@
   }
 
   public static final class BackdropScaffoldState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,? extends java.lang.Object!> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState, androidx.compose.ui.unit.Density density);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,? extends java.lang.Object?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState, androidx.compose.ui.unit.Density density);
   }
 
   public enum BackdropValue {
@@ -183,7 +183,7 @@
   }
 
   public static final class BottomSheetState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,? extends java.lang.Object!> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,? extends java.lang.Object?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
   }
 
   public enum BottomSheetValue {
@@ -571,7 +571,7 @@
   }
 
   public static final class ModalBottomSheetState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,? extends java.lang.Object!> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,? extends java.lang.Object?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
   }
 
   public enum ModalBottomSheetValue {
diff --git a/compose/material/material/api/restricted_current.txt b/compose/material/material/api/restricted_current.txt
index 1bd3768..b5452f5 100644
--- a/compose/material/material/api/restricted_current.txt
+++ b/compose/material/material/api/restricted_current.txt
@@ -79,7 +79,7 @@
   }
 
   public static final class BackdropScaffoldState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,? extends java.lang.Object!> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState, androidx.compose.ui.unit.Density density);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,? extends java.lang.Object?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState, androidx.compose.ui.unit.Density density);
   }
 
   public enum BackdropValue {
@@ -183,7 +183,7 @@
   }
 
   public static final class BottomSheetState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,? extends java.lang.Object!> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,? extends java.lang.Object?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
   }
 
   public enum BottomSheetValue {
@@ -571,7 +571,7 @@
   }
 
   public static final class ModalBottomSheetState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,? extends java.lang.Object!> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,? extends java.lang.Object?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
   }
 
   public enum ModalBottomSheetValue {
diff --git a/compose/material3/adaptive/adaptive-layout/api/1.0.0-beta03.txt b/compose/material3/adaptive/adaptive-layout/api/1.0.0-beta03.txt
index f775981..87f05eb 100644
--- a/compose/material3/adaptive/adaptive-layout/api/1.0.0-beta03.txt
+++ b/compose/material3/adaptive/adaptive-layout/api/1.0.0-beta03.txt
@@ -162,8 +162,8 @@
   }
 
   public final class ThreePaneScaffoldValueKt {
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>? currentDestination);
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>> destinationHistory);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>? currentDestination);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>> destinationHistory);
   }
 
 }
diff --git a/compose/material3/adaptive/adaptive-layout/api/current.txt b/compose/material3/adaptive/adaptive-layout/api/current.txt
index f775981..87f05eb 100644
--- a/compose/material3/adaptive/adaptive-layout/api/current.txt
+++ b/compose/material3/adaptive/adaptive-layout/api/current.txt
@@ -162,8 +162,8 @@
   }
 
   public final class ThreePaneScaffoldValueKt {
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>? currentDestination);
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>> destinationHistory);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>? currentDestination);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>> destinationHistory);
   }
 
 }
diff --git a/compose/material3/adaptive/adaptive-layout/api/restricted_1.0.0-beta03.txt b/compose/material3/adaptive/adaptive-layout/api/restricted_1.0.0-beta03.txt
index f775981..87f05eb 100644
--- a/compose/material3/adaptive/adaptive-layout/api/restricted_1.0.0-beta03.txt
+++ b/compose/material3/adaptive/adaptive-layout/api/restricted_1.0.0-beta03.txt
@@ -162,8 +162,8 @@
   }
 
   public final class ThreePaneScaffoldValueKt {
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>? currentDestination);
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>> destinationHistory);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>? currentDestination);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>> destinationHistory);
   }
 
 }
diff --git a/compose/material3/adaptive/adaptive-layout/api/restricted_current.txt b/compose/material3/adaptive/adaptive-layout/api/restricted_current.txt
index f775981..87f05eb 100644
--- a/compose/material3/adaptive/adaptive-layout/api/restricted_current.txt
+++ b/compose/material3/adaptive/adaptive-layout/api/restricted_current.txt
@@ -162,8 +162,8 @@
   }
 
   public final class ThreePaneScaffoldValueKt {
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>? currentDestination);
-    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object!>> destinationHistory);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>? currentDestination);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends java.lang.Object?>> destinationHistory);
   }
 
 }
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMotionTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMotionTest.kt
new file mode 100644
index 0000000..f559d54
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMotionTest.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.adaptive.layout
+
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.AnimateBounds
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.EnterFromLeft
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.EnterFromLeftDelayed
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.EnterFromRight
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.EnterFromRightDelayed
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.EnterWithExpand
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.ExitToLeft
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.ExitToRight
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.ExitWithShrink
+import androidx.compose.material3.adaptive.layout.DefaultPaneMotion.Companion.NoMotion
+import androidx.compose.material3.adaptive.layout.PaneAdaptedValue.Companion.Expanded
+import androidx.compose.material3.adaptive.layout.PaneAdaptedValue.Companion.Hidden
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+@RunWith(JUnit4::class)
+class PaneMotionTest {
+    @Test
+    fun test_allThreePaneMotions() {
+        for (from in ExpectedThreePaneMotions.indices) {
+            for (to in ExpectedThreePaneMotions.indices) {
+                val fromValue = from.toThreePaneScaffoldValue()
+                val toValue = to.toThreePaneScaffoldValue()
+                assertWithMessage("From $fromValue to $toValue: ")
+                    .that(calculatePaneMotion(fromValue, toValue, MockThreePaneOrder))
+                    .isEqualTo(ExpectedThreePaneMotions[from][to])
+            }
+        }
+    }
+}
+
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+private fun Int.toThreePaneScaffoldValue(): ThreePaneScaffoldValue {
+    return when (this) {
+        0 -> ThreePaneScaffoldValue(Hidden, Hidden, Hidden)
+        1 -> ThreePaneScaffoldValue(Expanded, Hidden, Hidden)
+        2 -> ThreePaneScaffoldValue(Hidden, Expanded, Hidden)
+        3 -> ThreePaneScaffoldValue(Hidden, Hidden, Expanded)
+        4 -> ThreePaneScaffoldValue(Expanded, Expanded, Hidden)
+        5 -> ThreePaneScaffoldValue(Expanded, Hidden, Expanded)
+        6 -> ThreePaneScaffoldValue(Hidden, Expanded, Expanded)
+        7 -> ThreePaneScaffoldValue(Expanded, Expanded, Expanded)
+        else -> throw AssertionError("Unexpected scaffold value: $this")
+    }
+}
+
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+private val MockThreePaneOrder =
+    ThreePaneScaffoldHorizontalOrder(
+        ThreePaneScaffoldRole.Primary,
+        ThreePaneScaffoldRole.Secondary,
+        ThreePaneScaffoldRole.Tertiary
+    )
+
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+private val ExpectedThreePaneMotions =
+    arrayOf(
+        // From H, H, H
+        arrayOf(
+            arrayOf(NoMotion, NoMotion, NoMotion), // To H, H, H
+            arrayOf(EnterFromRight, NoMotion, NoMotion), // To V, H, H
+            arrayOf(NoMotion, EnterFromRight, NoMotion), // To H, V, H
+            arrayOf(NoMotion, NoMotion, EnterFromRight), // To H, H, V
+            arrayOf(EnterFromRight, EnterFromRight, NoMotion), // To V, V, H
+            arrayOf(EnterFromRight, NoMotion, EnterFromRight), // To V, H, V
+            arrayOf(NoMotion, EnterFromRight, EnterFromRight), // To H, V, V
+            arrayOf(EnterFromRight, EnterFromRight, EnterFromRight), // To V, V, V
+        ),
+        // From V, H, H
+        arrayOf(
+            arrayOf(ExitToRight, NoMotion, NoMotion), // To H, H, H
+            arrayOf(AnimateBounds, NoMotion, NoMotion), // To V, H, H
+            arrayOf(ExitToLeft, EnterFromRight, NoMotion), // To H, V, H
+            arrayOf(ExitToLeft, NoMotion, EnterFromRight), // To H, H, V
+            arrayOf(AnimateBounds, EnterFromRight, NoMotion), // To V, V, H
+            arrayOf(AnimateBounds, NoMotion, EnterFromRight), // To V, H, V
+            arrayOf(ExitToLeft, EnterFromRight, EnterFromRight), // To H, V, V
+            arrayOf(AnimateBounds, EnterFromRight, EnterFromRight), // To V, V, V
+        ),
+        // From H, V, H
+        arrayOf(
+            arrayOf(NoMotion, ExitToRight, NoMotion), // To H, H, H
+            arrayOf(EnterFromLeft, ExitToRight, NoMotion), // To V, H, H
+            arrayOf(NoMotion, AnimateBounds, NoMotion), // To H, V, H
+            arrayOf(NoMotion, ExitToLeft, EnterFromRight), // To H, H, V
+            arrayOf(EnterFromLeft, AnimateBounds, NoMotion), // To V, V, H
+            arrayOf(EnterFromLeft, ExitToRight, EnterFromRightDelayed), // To V, H, V
+            arrayOf(NoMotion, AnimateBounds, EnterFromRight), // To H, V, V
+            arrayOf(EnterFromLeft, AnimateBounds, EnterFromRight), // To V, V, V
+        ),
+        // From H, H, V
+        arrayOf(
+            arrayOf(NoMotion, NoMotion, ExitToRight), // To H, H, H
+            arrayOf(EnterFromLeft, NoMotion, ExitToRight), // To V, H, H
+            arrayOf(NoMotion, EnterFromLeft, ExitToRight), // To H, V, H
+            arrayOf(NoMotion, NoMotion, AnimateBounds), // To H, H, V
+            arrayOf(EnterFromLeft, EnterFromLeft, ExitToRight), // To V, V, H
+            arrayOf(EnterFromLeft, NoMotion, AnimateBounds), // To V, H, V
+            arrayOf(NoMotion, EnterFromLeft, AnimateBounds), // To H, V, V
+            arrayOf(EnterFromLeft, EnterFromLeft, AnimateBounds), // To V, V, V
+        ),
+        // From V, V, H
+        arrayOf(
+            arrayOf(ExitToRight, ExitToRight, NoMotion), // To H, H, H
+            arrayOf(AnimateBounds, ExitToRight, NoMotion), // To V, H, H
+            arrayOf(ExitToLeft, AnimateBounds, NoMotion), // To H, V, H
+            arrayOf(ExitToLeft, ExitToLeft, EnterFromRight), // To H, H, V
+            arrayOf(AnimateBounds, AnimateBounds, NoMotion), // To V, V, H
+            arrayOf(AnimateBounds, ExitToRight, EnterFromRightDelayed), // To V, H, V
+            arrayOf(ExitToLeft, AnimateBounds, EnterFromRight), // To H, V, V
+            arrayOf(AnimateBounds, AnimateBounds, EnterFromRight), // To V, V, V
+        ),
+        // From V, H, V
+        arrayOf(
+            arrayOf(ExitToRight, NoMotion, ExitToRight), // To H, H, H
+            arrayOf(AnimateBounds, NoMotion, ExitToRight), // To V, H, H
+            arrayOf(ExitToLeft, EnterFromRightDelayed, ExitToRight), // To H, V, H
+            arrayOf(ExitToLeft, NoMotion, AnimateBounds), // To H, H, V
+            arrayOf(AnimateBounds, EnterFromRightDelayed, ExitToRight), // To V, V, H
+            arrayOf(AnimateBounds, NoMotion, AnimateBounds), // To V, H, V
+            arrayOf(ExitToLeft, EnterFromLeftDelayed, AnimateBounds), // To H, V, V
+            arrayOf(AnimateBounds, EnterWithExpand, AnimateBounds), // To V, V, V
+        ),
+        // From H, V, V
+        arrayOf(
+            arrayOf(NoMotion, ExitToRight, ExitToRight), // To H, H, H
+            arrayOf(EnterFromLeft, ExitToRight, ExitToRight), // To V, H, H
+            arrayOf(NoMotion, AnimateBounds, ExitToRight), // To H, V, H
+            arrayOf(NoMotion, ExitToLeft, AnimateBounds), // To H, H, V
+            arrayOf(EnterFromLeft, AnimateBounds, ExitToRight), // To V, V, H
+            arrayOf(EnterFromLeftDelayed, ExitToLeft, AnimateBounds), // To V, H, V
+            arrayOf(NoMotion, AnimateBounds, AnimateBounds), // To H, V, V
+            arrayOf(EnterFromLeft, AnimateBounds, AnimateBounds), // To V, V, V
+        ),
+        // From V, V, V
+        arrayOf(
+            arrayOf(ExitToRight, ExitToRight, ExitToRight), // To H, H, H
+            arrayOf(AnimateBounds, ExitToRight, ExitToRight), // To V, H, H
+            arrayOf(ExitToLeft, AnimateBounds, ExitToRight), // To H, V, H
+            arrayOf(ExitToLeft, ExitToLeft, AnimateBounds), // To H, H, V
+            arrayOf(AnimateBounds, AnimateBounds, ExitToRight), // To V, V, H
+            arrayOf(AnimateBounds, ExitWithShrink, AnimateBounds), // To V, H, V
+            arrayOf(ExitToLeft, AnimateBounds, AnimateBounds), // To H, V, V
+            arrayOf(AnimateBounds, AnimateBounds, AnimateBounds), // To V, V, V
+        ),
+    )
diff --git a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneMotion.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneMotion.kt
new file mode 100644
index 0000000..ecb54e7
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneMotion.kt
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.adaptive.layout
+
+import androidx.annotation.VisibleForTesting
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import kotlin.math.max
+import kotlin.math.min
+
+@ExperimentalMaterial3AdaptiveApi
+internal interface PaneMotion {
+    // TODO (conradchen): Implement the following fields
+    // val enterTransition: EnterTransition
+    // val exitTransition: ExitTransition
+    // val animateBoundsModifier: Modifier
+}
+
+@ExperimentalMaterial3AdaptiveApi
+@JvmInline
+internal value class DefaultPaneMotion private constructor(val value: Int) : PaneMotion {
+    companion object {
+        val NoMotion = DefaultPaneMotion(0)
+        val AnimateBounds = DefaultPaneMotion(1)
+        val EnterFromLeft = DefaultPaneMotion(2)
+        val EnterFromRight = DefaultPaneMotion(3)
+        val EnterFromLeftDelayed = DefaultPaneMotion(4)
+        val EnterFromRightDelayed = DefaultPaneMotion(5)
+        val ExitToLeft = DefaultPaneMotion(6)
+        val ExitToRight = DefaultPaneMotion(7)
+        val ExitWithShrink = DefaultPaneMotion(8)
+        val EnterWithExpand = DefaultPaneMotion(9)
+    }
+
+    override fun toString(): String =
+        when (value) {
+            0 -> "NoMotion"
+            1 -> "AnimateBounds"
+            2 -> "EnterFromLeft"
+            3 -> "EnterFromRight"
+            4 -> "EnterFromLeftDelayed"
+            5 -> "EnterFromRightDelayed"
+            6 -> "ExitToLeft"
+            7 -> "ExitToRight"
+            8 -> "ExitWithShrink"
+            9 -> "EnterWithExpand"
+            else -> "Undefined($value)"
+        }
+}
+
+@ExperimentalMaterial3AdaptiveApi
+@VisibleForTesting
+internal fun <T> calculatePaneMotion(
+    previousScaffoldValue: PaneScaffoldValue<T>,
+    currentScaffoldValue: PaneScaffoldValue<T>,
+    paneOrder: PaneScaffoldHorizontalOrder<T>
+): Array<PaneMotion> {
+    val numOfPanes = paneOrder.size
+    val paneStatus = Array(numOfPanes) { PaneMotionStatus.Hidden }
+    val paneMotions = Array<PaneMotion>(numOfPanes) { DefaultPaneMotion.NoMotion }
+    var firstShownPaneIndex = numOfPanes
+    var firstEnteringPaneIndex = numOfPanes
+    var lastShownPaneIndex = -1
+    var lastEnteringPaneIndex = -1
+    // First pass, to decide the entering/exiting status of each pane, and collect info for
+    // deciding, given a certain pane, if there's a pane on its left or on its right that is
+    // entering or keep showing during the transition.
+    // Also set up the motions of all panes that keep showing to AnimateBounds.
+    paneOrder.forEachIndexed { i, role ->
+        paneStatus[i] =
+            PaneMotionStatus.calculate(previousScaffoldValue[role], currentScaffoldValue[role])
+        when (paneStatus[i]) {
+            PaneMotionStatus.Shown -> {
+                firstShownPaneIndex = min(firstShownPaneIndex, i)
+                lastShownPaneIndex = max(lastShownPaneIndex, i)
+                paneMotions[i] = DefaultPaneMotion.AnimateBounds
+            }
+            PaneMotionStatus.Entering -> {
+                firstEnteringPaneIndex = min(firstEnteringPaneIndex, i)
+                lastEnteringPaneIndex = max(lastEnteringPaneIndex, i)
+            }
+        }
+    }
+    // Second pass, to decide the exiting motions of all exiting panes.
+    // Also collects info for the next pass to decide the entering motions of entering panes.
+    var hasPanesExitToRight = false
+    var hasPanesExitToLeft = false
+    var firstPaneExitToRightIndex = numOfPanes
+    var lastPaneExitToLeftIndex = -1
+    paneOrder.forEachIndexed { i, _ ->
+        val hasShownPanesOnLeft = firstShownPaneIndex < i
+        val hasEnteringPanesOnLeft = firstEnteringPaneIndex < i
+        val hasShownPanesOnRight = lastShownPaneIndex > i
+        val hasEnteringPanesOnRight = lastEnteringPaneIndex > i
+        if (paneStatus[i] == PaneMotionStatus.Exiting) {
+            paneMotions[i] =
+                if (!hasShownPanesOnRight && !hasEnteringPanesOnRight) {
+                    // No panes will interfere the motion on the right, exit to right.
+                    hasPanesExitToRight = true
+                    firstPaneExitToRightIndex = min(firstPaneExitToRightIndex, i)
+                    DefaultPaneMotion.ExitToRight
+                } else if (!hasShownPanesOnLeft && !hasEnteringPanesOnLeft) {
+                    // No panes will interfere the motion on the left, exit to left.
+                    hasPanesExitToLeft = true
+                    lastPaneExitToLeftIndex = max(lastPaneExitToLeftIndex, i)
+                    DefaultPaneMotion.ExitToLeft
+                } else if (!hasShownPanesOnRight) {
+                    // Only showing panes can interfere the motion on the right, exit to right.
+                    hasPanesExitToRight = true
+                    firstPaneExitToRightIndex = min(firstPaneExitToRightIndex, i)
+                    DefaultPaneMotion.ExitToRight
+                } else if (!hasShownPanesOnLeft) { // Only showing panes on left
+                    // Only showing panes can interfere the motion on the left, exit to left.
+                    hasPanesExitToLeft = true
+                    lastPaneExitToLeftIndex = max(lastPaneExitToLeftIndex, i)
+                    DefaultPaneMotion.ExitToLeft
+                } else {
+                    // Both sides has panes that keep being visible during transition, shrink to
+                    // exit
+                    DefaultPaneMotion.ExitWithShrink
+                }
+        }
+    }
+    // Third pass, to decide the entering motions of all entering panes.
+    paneOrder.forEachIndexed { i, _ ->
+        val hasShownPanesOnLeft = firstShownPaneIndex < i
+        val hasShownPanesOnRight = lastShownPaneIndex > i
+        val hasLeftPaneExitToRight = firstPaneExitToRightIndex < i
+        val hasRightPaneExitToLeft = lastPaneExitToLeftIndex > i
+        // For a given pane, if there's another pane that keeps showing on its right, or there's
+        // a pane on its right that's exiting to its left, the pane cannot enter from right since
+        // doing so will either interfere with the showing pane, or cause incorrect order of the
+        // pane position during the transition. In other words, this case is considered "blocking".
+        // Same on the other side.
+        val noBlockingPanesOnRight = !hasShownPanesOnRight && !hasRightPaneExitToLeft
+        val noBlockingPanesOnLeft = !hasShownPanesOnLeft && !hasLeftPaneExitToRight
+        if (paneStatus[i] == PaneMotionStatus.Entering) {
+            paneMotions[i] =
+                if (noBlockingPanesOnRight && !hasPanesExitToRight) {
+                    // No panes will block the motion on the right, enter from right.
+                    DefaultPaneMotion.EnterFromRight
+                } else if (noBlockingPanesOnLeft && !hasPanesExitToLeft) {
+                    // No panes will block the motion on the left, enter from left.
+                    DefaultPaneMotion.EnterFromLeft
+                } else if (noBlockingPanesOnRight) {
+                    // Only hiding panes can interfere the motion on the right, enter from right.
+                    DefaultPaneMotion.EnterFromRightDelayed
+                } else if (noBlockingPanesOnLeft) {
+                    // Only hiding panes can interfere the motion on the left, enter from left.
+                    DefaultPaneMotion.EnterFromLeftDelayed
+                } else {
+                    // Both sides has panes that keep being visible during transition, expand to
+                    // enter
+                    DefaultPaneMotion.EnterWithExpand
+                }
+        }
+    }
+    return paneMotions
+}
+
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+@JvmInline
+private value class PaneMotionStatus private constructor(val value: Int) {
+    companion object {
+        val Hidden = PaneMotionStatus(0)
+        val Exiting = PaneMotionStatus(1)
+        val Entering = PaneMotionStatus(2)
+        val Shown = PaneMotionStatus(3)
+
+        fun calculate(
+            previousValue: PaneAdaptedValue,
+            currentValue: PaneAdaptedValue
+        ): PaneMotionStatus {
+            val wasShown = if (previousValue == PaneAdaptedValue.Hidden) 0 else 1
+            val isShown = if (currentValue == PaneAdaptedValue.Hidden) 0 else 2
+            return PaneMotionStatus(wasShown or isShown)
+        }
+    }
+}
diff --git a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldHorizontalOrder.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldHorizontalOrder.kt
new file mode 100644
index 0000000..0d915a2
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldHorizontalOrder.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.adaptive.layout
+
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+
+@ExperimentalMaterial3AdaptiveApi
+internal interface PaneScaffoldHorizontalOrder<T> {
+    val size: Int
+
+    fun indexOf(role: T): Int
+
+    fun forEach(action: (T) -> Unit)
+
+    fun forEachIndexed(action: (Int, T) -> Unit)
+
+    fun forEachIndexedReversed(action: (Int, T) -> Unit)
+}
diff --git a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldValue.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldValue.kt
new file mode 100644
index 0000000..d3b1d1f
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldValue.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.adaptive.layout
+
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+
+@ExperimentalMaterial3AdaptiveApi
+internal interface PaneScaffoldValue<T> {
+    operator fun get(role: T): PaneAdaptedValue
+}
diff --git a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldHorizontalOrder.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldHorizontalOrder.kt
index fb1bff4..1c4edda 100644
--- a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldHorizontalOrder.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldHorizontalOrder.kt
@@ -36,7 +36,7 @@
     val firstPane: ThreePaneScaffoldRole,
     val secondPane: ThreePaneScaffoldRole,
     val thirdPane: ThreePaneScaffoldRole
-) {
+) : PaneScaffoldHorizontalOrder<ThreePaneScaffoldRole> {
     init {
         require(firstPane != secondPane && secondPane != thirdPane && firstPane != thirdPane) {
             "invalid ThreePaneScaffoldHorizontalOrder($firstPane, $secondPane, $thirdPane)" +
@@ -44,6 +44,34 @@
         }
     }
 
+    override val size = 3
+
+    override fun indexOf(role: ThreePaneScaffoldRole) =
+        when (role) {
+            firstPane -> 0
+            secondPane -> 1
+            thirdPane -> 2
+            else -> -1
+        }
+
+    override fun forEach(action: (ThreePaneScaffoldRole) -> Unit) {
+        action(firstPane)
+        action(secondPane)
+        action(thirdPane)
+    }
+
+    override fun forEachIndexed(action: (Int, ThreePaneScaffoldRole) -> Unit) {
+        action(0, firstPane)
+        action(1, secondPane)
+        action(2, thirdPane)
+    }
+
+    override fun forEachIndexedReversed(action: (Int, ThreePaneScaffoldRole) -> Unit) {
+        action(2, thirdPane)
+        action(1, secondPane)
+        action(0, firstPane)
+    }
+
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (other !is ThreePaneScaffoldHorizontalOrder) return false
@@ -73,35 +101,6 @@
     }
 }
 
-@ExperimentalMaterial3AdaptiveApi
-internal inline fun ThreePaneScaffoldHorizontalOrder.forEach(
-    action: (ThreePaneScaffoldRole) -> Unit
-) {
-    action(firstPane)
-    action(secondPane)
-    action(thirdPane)
-}
-
-@ExperimentalMaterial3AdaptiveApi
-internal inline fun ThreePaneScaffoldHorizontalOrder.forEachIndexed(
-    action: (Int, ThreePaneScaffoldRole) -> Unit
-) {
-    action(0, firstPane)
-    action(1, secondPane)
-    action(2, thirdPane)
-}
-
-@ExperimentalMaterial3AdaptiveApi
-internal fun ThreePaneScaffoldHorizontalOrder.indexOf(role: ThreePaneScaffoldRole): Int {
-    forEachIndexed { i, r ->
-        if (r == role) {
-            return i
-        }
-    }
-    // should never reach this far
-    return 0
-}
-
 /** The set of the available pane roles of [ThreePaneScaffold]. */
 enum class ThreePaneScaffoldRole {
     /**
diff --git a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValue.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValue.kt
index 167d325..40ebdd8 100644
--- a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValue.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValue.kt
@@ -172,7 +172,7 @@
     val primary: PaneAdaptedValue,
     val secondary: PaneAdaptedValue,
     val tertiary: PaneAdaptedValue
-) {
+) : PaneScaffoldValue<ThreePaneScaffoldRole> {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (other !is ThreePaneScaffoldValue) return false
@@ -195,7 +195,7 @@
             "tertiary=$tertiary)"
     }
 
-    operator fun get(role: ThreePaneScaffoldRole): PaneAdaptedValue =
+    override operator fun get(role: ThreePaneScaffoldRole): PaneAdaptedValue =
         when (role) {
             ThreePaneScaffoldRole.Primary -> primary
             ThreePaneScaffoldRole.Secondary -> secondary
diff --git a/compose/material3/material3/api/1.3.0-beta03.txt b/compose/material3/material3/api/1.3.0-beta03.txt
index 40db5a9..102d2d3 100644
--- a/compose/material3/material3/api/1.3.0-beta03.txt
+++ b/compose/material3/material3/api/1.3.0-beta03.txt
@@ -124,8 +124,8 @@
   }
 
   public static final class BottomAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetDefaults {
@@ -2112,8 +2112,8 @@
   }
 
   public static final class TopAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class Typography {
@@ -2199,8 +2199,8 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   public final class CarouselStateKt {
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index 40db5a9..102d2d3 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -124,8 +124,8 @@
   }
 
   public static final class BottomAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetDefaults {
@@ -2112,8 +2112,8 @@
   }
 
   public static final class TopAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class Typography {
@@ -2199,8 +2199,8 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   public final class CarouselStateKt {
diff --git a/compose/material3/material3/api/restricted_1.3.0-beta03.txt b/compose/material3/material3/api/restricted_1.3.0-beta03.txt
index 40db5a9..102d2d3 100644
--- a/compose/material3/material3/api/restricted_1.3.0-beta03.txt
+++ b/compose/material3/material3/api/restricted_1.3.0-beta03.txt
@@ -124,8 +124,8 @@
   }
 
   public static final class BottomAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetDefaults {
@@ -2112,8 +2112,8 @@
   }
 
   public static final class TopAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class Typography {
@@ -2199,8 +2199,8 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   public final class CarouselStateKt {
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index 40db5a9..102d2d3 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -124,8 +124,8 @@
   }
 
   public static final class BottomAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetDefaults {
@@ -2112,8 +2112,8 @@
   }
 
   public static final class TopAppBarState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class Typography {
@@ -2199,8 +2199,8 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.carousel.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   public final class CarouselStateKt {
diff --git a/compose/runtime/runtime-livedata/build.gradle b/compose/runtime/runtime-livedata/build.gradle
index 984fafc..2655560 100644
--- a/compose/runtime/runtime-livedata/build.gradle
+++ b/compose/runtime/runtime-livedata/build.gradle
@@ -37,7 +37,7 @@
     api(project(":compose:runtime:runtime"))
     api("androidx.lifecycle:lifecycle-livedata:2.6.1")
     api("androidx.lifecycle:lifecycle-runtime:2.6.1")
-    api("androidx.lifecycle:lifecycle-runtime-compose:2.8.0")
+    api("androidx.lifecycle:lifecycle-runtime-compose:2.8.2")
 
     androidTestImplementation(projectOrArtifact(":compose:ui:ui-test-junit4"))
     androidTestImplementation(project(":compose:test-utils"))
diff --git a/compose/runtime/runtime-tracing/api/1.0.0-beta01.txt b/compose/runtime/runtime-tracing/api/1.0.0-beta01.txt
index b68a158..f00871b 100644
--- a/compose/runtime/runtime-tracing/api/1.0.0-beta01.txt
+++ b/compose/runtime/runtime-tracing/api/1.0.0-beta01.txt
@@ -4,7 +4,7 @@
   public final class ComposeTracingInitializer implements androidx.startup.Initializer<kotlin.Unit> {
     ctor public ComposeTracingInitializer();
     method public void create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
 }
diff --git a/compose/runtime/runtime-tracing/api/current.txt b/compose/runtime/runtime-tracing/api/current.txt
index b68a158..f00871b 100644
--- a/compose/runtime/runtime-tracing/api/current.txt
+++ b/compose/runtime/runtime-tracing/api/current.txt
@@ -4,7 +4,7 @@
   public final class ComposeTracingInitializer implements androidx.startup.Initializer<kotlin.Unit> {
     ctor public ComposeTracingInitializer();
     method public void create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
 }
diff --git a/compose/runtime/runtime-tracing/api/restricted_1.0.0-beta01.txt b/compose/runtime/runtime-tracing/api/restricted_1.0.0-beta01.txt
index b68a158..f00871b 100644
--- a/compose/runtime/runtime-tracing/api/restricted_1.0.0-beta01.txt
+++ b/compose/runtime/runtime-tracing/api/restricted_1.0.0-beta01.txt
@@ -4,7 +4,7 @@
   public final class ComposeTracingInitializer implements androidx.startup.Initializer<kotlin.Unit> {
     ctor public ComposeTracingInitializer();
     method public void create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
 }
diff --git a/compose/runtime/runtime-tracing/api/restricted_current.txt b/compose/runtime/runtime-tracing/api/restricted_current.txt
index b68a158..f00871b 100644
--- a/compose/runtime/runtime-tracing/api/restricted_current.txt
+++ b/compose/runtime/runtime-tracing/api/restricted_current.txt
@@ -4,7 +4,7 @@
   public final class ComposeTracingInitializer implements androidx.startup.Initializer<kotlin.Unit> {
     ctor public ComposeTracingInitializer();
     method public void create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
 }
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index ed8452e..374319c 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -132,7 +132,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.ScopeUpdateScope? endRestartGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endReusableGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endToMarker(int marker);
-    method public androidx.compose.runtime.Applier<? extends java.lang.Object!> getApplier();
+    method public androidx.compose.runtime.Applier<? extends java.lang.Object?> getApplier();
     method @org.jetbrains.annotations.TestOnly public kotlin.coroutines.CoroutineContext getApplyCoroutineContext();
     method @org.jetbrains.annotations.TestOnly public androidx.compose.runtime.ControlledComposition getComposition();
     method public androidx.compose.runtime.tooling.CompositionData getCompositionData();
@@ -144,7 +144,7 @@
     method public androidx.compose.runtime.RecomposeScope? getRecomposeScope();
     method public Object? getRecomposeScopeIdentity();
     method public boolean getSkipping();
-    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(androidx.compose.runtime.MovableContent<? extends java.lang.Object!> value, Object? parameter);
+    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(androidx.compose.runtime.MovableContent<? extends java.lang.Object?> value, Object? parameter);
     method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void insertMovableContentReferences(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference?>> references);
     method @androidx.compose.runtime.ComposeCompilerApi public Object joinKey(Object? left, Object? right);
     method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void recordSideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
@@ -158,8 +158,8 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
     method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
-    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!> value);
-    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!>[] values);
+    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?> value);
+    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?>[] values);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
@@ -167,7 +167,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
     method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
     method @androidx.compose.runtime.ComposeCompilerApi public void useNode();
-    property public abstract androidx.compose.runtime.Applier<? extends java.lang.Object!> applier;
+    property public abstract androidx.compose.runtime.Applier<? extends java.lang.Object?> applier;
     property @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi @org.jetbrains.annotations.TestOnly public abstract kotlin.coroutines.CoroutineContext applyCoroutineContext;
     property @org.jetbrains.annotations.TestOnly public abstract androidx.compose.runtime.ControlledComposition composition;
     property public abstract androidx.compose.runtime.tooling.CompositionData compositionData;
@@ -214,11 +214,11 @@
   }
 
   public final class CompositionKt {
-    method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent);
-    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
-    method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent);
-    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
-    method public static androidx.compose.runtime.ReusableComposition ReusableComposition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent);
+    method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method public static androidx.compose.runtime.ReusableComposition ReusableComposition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent);
     method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
   }
 
@@ -236,8 +236,8 @@
 
   public final class CompositionLocalKt {
     method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.CompositionLocalContext context, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!>[] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?>[] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> compositionLocalOf(optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> defaultFactory);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> compositionLocalWithComputedDefaultOf(kotlin.jvm.functions.Function1<? super androidx.compose.runtime.CompositionLocalAccessorScope,? extends T> defaultComputation);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> staticCompositionLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
@@ -373,9 +373,9 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
-    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> getKey();
+    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> getKey();
     method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
-    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> key;
+    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> key;
     field public static final androidx.compose.runtime.MonotonicFrameClock.Key Key;
   }
 
@@ -467,13 +467,13 @@
   }
 
   public final class PrimitiveSnapshotStateKt {
-    method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, float value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, float value);
   }
 
   public interface ProduceStateScope<T> extends androidx.compose.runtime.MutableState<T> kotlinx.coroutines.CoroutineScope {
-    method public suspend Object? awaitDispose(kotlin.jvm.functions.Function0<kotlin.Unit> onDispose, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? awaitDispose(kotlin.jvm.functions.Function0<kotlin.Unit> onDispose, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
   }
 
   @androidx.compose.runtime.Stable public abstract class ProvidableCompositionLocal<T> extends androidx.compose.runtime.CompositionLocal<T> {
@@ -570,21 +570,21 @@
   }
 
   public final class SnapshotDoubleStateKt {
-    method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, double value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, double value);
   }
 
   public final class SnapshotIntStateKt {
-    method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, int value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, int value);
   }
 
   public final class SnapshotLongStateKt {
-    method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, long value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, long value);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface SnapshotMutationPolicy<T> {
@@ -604,7 +604,7 @@
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
-    method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T... elements);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
@@ -620,7 +620,7 @@
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> producer);
     method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> referentialEqualityPolicy();
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T newValue);
-    method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, T value);
+    method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, T value);
     method public static <T> kotlinx.coroutines.flow.Flow<T> snapshotFlow(kotlin.jvm.functions.Function0<? extends T> block);
     method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> structuralEqualityPolicy();
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> toMutableStateList(java.util.Collection<? extends T>);
@@ -817,17 +817,17 @@
   public final class ComposableMethod {
     method public java.lang.reflect.Method asMethod();
     method public int getParameterCount();
-    method public Class<? extends java.lang.Object!>[] getParameterTypes();
+    method public Class<? extends java.lang.Object?>[] getParameterTypes();
     method public java.lang.reflect.Parameter[] getParameters();
     method public operator Object? invoke(androidx.compose.runtime.Composer composer, Object? instance, java.lang.Object?... args);
     property public final int parameterCount;
-    property public final Class<? extends java.lang.Object!>[] parameterTypes;
+    property public final Class<? extends java.lang.Object?>[] parameterTypes;
     property public final java.lang.reflect.Parameter[] parameters;
   }
 
   public final class ComposableMethodKt {
     method public static androidx.compose.runtime.reflect.ComposableMethod? asComposableMethod(java.lang.reflect.Method);
-    method @kotlin.jvm.Throws(exceptionClasses=NoSuchMethodException::class) public static androidx.compose.runtime.reflect.ComposableMethod getDeclaredComposableMethod(Class<? extends java.lang.Object!>, String methodName, Class<? extends java.lang.Object!>... args) throws java.lang.NoSuchMethodException;
+    method @kotlin.jvm.Throws(exceptionClasses=NoSuchMethodException::class) public static androidx.compose.runtime.reflect.ComposableMethod getDeclaredComposableMethod(Class<? extends java.lang.Object?>, String methodName, Class<? extends java.lang.Object?>... args) throws java.lang.NoSuchMethodException;
   }
 
 }
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index 5be67b2..914f839 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -137,7 +137,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.ScopeUpdateScope? endRestartGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endReusableGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endToMarker(int marker);
-    method public androidx.compose.runtime.Applier<? extends java.lang.Object!> getApplier();
+    method public androidx.compose.runtime.Applier<? extends java.lang.Object?> getApplier();
     method @org.jetbrains.annotations.TestOnly public kotlin.coroutines.CoroutineContext getApplyCoroutineContext();
     method @org.jetbrains.annotations.TestOnly public androidx.compose.runtime.ControlledComposition getComposition();
     method public androidx.compose.runtime.tooling.CompositionData getCompositionData();
@@ -149,7 +149,7 @@
     method public androidx.compose.runtime.RecomposeScope? getRecomposeScope();
     method public Object? getRecomposeScopeIdentity();
     method public boolean getSkipping();
-    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(androidx.compose.runtime.MovableContent<? extends java.lang.Object!> value, Object? parameter);
+    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(androidx.compose.runtime.MovableContent<? extends java.lang.Object?> value, Object? parameter);
     method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void insertMovableContentReferences(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference?>> references);
     method @androidx.compose.runtime.ComposeCompilerApi public Object joinKey(Object? left, Object? right);
     method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void recordSideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
@@ -163,8 +163,8 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
     method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
-    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!> value);
-    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!>[] values);
+    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?> value);
+    method @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?>[] values);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
@@ -172,7 +172,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
     method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
     method @androidx.compose.runtime.ComposeCompilerApi public void useNode();
-    property public abstract androidx.compose.runtime.Applier<? extends java.lang.Object!> applier;
+    property public abstract androidx.compose.runtime.Applier<? extends java.lang.Object?> applier;
     property @SuppressCompatibility @androidx.compose.runtime.InternalComposeApi @org.jetbrains.annotations.TestOnly public abstract kotlin.coroutines.CoroutineContext applyCoroutineContext;
     property @org.jetbrains.annotations.TestOnly public abstract androidx.compose.runtime.ControlledComposition composition;
     property public abstract androidx.compose.runtime.tooling.CompositionData compositionData;
@@ -232,11 +232,11 @@
   }
 
   public final class CompositionKt {
-    method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent);
-    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
-    method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent);
-    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
-    method public static androidx.compose.runtime.ReusableComposition ReusableComposition(androidx.compose.runtime.Applier<? extends java.lang.Object!> applier, androidx.compose.runtime.CompositionContext parent);
+    method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method public static androidx.compose.runtime.ReusableComposition ReusableComposition(androidx.compose.runtime.Applier<? extends java.lang.Object?> applier, androidx.compose.runtime.CompositionContext parent);
     method @SuppressCompatibility @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
   }
 
@@ -254,8 +254,8 @@
 
   public final class CompositionLocalKt {
     method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.CompositionLocalContext context, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object!>[] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<? extends java.lang.Object?>[] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> compositionLocalOf(optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> defaultFactory);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> compositionLocalWithComputedDefaultOf(kotlin.jvm.functions.Function1<? super androidx.compose.runtime.CompositionLocalAccessorScope,? extends T> defaultComputation);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> staticCompositionLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
@@ -401,9 +401,9 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
-    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> getKey();
+    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> getKey();
     method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
-    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> key;
+    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> key;
     field public static final androidx.compose.runtime.MonotonicFrameClock.Key Key;
   }
 
@@ -495,13 +495,13 @@
   }
 
   public final class PrimitiveSnapshotStateKt {
-    method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, float value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, float value);
   }
 
   public interface ProduceStateScope<T> extends androidx.compose.runtime.MutableState<T> kotlinx.coroutines.CoroutineScope {
-    method public suspend Object? awaitDispose(kotlin.jvm.functions.Function0<kotlin.Unit> onDispose, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? awaitDispose(kotlin.jvm.functions.Function0<kotlin.Unit> onDispose, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
   }
 
   @androidx.compose.runtime.Stable public abstract class ProvidableCompositionLocal<T> extends androidx.compose.runtime.CompositionLocal<T> {
@@ -602,21 +602,21 @@
   }
 
   public final class SnapshotDoubleStateKt {
-    method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, double value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, double value);
   }
 
   public final class SnapshotIntStateKt {
-    method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, int value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, int value);
   }
 
   public final class SnapshotLongStateKt {
-    method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
-    method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, long value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, long value);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface SnapshotMutationPolicy<T> {
@@ -636,7 +636,7 @@
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
-    method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T... elements);
     method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
@@ -652,7 +652,7 @@
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> producer);
     method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> referentialEqualityPolicy();
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T newValue);
-    method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object!> property, T value);
+    method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<? extends java.lang.Object?> property, T value);
     method public static <T> kotlinx.coroutines.flow.Flow<T> snapshotFlow(kotlin.jvm.functions.Function0<? extends T> block);
     method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> structuralEqualityPolicy();
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> toMutableStateList(java.util.Collection<? extends T>);
@@ -852,17 +852,17 @@
   public final class ComposableMethod {
     method public java.lang.reflect.Method asMethod();
     method public int getParameterCount();
-    method public Class<? extends java.lang.Object!>[] getParameterTypes();
+    method public Class<? extends java.lang.Object?>[] getParameterTypes();
     method public java.lang.reflect.Parameter[] getParameters();
     method public operator Object? invoke(androidx.compose.runtime.Composer composer, Object? instance, java.lang.Object?... args);
     property public final int parameterCount;
-    property public final Class<? extends java.lang.Object!>[] parameterTypes;
+    property public final Class<? extends java.lang.Object?>[] parameterTypes;
     property public final java.lang.reflect.Parameter[] parameters;
   }
 
   public final class ComposableMethodKt {
     method public static androidx.compose.runtime.reflect.ComposableMethod? asComposableMethod(java.lang.reflect.Method);
-    method @kotlin.jvm.Throws(exceptionClasses=NoSuchMethodException::class) public static androidx.compose.runtime.reflect.ComposableMethod getDeclaredComposableMethod(Class<? extends java.lang.Object!>, String methodName, Class<? extends java.lang.Object!>... args) throws java.lang.NoSuchMethodException;
+    method @kotlin.jvm.Throws(exceptionClasses=NoSuchMethodException::class) public static androidx.compose.runtime.reflect.ComposableMethod getDeclaredComposableMethod(Class<? extends java.lang.Object?>, String methodName, Class<? extends java.lang.Object?>... args) throws java.lang.NoSuchMethodException;
   }
 
 }
diff --git a/compose/ui/ui-test/api/current.txt b/compose/ui/ui-test/api/current.txt
index 6769c1d..c3e17f2 100644
--- a/compose/ui/ui-test/api/current.txt
+++ b/compose/ui/ui-test/api/current.txt
@@ -83,6 +83,7 @@
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedWidth);
     method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public static androidx.compose.ui.unit.DpRect getBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static java.util.List<androidx.compose.ui.geometry.Rect> getPartialBoundsOfLinks(androidx.compose.ui.test.SemanticsNodeInteraction, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.LinkAnnotation>,java.lang.Boolean> predicate);
     method public static androidx.compose.ui.unit.DpRect getUnclippedBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
   }
 
diff --git a/compose/ui/ui-test/api/restricted_current.txt b/compose/ui/ui-test/api/restricted_current.txt
index 54dfd84..89133d3 100644
--- a/compose/ui/ui-test/api/restricted_current.txt
+++ b/compose/ui/ui-test/api/restricted_current.txt
@@ -83,6 +83,7 @@
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedWidth);
     method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public static androidx.compose.ui.unit.DpRect getBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static java.util.List<androidx.compose.ui.geometry.Rect> getPartialBoundsOfLinks(androidx.compose.ui.test.SemanticsNodeInteraction, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.LinkAnnotation>,java.lang.Boolean> predicate);
     method public static androidx.compose.ui.unit.DpRect getUnclippedBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
   }
 
diff --git a/compose/ui/ui-test/samples/src/main/java/androidx/compose/ui/test/samples/BoundsAssertionsSamples.kt b/compose/ui/ui-test/samples/src/main/java/androidx/compose/ui/test/samples/BoundsAssertionsSamples.kt
new file mode 100644
index 0000000..c1560d3
--- /dev/null
+++ b/compose/ui/ui-test/samples/src/main/java/androidx/compose/ui/test/samples/BoundsAssertionsSamples.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.test.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.MouseInjectionScope
+import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.click
+import androidx.compose.ui.test.getPartialBoundsOfLinks
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performMouseInput
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.text.LinkAnnotation
+
+@Sampled
+fun touchInputOnFirstSpecificLinkInText() {
+    // Example of clicking on a link
+    val firstLinkBounds =
+        composeTestRule
+            .onNodeWithText("YOUR_TEXT_WITH_LINK")
+            .getPartialBoundsOfLinks { (it.item as? LinkAnnotation.Url)?.url == "YOUR_URL" }
+            .first()
+
+    composeTestRule.onNodeWithText("YOUR_TEXT_WITH_LINK").performTouchInput {
+        click(firstLinkBounds.center)
+    }
+}
+
+@OptIn(ExperimentalTestApi::class)
+@Sampled
+fun hoverAnyFirstLinkInText() {
+    // Example of a convenience function to hover over the first link
+    fun SemanticsNodeInteraction.performMouseInputOnFirstLink(
+        block: MouseInjectionScope.(offsetInLink: Offset) -> Unit
+    ): SemanticsNodeInteraction {
+        val linkBounds = getPartialBoundsOfLinks().firstOrNull() ?: return this
+        return this.performMouseInput { block(linkBounds.center) }
+    }
+
+    composeTestRule.onNodeWithText("YOUR_TEXT_WITH_LINK").performMouseInputOnFirstLink {
+        moveTo(it)
+    }
+}
diff --git a/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt b/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt
index f033023..73c2666 100644
--- a/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt
+++ b/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt
@@ -19,11 +19,14 @@
 import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.absoluteOffset
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.testutils.WithMinimumTouchTargetSize
@@ -32,11 +35,14 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.HorizontalAlignmentLine
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.text
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.assertHeightIsAtLeast
 import androidx.compose.ui.test.assertHeightIsEqualTo
@@ -49,12 +55,20 @@
 import androidx.compose.ui.test.assertWidthIsEqualTo
 import androidx.compose.ui.test.getAlignmentLinePosition
 import androidx.compose.ui.test.getBoundsInRoot
+import androidx.compose.ui.test.getPartialBoundsOfLinks
 import androidx.compose.ui.test.getUnclippedBoundsInRoot
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.LinkAnnotation
+import androidx.compose.ui.text.TextLayoutResult
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.withLink
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -448,4 +462,139 @@
             ) {}
         }
     }
+
+    @Test
+    fun getBoundsWithinLink_multipleMatches() {
+        lateinit var textLayoutResult: TextLayoutResult
+        rule.setContent {
+            BasicText(
+                buildAnnotatedString {
+                    append("a")
+                    withLink(LinkAnnotation.Url("url1")) { append("link1") }
+                    withLink(LinkAnnotation.Url("url2")) { append("link2") }
+                    withLink(LinkAnnotation.Clickable("tag1") {}) { append("link3") }
+                },
+                onTextLayout = { textLayoutResult = it },
+            )
+        }
+
+        val textNode = rule.onNodeWithText("a", substring = true)
+        assertThat(textNode.getPartialBoundsOfLinks { true })
+            .containsExactly(
+                textLayoutResult.getBoundingBox(1),
+                textLayoutResult.getBoundingBox(6),
+                textLayoutResult.getBoundingBox(11)
+            )
+    }
+
+    @Test
+    fun getBoundsWithinLink_forSpecificUrl_multipleMatches() {
+        lateinit var textLayoutResult: TextLayoutResult
+        rule.setContent {
+            BasicText(
+                buildAnnotatedString {
+                    append("a")
+                    withLink(LinkAnnotation.Url("url1")) { append("link1") }
+                    withLink(LinkAnnotation.Url("url2")) { append("link2") }
+                    withLink(LinkAnnotation.Url("url1") {}) { append("link3") }
+                    withLink(LinkAnnotation.Clickable("tag2") {}) { append("link4") }
+                },
+                onTextLayout = { textLayoutResult = it },
+            )
+        }
+
+        val textNode = rule.onNodeWithText("a", substring = true)
+        assertThat(
+                textNode.getPartialBoundsOfLinks { (it.item as? LinkAnnotation.Url)?.url == "url1" }
+            )
+            .containsExactly(
+                textLayoutResult.getBoundingBox(1),
+                textLayoutResult.getBoundingBox(11)
+            )
+    }
+
+    @Test
+    fun getBoundsWithinLink_forAllClickable_multipleMatches() {
+        lateinit var textLayoutResult: TextLayoutResult
+        rule.setContent {
+            BasicText(
+                buildAnnotatedString {
+                    append("a")
+                    withLink(LinkAnnotation.Clickable("tag1") {}) { append("link1") }
+                    withLink(LinkAnnotation.Url("url2")) { append("link2") }
+                    withLink(LinkAnnotation.Clickable("tag2") {}) { append("link3") }
+                },
+                onTextLayout = { textLayoutResult = it },
+            )
+        }
+
+        val textNode = rule.onNodeWithText("a", substring = true)
+        assertThat(textNode.getPartialBoundsOfLinks { it.item is LinkAnnotation.Clickable })
+            .containsExactly(
+                textLayoutResult.getBoundingBox(1),
+                textLayoutResult.getBoundingBox(11)
+            )
+    }
+
+    fun getBoundsWithinLink_ZeroMatches() {
+        rule.setContent { BasicText(AnnotatedString("a")) }
+        assertThat(rule.onNodeWithText("a").getPartialBoundsOfLinks { true })
+            .isEqualTo(emptyList<Rect>())
+    }
+
+    fun getBoundsWithinLink_explicitZeroMatches() {
+        rule.setContent {
+            BasicText(buildAnnotatedString { withLink(LinkAnnotation.Url("url")) { append("a") } })
+        }
+        assertThat(rule.onNodeWithText("abc").getPartialBoundsOfLinks { false })
+            .isEqualTo(emptyList<Rect>())
+    }
+
+    @Test
+    fun getBoundsWithinLink_relativeToTextNode() {
+        lateinit var textLayoutResult: TextLayoutResult
+        val offset = IntOffset(17, 17)
+        rule.setContent {
+            BasicText(
+                buildAnnotatedString { withLink(LinkAnnotation.Url("url")) { append("link") } },
+                onTextLayout = { textLayoutResult = it },
+                modifier = Modifier.absoluteOffset { offset }
+            )
+        }
+
+        val textNode = rule.onNodeWithText("link")
+        assertThat(textNode.getPartialBoundsOfLinks { true }.first())
+            .isEqualTo(textLayoutResult.getBoundingBox(0))
+    }
+
+    @Test(expected = AssertionError::class)
+    fun getBoundsWithinLink_expectMatchingTextForTextLayoutResult() {
+        val TAG = "text node"
+        rule.setContent {
+            BasicText(
+                buildAnnotatedString { withLink(LinkAnnotation.Url("url")) { append("link") } },
+                modifier = Modifier.testTag(TAG).semantics { text = AnnotatedString("other text") }
+            )
+        }
+        rule.onNodeWithTag(TAG).getPartialBoundsOfLinks { true }
+    }
+
+    @Test
+    fun getBoundsWithinLink_mergedNode_expectMatchingTextForTextLayoutResult() {
+        lateinit var textLayoutResult: TextLayoutResult
+        val TAG = "box node"
+        rule.setContent {
+            Box(Modifier.semantics(true) {}.testTag(TAG)) {
+                Box(Modifier.size(10.dp).semantics { text = AnnotatedString("no link text") })
+                BasicText(
+                    buildAnnotatedString { withLink(LinkAnnotation.Url("url")) { append("link") } },
+                    onTextLayout = { textLayoutResult = it }
+                )
+            }
+        }
+
+        val textNode = rule.onNodeWithTag(TAG)
+        assertThat(textNode.getPartialBoundsOfLinks { true }.first())
+            .isEqualTo(textLayoutResult.getBoundingBox(0))
+    }
 }
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt
index 8efa945..3799a98 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt
@@ -18,7 +18,13 @@
 
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.layout.AlignmentLine
+import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.semantics.SemanticsNode
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.semantics.getOrNull
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.LinkAnnotation
+import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpRect
@@ -26,6 +32,7 @@
 import androidx.compose.ui.unit.isUnspecified
 import androidx.compose.ui.unit.toSize
 import androidx.compose.ui.unit.width
+import androidx.compose.ui.util.fastMap
 import kotlin.math.abs
 
 /**
@@ -171,6 +178,57 @@
     }
 }
 
+/**
+ * For every link matching the [predicate] returns a rectangle that is inside the bounds of this
+ * link. The bounds are in the text node's coordinate system.
+ *
+ * **Note** Each such bounds will be inside the overall link bounds but may not represent its entire
+ * bounds.
+ *
+ * You may pass an offset within the rectangle to injection methods to operate them on the link, for
+ * example [TouchInjectionScope.click] or [MouseInjectionScope.moveTo].
+ *
+ * @sample androidx.compose.ui.test.samples.touchInputOnFirstSpecificLinkInText
+ *
+ * @sample androidx.compose.ui.test.samples.hoverAnyFirstLinkInText
+ */
+fun SemanticsNodeInteraction.getPartialBoundsOfLinks(
+    predicate: (AnnotatedString.Range<LinkAnnotation>) -> Boolean = { true }
+): List<Rect> = withDensity {
+    val errorMessage = "Failed to retrieve bounds of the link."
+    val node = fetchSemanticsNode(errorMessage)
+
+    val texts = node.config.getOrNull(SemanticsProperties.Text)
+    if (texts.isNullOrEmpty())
+        throw AssertionError("$errorMessage\n Reason: No text found on node.")
+
+    if (!(node.config.contains(SemanticsActions.GetTextLayoutResult)))
+        throw AssertionError(
+            "$errorMessage\n Reason: Node doesn't have GetTextLayoutResult action."
+        )
+    // This will contain only one element almost always. The only time when it could have more than
+    // one is if a developer overrides the getTextLayoutResult semantics and adds multiple elements
+    // into the list.
+    val textLayoutResults = mutableListOf<TextLayoutResult>()
+    node.config[SemanticsActions.GetTextLayoutResult].action?.invoke(textLayoutResults)
+
+    val matchedTextLayoutResults = textLayoutResults.filter { texts.contains(it.layoutInput.text) }
+    if (matchedTextLayoutResults.isEmpty()) {
+        throw AssertionError(
+            "$errorMessage\n Reason: No matching TextLayoutResult found for the node's text."
+        )
+    }
+
+    val allBoundsOfLinks = mutableListOf<Rect>()
+    for (textLayoutResult in matchedTextLayoutResults) {
+        val text = textLayoutResult.layoutInput.text
+        val links = text.getLinkAnnotations(0, text.length).filter(predicate)
+        val boundsOfLinks = links.fastMap { textLayoutResult.getBoundingBox(it.start) }
+        allBoundsOfLinks.addAll(boundsOfLinks)
+    }
+    return@withDensity allBoundsOfLinks
+}
+
 private fun <R> SemanticsNodeInteraction.withDensity(operation: Density.(SemanticsNode) -> R): R {
     val node = fetchSemanticsNode("Failed to retrieve density for the node.")
     val density = node.layoutInfo.density
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index fa07a86..58f340d 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -63,8 +63,8 @@
   }
 
   public static final class AnnotatedString.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index 8214d9c..081cd6f 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -63,8 +63,8 @@
   }
 
   public static final class AnnotatedString.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.AnnotatedString,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
diff --git a/compose/ui/ui-tooling-preview/api/current.txt b/compose/ui/ui-tooling-preview/api/current.txt
index 8a61e39..c545ecb 100644
--- a/compose/ui/ui-tooling-preview/api/current.txt
+++ b/compose/ui/ui-tooling-preview/api/current.txt
@@ -98,9 +98,9 @@
 
   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface PreviewParameter {
     method public abstract int limit() default kotlin.jvm.internal.IntCompanionObject.MAX_VALUE;
-    method public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object!>> provider();
+    method public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object?>> provider();
     property public abstract int limit;
-    property public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object!>> provider;
+    property public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object?>> provider;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface PreviewParameterProvider<T> {
diff --git a/compose/ui/ui-tooling-preview/api/restricted_current.txt b/compose/ui/ui-tooling-preview/api/restricted_current.txt
index 8a61e39..c545ecb 100644
--- a/compose/ui/ui-tooling-preview/api/restricted_current.txt
+++ b/compose/ui/ui-tooling-preview/api/restricted_current.txt
@@ -98,9 +98,9 @@
 
   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface PreviewParameter {
     method public abstract int limit() default kotlin.jvm.internal.IntCompanionObject.MAX_VALUE;
-    method public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object!>> provider();
+    method public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object?>> provider();
     property public abstract int limit;
-    property public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object!>> provider;
+    property public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<? extends java.lang.Object?>> provider;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface PreviewParameterProvider<T> {
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index 1b75413..91b59dd 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -176,9 +176,9 @@
   }
 
   @androidx.compose.runtime.Stable public interface MotionDurationScale extends kotlin.coroutines.CoroutineContext.Element {
-    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> getKey();
+    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> getKey();
     method public float getScaleFactor();
-    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> key;
+    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> key;
     property public abstract float scaleFactor;
     field public static final androidx.compose.ui.MotionDurationScale.Key Key;
   }
@@ -2553,11 +2553,11 @@
 
   public final class ModifierLocalModifierNodeKt {
     method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf();
-    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!> key1, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!> key2, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>... keys);
-    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>... keys);
+    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?> key1, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?> key2, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>... keys);
+    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>... keys);
     method public static <T> androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<T> key);
-    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?> entry1, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?> entry2, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?>... entries);
-    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?>... entries);
+    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?> entry1, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?> entry2, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?>... entries);
+    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?>... entries);
     method public static <T> androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<T>,? extends T> entry);
   }
 
@@ -2889,6 +2889,7 @@
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill?> getLocalAutofill();
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalCursorBlinkEnabled();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> getLocalDensity();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> getLocalFocusManager();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.font.FontFamily.Resolver> getLocalFontFamilyResolver();
@@ -2907,6 +2908,7 @@
     property @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill?> LocalAutofill;
     property @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> LocalAutofillTree;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> LocalClipboardManager;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalCursorBlinkEnabled;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> LocalDensity;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> LocalFocusManager;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.font.FontFamily.Resolver> LocalFontFamilyResolver;
@@ -2924,9 +2926,9 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface InfiniteAnimationPolicy extends kotlin.coroutines.CoroutineContext.Element {
-    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> getKey();
+    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> getKey();
     method public suspend <R> Object? onInfiniteOperation(kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? super R>);
-    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> key;
+    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> key;
     field public static final androidx.compose.ui.platform.InfiniteAnimationPolicy.Key Key;
   }
 
@@ -2991,7 +2993,7 @@
   }
 
   @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public fun interface PlatformTextInputInterceptor {
-    method public suspend Object? interceptStartInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, androidx.compose.ui.platform.PlatformTextInputSession nextHandler, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? interceptStartInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, androidx.compose.ui.platform.PlatformTextInputSession nextHandler, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
   }
 
   public fun interface PlatformTextInputMethodRequest {
@@ -3003,12 +3005,12 @@
 
   public final class PlatformTextInputModifierNodeKt {
     method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi public static void InterceptPlatformTextInput(androidx.compose.ui.platform.PlatformTextInputInterceptor interceptor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method public static suspend Object? establishTextInputSession(androidx.compose.ui.platform.PlatformTextInputModifierNode, kotlin.jvm.functions.Function2<? super androidx.compose.ui.platform.PlatformTextInputSessionScope,? super kotlin.coroutines.Continuation<? extends java.lang.Object!>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public static suspend Object? establishTextInputSession(androidx.compose.ui.platform.PlatformTextInputModifierNode, kotlin.jvm.functions.Function2<? super androidx.compose.ui.platform.PlatformTextInputSessionScope,? super kotlin.coroutines.Continuation<? extends java.lang.Object?>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
   }
 
   public interface PlatformTextInputSession {
     method public android.view.View getView();
-    method public suspend Object? startInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? startInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     property public abstract android.view.View view;
   }
 
@@ -3364,7 +3366,7 @@
     field public static final androidx.compose.ui.semantics.SemanticsActions INSTANCE;
   }
 
-  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object!>,? extends java.lang.Object?>> kotlin.jvm.internal.markers.KMappedMarker androidx.compose.ui.semantics.SemanticsPropertyReceiver {
+  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object?>,? extends java.lang.Object?>> kotlin.jvm.internal.markers.KMappedMarker androidx.compose.ui.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
     method public operator <T> boolean contains(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
     method public androidx.compose.ui.semantics.SemanticsConfiguration copy();
@@ -3373,7 +3375,7 @@
     method public <T> T? getOrElseNullable(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T?> defaultValue);
     method public boolean isClearingSemantics();
     method public boolean isMergingSemanticsOfDescendants();
-    method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object!>,java.lang.Object?>> iterator();
+    method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object?>,java.lang.Object?>> iterator();
     method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
     method public void setClearingSemantics(boolean);
     method public void setMergingSemanticsOfDescendants(boolean);
@@ -3620,9 +3622,9 @@
   public final class SemanticsPropertyKey<T> {
     ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T?,? super T,? extends T?> mergePolicy);
     method public String getName();
-    method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method public T? merge(T? parentValue, T childValue);
-    method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object!> property, T value);
+    method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object?> property, T value);
     property public final String name;
   }
 
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 9ab5ea2..af60fc9 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -176,9 +176,9 @@
   }
 
   @androidx.compose.runtime.Stable public interface MotionDurationScale extends kotlin.coroutines.CoroutineContext.Element {
-    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> getKey();
+    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> getKey();
     method public float getScaleFactor();
-    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> key;
+    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> key;
     property public abstract float scaleFactor;
     field public static final androidx.compose.ui.MotionDurationScale.Key Key;
   }
@@ -2560,11 +2560,11 @@
 
   public final class ModifierLocalModifierNodeKt {
     method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf();
-    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!> key1, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!> key2, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>... keys);
-    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>... keys);
+    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?> key1, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?> key2, androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>... keys);
+    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>... keys);
     method public static <T> androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<T> key);
-    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?> entry1, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?> entry2, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?>... entries);
-    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object!>,?>... entries);
+    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?> entry1, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?> entry2, kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?>... entries);
+    method @Deprecated public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<? extends java.lang.Object?>,?>... entries);
     method public static <T> androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<T>,? extends T> entry);
   }
 
@@ -2942,6 +2942,7 @@
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill?> getLocalAutofill();
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalCursorBlinkEnabled();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> getLocalDensity();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> getLocalFocusManager();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.font.FontFamily.Resolver> getLocalFontFamilyResolver();
@@ -2960,6 +2961,7 @@
     property @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill?> LocalAutofill;
     property @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> LocalAutofillTree;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> LocalClipboardManager;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalCursorBlinkEnabled;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> LocalDensity;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> LocalFocusManager;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.font.FontFamily.Resolver> LocalFontFamilyResolver;
@@ -2977,9 +2979,9 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface InfiniteAnimationPolicy extends kotlin.coroutines.CoroutineContext.Element {
-    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> getKey();
+    method public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> getKey();
     method public suspend <R> Object? onInfiniteOperation(kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? super R>);
-    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object!> key;
+    property public default kotlin.coroutines.CoroutineContext.Key<? extends java.lang.Object?> key;
     field public static final androidx.compose.ui.platform.InfiniteAnimationPolicy.Key Key;
   }
 
@@ -3049,7 +3051,7 @@
   }
 
   @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public fun interface PlatformTextInputInterceptor {
-    method public suspend Object? interceptStartInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, androidx.compose.ui.platform.PlatformTextInputSession nextHandler, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? interceptStartInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, androidx.compose.ui.platform.PlatformTextInputSession nextHandler, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
   }
 
   public fun interface PlatformTextInputMethodRequest {
@@ -3061,12 +3063,12 @@
 
   public final class PlatformTextInputModifierNodeKt {
     method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi public static void InterceptPlatformTextInput(androidx.compose.ui.platform.PlatformTextInputInterceptor interceptor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method public static suspend Object? establishTextInputSession(androidx.compose.ui.platform.PlatformTextInputModifierNode, kotlin.jvm.functions.Function2<? super androidx.compose.ui.platform.PlatformTextInputSessionScope,? super kotlin.coroutines.Continuation<? extends java.lang.Object!>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public static suspend Object? establishTextInputSession(androidx.compose.ui.platform.PlatformTextInputModifierNode, kotlin.jvm.functions.Function2<? super androidx.compose.ui.platform.PlatformTextInputSessionScope,? super kotlin.coroutines.Continuation<? extends java.lang.Object?>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
   }
 
   public interface PlatformTextInputSession {
     method public android.view.View getView();
-    method public suspend Object? startInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? startInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest request, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     property public abstract android.view.View view;
   }
 
@@ -3424,7 +3426,7 @@
     field public static final androidx.compose.ui.semantics.SemanticsActions INSTANCE;
   }
 
-  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object!>,? extends java.lang.Object?>> kotlin.jvm.internal.markers.KMappedMarker androidx.compose.ui.semantics.SemanticsPropertyReceiver {
+  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object?>,? extends java.lang.Object?>> kotlin.jvm.internal.markers.KMappedMarker androidx.compose.ui.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
     method public operator <T> boolean contains(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
     method public androidx.compose.ui.semantics.SemanticsConfiguration copy();
@@ -3433,7 +3435,7 @@
     method public <T> T? getOrElseNullable(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T?> defaultValue);
     method public boolean isClearingSemantics();
     method public boolean isMergingSemanticsOfDescendants();
-    method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object!>,java.lang.Object?>> iterator();
+    method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<? extends java.lang.Object?>,java.lang.Object?>> iterator();
     method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
     method public void setClearingSemantics(boolean);
     method public void setMergingSemanticsOfDescendants(boolean);
@@ -3680,9 +3682,9 @@
   public final class SemanticsPropertyKey<T> {
     ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T?,? super T,? extends T?> mergePolicy);
     method public String getName();
-    method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object!> property);
+    method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object?> property);
     method public T? merge(T? parentValue, T childValue);
-    method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object!> property, T value);
+    method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<? extends java.lang.Object?> property, T value);
     property public final String name;
   }
 
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 248201f..7659997 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -94,7 +94,7 @@
                 implementation('androidx.collection:collection:1.0.0')
                 implementation("androidx.customview:customview-poolingcontainer:1.0.0")
                 implementation("androidx.savedstate:savedstate-ktx:1.2.1")
-                api("androidx.lifecycle:lifecycle-runtime-compose:2.8.0")
+                api("androidx.lifecycle:lifecycle-runtime-compose:2.8.2")
                 implementation("androidx.lifecycle:lifecycle-viewmodel:2.6.1")
                 implementation("androidx.emoji2:emoji2:1.2.0")
 
@@ -104,13 +104,13 @@
                 // converting `lifecycle-runtime-compose` to KMP triggered a Gradle bug. Adding
                 // the `livedata` dependency directly works around the issue.
                 // See https://github.com/gradle/gradle/issues/14220 for details.
-                compileOnly("androidx.lifecycle:lifecycle-livedata-core:2.8.0")
+                compileOnly("androidx.lifecycle:lifecycle-livedata-core:2.8.2")
 
                 // `compose-ui` has a transitive dependency on `lifecycle-viewmodel-savedstate`, and
                 // converting `lifecycle-runtime-compose` to KMP triggered a Gradle bug. Adding
                 // the `lifecycle-viewmodel-savedstate` dependency directly works around the issue.
                 // See https://github.com/gradle/gradle/issues/14220 for details.
-                compileOnly("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.0")
+                compileOnly("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.2")
             }
         }
 
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAssistTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAssistTest.kt
new file mode 100644
index 0000000..2d08cc5
--- /dev/null
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAssistTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui
+
+import android.view.ViewStructure
+import androidx.compose.foundation.layout.Box
+import androidx.compose.ui.autofill.FakeViewStructure
+import androidx.compose.ui.platform.AndroidComposeView
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.TestActivity
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class AndroidAssistTest {
+    @get:Rule val rule = createAndroidComposeRule<TestActivity>()
+    private lateinit var androidComposeView: AndroidComposeView
+
+    private val contentTag = "content_tag"
+    private val accessibilityClassName = "android.view.ViewGroup"
+
+    // Test that the assistStructure only has its classname set on API levels 26 and 27. See
+    // b/251152083 for more information.
+    @Test
+    @SmallTest
+    @SdkSuppress(minSdkVersion = 26, maxSdkVersion = 27)
+    fun verifyAssistStructureSet() {
+        val viewStructure: ViewStructure = FakeViewStructure()
+
+        rule.setContent {
+            androidComposeView = LocalView.current as AndroidComposeView
+            Box(Modifier.testTag(contentTag))
+        }
+
+        rule.runOnIdle { androidComposeView.dispatchProvideStructure(viewStructure) }
+
+        // Use FakeViewStructure here in order to test the accessibility class name is set properly.
+        Truth.assertThat(viewStructure)
+            .isEqualTo(FakeViewStructure().apply { setClassName(accessibilityClassName) })
+    }
+}
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
index 5955e2d..7583b05 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
@@ -561,6 +561,49 @@
     }
 
     @Test
+    fun textNode_withRoleButton_className_button() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier.size(10.dp).semantics(mergeDescendants = true) {
+                    testTag = tag
+                    text = AnnotatedString("text") // makes it a text node
+                    role = Role.Button
+                }
+            )
+        }
+        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
+
+        // Act.
+        val info = rule.runOnIdle { androidComposeView.createAccessibilityNodeInfo(virtualViewId) }
+
+        // Assert.
+        rule.runOnIdle { assertThat(info.className).isEqualTo("android.widget.Button") }
+    }
+
+    @Test
+    fun textFieldNode_withRoleButton_className_button() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier.size(10.dp).semantics(mergeDescendants = true) {
+                    testTag = tag
+                    editableText = AnnotatedString("")
+                    setText { true } // makes it a text field node
+                    role = Role.Button
+                }
+            )
+        }
+        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
+
+        // Act.
+        val info = rule.runOnIdle { androidComposeView.createAccessibilityNodeInfo(virtualViewId) }
+
+        // Assert.
+        rule.runOnIdle { assertThat(info.className).isEqualTo("android.widget.Button") }
+    }
+
+    @Test
     fun nodeWithTextAndLayoutResult_className_textView() {
         // Arrange.
         rule.setContentWithAccessibilityEnabled {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index c8131ed..8a3000f3 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -825,7 +825,7 @@
      */
     override fun dispatchProvideStructure(structure: ViewStructure) {
         if (SDK_INT == 26 || SDK_INT == 27) {
-            AndroidComposeViewAssistHelperMethodsO.setClassName(structure)
+            AndroidComposeViewAssistHelperMethodsO.setClassName(structure, view)
         } else {
             super.dispatchProvideStructure(structure)
         }
@@ -2497,8 +2497,8 @@
 private object AndroidComposeViewAssistHelperMethodsO {
     @RequiresApi(M)
     @DoNotInline
-    fun setClassName(structure: ViewStructure) {
-        structure.setClassName(javaClass.name)
+    fun setClassName(structure: ViewStructure, view: View) {
+        structure.setClassName(view.accessibilityClassName.toString())
     }
 }
 
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
index 55a7819..4e24591 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
@@ -764,6 +764,15 @@
     ) {
         // set classname
         info.className = ClassName
+
+        // Set a classname for text nodes before setting a classname based on a role ensuring that
+        // the latter if present wins (see b/343392125)
+        if (semanticsNode.unmergedConfig.contains(SemanticsActions.SetText)) {
+            info.className = TextFieldClassName
+        }
+        if (semanticsNode.unmergedConfig.contains(SemanticsProperties.Text)) {
+            info.className = TextClassName
+        }
         val role = semanticsNode.unmergedConfig.getOrNull(SemanticsProperties.Role)
         role?.let {
             if (semanticsNode.isFake || semanticsNode.replacedChildren.isEmpty()) {
@@ -785,12 +794,6 @@
                 }
             }
         }
-        if (semanticsNode.unmergedConfig.contains(SemanticsActions.SetText)) {
-            info.className = TextFieldClassName
-        }
-        if (semanticsNode.unmergedConfig.contains(SemanticsProperties.Text)) {
-            info.className = TextClassName
-        }
 
         info.packageName = view.context.packageName
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt
index cf81520..3b31826 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt
@@ -22,6 +22,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocal
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.ProvidableCompositionLocal
 import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.runtime.staticCompositionLocalOf
 import androidx.compose.ui.ExperimentalComposeUiApi
@@ -164,6 +165,9 @@
 val LocalScrollCaptureInProgress: CompositionLocal<Boolean>
     get() = LocalProvidableScrollCaptureInProgress
 
+/** Configure the blink timeout, after interaction, for text cursors. */
+val LocalCursorBlinkEnabled: ProvidableCompositionLocal<Boolean> = staticCompositionLocalOf { true }
+
 @ExperimentalComposeUiApi
 @Composable
 internal fun ProvideCommonCompositionLocals(
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
index 0f57306..aed78ea 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
@@ -820,8 +820,9 @@
 var SemanticsPropertyReceiver.isContainer by SemanticsProperties.IsTraversalGroup
 
 /**
- * Whether this semantics node is a traversal group. This is defined as a node whose function is to
- * serve as a boundary or border in organizing its children.
+ * Whether this semantics node is a traversal group.
+ *
+ * See https://developer.android.com/jetpack/compose/accessibility#modify-traversal-order
  *
  * @see SemanticsProperties.IsTraversalGroup
  */
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallServiceCompatTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallServiceCompatTest.kt
index c42ace6..99122a0 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallServiceCompatTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallServiceCompatTest.kt
@@ -41,7 +41,6 @@
 import org.junit.After
 import org.junit.Assert
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -98,7 +97,6 @@
      */
     @LargeTest
     @Test(timeout = 10000)
-    @Ignore //  b/343742088
     fun testResolveCallExtension_Extra() {
         setUpBackwardsCompatTest()
         val voipApiExtra = Pair(CallsManager.EXTRA_VOIP_API_VERSION, true)
@@ -124,7 +122,6 @@
      */
     @LargeTest
     @Test(timeout = 10000)
-    @Ignore //  b/343742088
     fun testResolveCallExtension_CapabilityExchange() {
         // Add EXTRA_VOIP_BACKWARDS_COMPATIBILITY_SUPPORTED for pre-U testing
         val backwardsCompatExtra = configureCapabilityExchangeTypeTest()
@@ -132,7 +129,7 @@
             TestUtils.OUTGOING_CALL_ATTRIBUTES,
             InCallServiceCompat.CAPABILITY_EXCHANGE,
             // Waiting is not required for U+ testing
-            waitForCallDetailExtras = !TestUtils.buildIsAtLeastU(),
+            waitForCallDetailExtras = !Utils.hasPlatformV2Apis(),
             extraToInclude = backwardsCompatExtra,
         )
     }
@@ -156,7 +153,6 @@
      */
     @LargeTest
     @Test(timeout = 10000)
-    @Ignore //  b/343742088
     fun testResolveCallExtension_TransactionalOpsNotSupported() {
         // Phone accounts that don't use the v2 APIs don't support transactional ops.
         setUpBackwardsCompatTest()
@@ -227,7 +223,7 @@
     }
 
     private fun configureCapabilityExchangeTypeTest(): Pair<String, Boolean>? {
-        if (TestUtils.buildIsAtLeastU()) {
+        if (Utils.hasPlatformV2Apis()) {
             Log.w(CallCompatTest.TAG, "Setting up v2 tests for U+ device")
             setUpV2TestWithExtensions()
         } else {
@@ -236,7 +232,7 @@
         }
 
         // Add EXTRA_VOIP_BACKWARDS_COMPATIBILITY_SUPPORTED for pre-U testing
-        return if (!TestUtils.buildIsAtLeastU())
+        return if (!Utils.hasPlatformV2Apis())
             Pair(CallsManager.EXTRA_VOIP_BACKWARDS_COMPATIBILITY_SUPPORTED, true)
         else null
     }
diff --git a/datastore/datastore-preferences-core/api/current.txt b/datastore/datastore-preferences-core/api/current.txt
index c09b4e58..1de9eb3 100644
--- a/datastore/datastore-preferences-core/api/current.txt
+++ b/datastore/datastore-preferences-core/api/current.txt
@@ -2,14 +2,14 @@
 package androidx.datastore.preferences.core {
 
   public final class MutablePreferences extends androidx.datastore.preferences.core.Preferences {
-    method public java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object!>,java.lang.Object> asMap();
+    method public java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object?>,java.lang.Object> asMap();
     method public void clear();
     method public operator <T> boolean contains(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public operator <T> T? get(androidx.datastore.preferences.core.Preferences.Key<T> key);
-    method public operator void minusAssign(androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object!> key);
+    method public operator void minusAssign(androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object?> key);
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
-    method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!> pair);
-    method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!>... pairs);
+    method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?> pair);
+    method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?>... pairs);
     method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
   }
@@ -25,7 +25,7 @@
   }
 
   public abstract class Preferences {
-    method public abstract java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object!>,java.lang.Object> asMap();
+    method public abstract java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object?>,java.lang.Object> asMap();
     method public abstract operator <T> boolean contains(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public abstract operator <T> T? get(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public final androidx.datastore.preferences.core.MutablePreferences toMutablePreferences();
@@ -42,9 +42,9 @@
   }
 
   public final class PreferencesFactory {
-    method public static androidx.datastore.preferences.core.Preferences create(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!>... pairs);
+    method public static androidx.datastore.preferences.core.Preferences create(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?>... pairs);
     method public static androidx.datastore.preferences.core.Preferences createEmpty();
-    method public static androidx.datastore.preferences.core.MutablePreferences createMutable(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!>... pairs);
+    method public static androidx.datastore.preferences.core.MutablePreferences createMutable(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?>... pairs);
   }
 
   public final class PreferencesKeys {
diff --git a/datastore/datastore-preferences-core/api/restricted_current.txt b/datastore/datastore-preferences-core/api/restricted_current.txt
index c09b4e58..1de9eb3 100644
--- a/datastore/datastore-preferences-core/api/restricted_current.txt
+++ b/datastore/datastore-preferences-core/api/restricted_current.txt
@@ -2,14 +2,14 @@
 package androidx.datastore.preferences.core {
 
   public final class MutablePreferences extends androidx.datastore.preferences.core.Preferences {
-    method public java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object!>,java.lang.Object> asMap();
+    method public java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object?>,java.lang.Object> asMap();
     method public void clear();
     method public operator <T> boolean contains(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public operator <T> T? get(androidx.datastore.preferences.core.Preferences.Key<T> key);
-    method public operator void minusAssign(androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object!> key);
+    method public operator void minusAssign(androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object?> key);
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
-    method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!> pair);
-    method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!>... pairs);
+    method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?> pair);
+    method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?>... pairs);
     method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
   }
@@ -25,7 +25,7 @@
   }
 
   public abstract class Preferences {
-    method public abstract java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object!>,java.lang.Object> asMap();
+    method public abstract java.util.Map<androidx.datastore.preferences.core.Preferences.Key<? extends java.lang.Object?>,java.lang.Object> asMap();
     method public abstract operator <T> boolean contains(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public abstract operator <T> T? get(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public final androidx.datastore.preferences.core.MutablePreferences toMutablePreferences();
@@ -42,9 +42,9 @@
   }
 
   public final class PreferencesFactory {
-    method public static androidx.datastore.preferences.core.Preferences create(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!>... pairs);
+    method public static androidx.datastore.preferences.core.Preferences create(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?>... pairs);
     method public static androidx.datastore.preferences.core.Preferences createEmpty();
-    method public static androidx.datastore.preferences.core.MutablePreferences createMutable(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object!>... pairs);
+    method public static androidx.datastore.preferences.core.MutablePreferences createMutable(androidx.datastore.preferences.core.Preferences.Pair<? extends java.lang.Object?>... pairs);
   }
 
   public final class PreferencesKeys {
diff --git a/glance/glance-appwidget/api/current.txt b/glance/glance-appwidget/api/current.txt
index c1e33ae..1f04a7b 100644
--- a/glance/glance-appwidget/api/current.txt
+++ b/glance/glance-appwidget/api/current.txt
@@ -55,17 +55,17 @@
   public abstract class GlanceAppWidget {
     ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
     method public androidx.glance.appwidget.SizeMode getSizeMode();
-    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? getStateDefinition();
+    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? getStateDefinition();
     method @kotlin.jvm.Throws(exceptionClasses=Throwable::class) public void onCompositionError(android.content.Context context, androidx.glance.GlanceId glanceId, int appWidgetId, Throwable throwable) throws java.lang.Throwable;
     method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     property public androidx.glance.appwidget.SizeMode sizeMode;
-    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? stateDefinition;
+    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? stateDefinition;
   }
 
   public final class GlanceAppWidgetKt {
-    method public static suspend Object? provideContent(androidx.glance.appwidget.GlanceAppWidget, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public static suspend Object? provideContent(androidx.glance.appwidget.GlanceAppWidget, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     method public static suspend Object? updateAll(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public static suspend inline <reified State> Object? updateIf(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.jvm.functions.Function1<? super State,java.lang.Boolean> predicate, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
diff --git a/glance/glance-appwidget/api/restricted_current.txt b/glance/glance-appwidget/api/restricted_current.txt
index c1e33ae..1f04a7b 100644
--- a/glance/glance-appwidget/api/restricted_current.txt
+++ b/glance/glance-appwidget/api/restricted_current.txt
@@ -55,17 +55,17 @@
   public abstract class GlanceAppWidget {
     ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
     method public androidx.glance.appwidget.SizeMode getSizeMode();
-    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? getStateDefinition();
+    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? getStateDefinition();
     method @kotlin.jvm.Throws(exceptionClasses=Throwable::class) public void onCompositionError(android.content.Context context, androidx.glance.GlanceId glanceId, int appWidgetId, Throwable throwable) throws java.lang.Throwable;
     method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     property public androidx.glance.appwidget.SizeMode sizeMode;
-    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? stateDefinition;
+    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? stateDefinition;
   }
 
   public final class GlanceAppWidgetKt {
-    method public static suspend Object? provideContent(androidx.glance.appwidget.GlanceAppWidget, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public static suspend Object? provideContent(androidx.glance.appwidget.GlanceAppWidget, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     method public static suspend Object? updateAll(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public static suspend inline <reified State> Object? updateIf(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.jvm.functions.Function1<? super State,java.lang.Boolean> predicate, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
diff --git a/glance/glance-template/api/current.txt b/glance/glance-template/api/current.txt
index d709571..529b7b8 100644
--- a/glance/glance-template/api/current.txt
+++ b/glance/glance-template/api/current.txt
@@ -85,9 +85,9 @@
   public abstract class GlanceTemplateAppWidget extends androidx.glance.appwidget.GlanceAppWidget {
     ctor public GlanceTemplateAppWidget();
     method @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public abstract void TemplateContent();
-    method public final suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public final suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     property public androidx.glance.appwidget.SizeMode sizeMode;
-    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? stateDefinition;
+    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? stateDefinition;
     field public static final androidx.glance.template.GlanceTemplateAppWidget.Companion Companion;
   }
 
diff --git a/glance/glance-template/api/restricted_current.txt b/glance/glance-template/api/restricted_current.txt
index d709571..529b7b8 100644
--- a/glance/glance-template/api/restricted_current.txt
+++ b/glance/glance-template/api/restricted_current.txt
@@ -85,9 +85,9 @@
   public abstract class GlanceTemplateAppWidget extends androidx.glance.appwidget.GlanceAppWidget {
     ctor public GlanceTemplateAppWidget();
     method @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public abstract void TemplateContent();
-    method public final suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public final suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     property public androidx.glance.appwidget.SizeMode sizeMode;
-    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? stateDefinition;
+    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? stateDefinition;
     field public static final androidx.glance.template.GlanceTemplateAppWidget.Companion Companion;
   }
 
diff --git a/glance/glance-wear-tiles/api/current.txt b/glance/glance-wear-tiles/api/current.txt
index b1fbfa9..1b62900 100644
--- a/glance/glance-wear-tiles/api/current.txt
+++ b/glance/glance-wear-tiles/api/current.txt
@@ -21,14 +21,14 @@
   public abstract class GlanceTileService extends androidx.wear.tiles.TileService {
     ctor public GlanceTileService(optional androidx.wear.tiles.LayoutElementBuilders.LayoutElement? errorUiLayout);
     method @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public abstract void Content();
-    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? getStateDefinition();
+    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? getStateDefinition();
     method public final suspend <T> Object? getTileState(kotlin.coroutines.Continuation<? super T>);
     method public androidx.glance.wear.tiles.TimelineMode getTimelineMode();
     method protected final com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> onResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
     method public void onStart(android.content.Intent? intent, int startId);
     method protected final com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
     method public final suspend <T> Object? updateTileState(kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super T>,? extends java.lang.Object?> updateState, kotlin.coroutines.Continuation<? super T>);
-    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? stateDefinition;
+    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? stateDefinition;
     property public androidx.glance.wear.tiles.TimelineMode timelineMode;
   }
 
diff --git a/glance/glance-wear-tiles/api/restricted_current.txt b/glance/glance-wear-tiles/api/restricted_current.txt
index b1fbfa9..1b62900 100644
--- a/glance/glance-wear-tiles/api/restricted_current.txt
+++ b/glance/glance-wear-tiles/api/restricted_current.txt
@@ -21,14 +21,14 @@
   public abstract class GlanceTileService extends androidx.wear.tiles.TileService {
     ctor public GlanceTileService(optional androidx.wear.tiles.LayoutElementBuilders.LayoutElement? errorUiLayout);
     method @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public abstract void Content();
-    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? getStateDefinition();
+    method public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? getStateDefinition();
     method public final suspend <T> Object? getTileState(kotlin.coroutines.Continuation<? super T>);
     method public androidx.glance.wear.tiles.TimelineMode getTimelineMode();
     method protected final com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> onResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
     method public void onStart(android.content.Intent? intent, int startId);
     method protected final com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
     method public final suspend <T> Object? updateTileState(kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super T>,? extends java.lang.Object?> updateState, kotlin.coroutines.Continuation<? super T>);
-    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object!>? stateDefinition;
+    property public androidx.glance.state.GlanceStateDefinition<? extends java.lang.Object?>? stateDefinition;
     property public androidx.glance.wear.tiles.TimelineMode timelineMode;
   }
 
diff --git a/glance/glance/api/current.txt b/glance/glance/api/current.txt
index d7d9a71..66f1f53 100644
--- a/glance/glance/api/current.txt
+++ b/glance/glance/api/current.txt
@@ -129,7 +129,7 @@
     method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick);
     method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick, optional @DrawableRes int rippleOverride);
     method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
-    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional String? key, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional String? key, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
     method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, kotlin.jvm.functions.Function0<kotlin.Unit> block);
     field @DrawableRes public static final int NoRippleOverride = 0; // 0x0
   }
diff --git a/glance/glance/api/restricted_current.txt b/glance/glance/api/restricted_current.txt
index d7d9a71..66f1f53 100644
--- a/glance/glance/api/restricted_current.txt
+++ b/glance/glance/api/restricted_current.txt
@@ -129,7 +129,7 @@
     method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick);
     method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick, optional @DrawableRes int rippleOverride);
     method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
-    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional String? key, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional String? key, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
     method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, kotlin.jvm.functions.Function0<kotlin.Unit> block);
     field @DrawableRes public static final int NoRippleOverride = 0; // 0x0
   }
diff --git a/glance/glance/src/main/java/androidx/glance/action/Action.kt b/glance/glance/src/main/java/androidx/glance/action/Action.kt
index 93e8b94..6cc12b1 100644
--- a/glance/glance/src/main/java/androidx/glance/action/Action.kt
+++ b/glance/glance/src/main/java/androidx/glance/action/Action.kt
@@ -20,7 +20,6 @@
 import androidx.annotation.DrawableRes
 import androidx.annotation.RestrictTo
 import androidx.compose.runtime.Composable
-import androidx.glance.ExperimentalGlanceApi
 import androidx.glance.GlanceModifier
 
 /**
@@ -83,7 +82,6 @@
  *   provided we use the key that is automatically generated by the Compose runtime, which is unique
  *   for every exact code location in the composition tree.
  */
-@ExperimentalGlanceApi
 @Composable
 fun GlanceModifier.clickable(
     key: String? = null,
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
index d3e8195..d67e8df 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
@@ -26,6 +26,7 @@
 import android.os.Build
 import android.view.SurfaceHolder
 import android.view.SurfaceView
+import android.view.View
 import android.widget.FrameLayout
 import androidx.annotation.RequiresApi
 import androidx.graphics.opengl.GLRenderer
@@ -41,10 +42,12 @@
 import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
+import java.util.concurrent.ConcurrentLinkedQueue
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.Executor
 import java.util.concurrent.Executors
 import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicInteger
 import java.util.concurrent.atomic.AtomicReference
 import kotlin.math.abs
 import kotlin.math.roundToInt
@@ -1945,6 +1948,446 @@
         }
     }
 
+    @Test
+    fun stillOneDrawOnSurfaceCreationAfterDestroySurfaceWithPendingCommit() {
+        val multiBufferDraws: ConcurrentLinkedQueue<List<String>> = ConcurrentLinkedQueue()
+        var afterSurfaceDestroyedMultiBufferDraws: List<List<String>>? = null
+        val latchToCountDownOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val latchToAwaitOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val callbacks =
+            object : GLFrontBufferedRenderer.Callback<String> {
+
+                override fun onDrawFrontBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    param: String
+                ) {}
+
+                override fun onDrawMultiBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    params: Collection<String>
+                ) {
+                    multiBufferDraws.add(params.toList())
+                    latchToCountDownOnMultiLayerDraw.get()?.countDown()
+                    latchToAwaitOnMultiLayerDraw.get()?.await(3, TimeUnit.SECONDS)
+                }
+            }
+        verifyGLFrontBufferedRenderer(
+            callbacks,
+        ) { _, renderer, surfaceView ->
+            val untilSurfaceDestroyed = CountDownLatch(1)
+            val untilSurfaceCreated = CountDownLatch(1)
+            val untilFirstDrawAfterSurfaceCreated = CountDownLatch(1)
+            surfaceView.holder.addCallback(
+                object : SurfaceHolder.Callback {
+                    override fun surfaceCreated(holder: SurfaceHolder) {
+                        untilSurfaceCreated.countDown()
+                        latchToCountDownOnMultiLayerDraw.set(untilFirstDrawAfterSurfaceCreated)
+                    }
+
+                    override fun surfaceChanged(
+                        holder: SurfaceHolder,
+                        format: Int,
+                        width: Int,
+                        height: Int
+                    ) {}
+
+                    override fun surfaceDestroyed(holder: SurfaceHolder) {
+                        untilSurfaceDestroyed.countDown()
+                    }
+                }
+            )
+
+            // This draw is still ongoing when the view is hidden and the surface destroyed.
+            val untilInitialDraw = CountDownLatch(1)
+            latchToCountDownOnMultiLayerDraw.set(untilInitialDraw)
+            latchToAwaitOnMultiLayerDraw.set(untilSurfaceCreated)
+            renderer.renderFrontBufferedLayer("FIRST")
+            renderer.commit()
+
+            // This draw doesn't happen because pending callbacks are cancelled when the surface
+            // is destroyed.
+            renderer.renderFrontBufferedLayer("SECOND")
+            renderer.commit()
+            untilInitialDraw.await(3, TimeUnit.SECONDS)
+
+            // When the view is hidden and restored, the initial draw of the surface should call
+            // onDrawMultiBufferedLayer once, passing an empty list of params.
+            surfaceView.post { surfaceView.setVisibility(View.INVISIBLE) }
+            untilSurfaceDestroyed.await(3, TimeUnit.SECONDS)
+            afterSurfaceDestroyedMultiBufferDraws = multiBufferDraws.toList()
+
+            surfaceView.post { surfaceView.setVisibility(View.VISIBLE) }
+            untilFirstDrawAfterSurfaceCreated.await(3, TimeUnit.SECONDS)
+
+            // At the end of this block, renderer.release(false) is called to complete
+            // in-progress renders.
+        }
+        assertEquals(listOf(listOf(), listOf("FIRST")), afterSurfaceDestroyedMultiBufferDraws)
+        assertEquals(
+            // The draw with empty parameter list at the end happens when the surface is created.
+            // Before this fix, that incorrectly happened a second time.
+            listOf(listOf(), listOf("FIRST"), listOf()),
+            multiBufferDraws.toList()
+        )
+    }
+
+    @Test
+    fun noFrontDrawOnSurfaceCreationAfterDestroySurfaceWithPendingCommit() {
+        val frontDrawParams = ConcurrentLinkedQueue<String>()
+        val frontDrawCompleteCount = AtomicInteger(0)
+        var afterSurfaceDestroyedFrontDrawParams: List<String>? = null
+        var afterSurfaceDestroyedFrontDrawCount: Int? = null
+        val latchToCountDownOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val latchToAwaitOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val callbacks =
+            object : GLFrontBufferedRenderer.Callback<String> {
+
+                override fun onDrawFrontBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    param: String
+                ) {
+                    frontDrawParams.add(param)
+                }
+
+                override fun onFrontBufferedLayerRenderComplete(
+                    frontBufferedLayerSurfaceControl: SurfaceControlCompat,
+                    transaction: SurfaceControlCompat.Transaction
+                ) {
+                    // This one is a little more awkward to record because the
+                    // onDrawFrontBufferedLayer
+                    // is in a block passed to ParamQueue.next, which doesn't run when the
+                    // ParamQueue
+                    // is actually empty. onFrontBufferedLayerRenderComplete gets called
+                    // unconditionally
+                    // so examine that instead.
+                    frontDrawCompleteCount.incrementAndGet()
+                }
+
+                override fun onDrawMultiBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    params: Collection<String>
+                ) {
+                    latchToCountDownOnMultiLayerDraw.get()?.countDown()
+                    latchToAwaitOnMultiLayerDraw.get()?.await(3, TimeUnit.SECONDS)
+                }
+            }
+        verifyGLFrontBufferedRenderer(
+            callbacks,
+        ) { _, renderer, surfaceView ->
+            val untilSurfaceDestroyed = CountDownLatch(1)
+            val untilSurfaceCreated = CountDownLatch(1)
+            val untilFirstDrawAfterSurfaceCreated = CountDownLatch(1)
+            surfaceView.holder.addCallback(
+                object : SurfaceHolder.Callback {
+                    override fun surfaceCreated(holder: SurfaceHolder) {
+                        untilSurfaceCreated.countDown()
+                        latchToCountDownOnMultiLayerDraw.set(untilFirstDrawAfterSurfaceCreated)
+                    }
+
+                    override fun surfaceChanged(
+                        holder: SurfaceHolder,
+                        format: Int,
+                        width: Int,
+                        height: Int
+                    ) {}
+
+                    override fun surfaceDestroyed(holder: SurfaceHolder) {
+                        untilSurfaceDestroyed.countDown()
+                    }
+                }
+            )
+
+            // This draw is still ongoing when the view is hidden and the surface destroyed.
+            val untilInitialDraw = CountDownLatch(1)
+            latchToCountDownOnMultiLayerDraw.set(untilInitialDraw)
+            latchToAwaitOnMultiLayerDraw.set(untilSurfaceCreated)
+            renderer.commit()
+
+            // This draw doesn't happen because pending callbacks are cancelled when the surface
+            // is destroyed.
+            renderer.renderFrontBufferedLayer("TOSSED")
+            untilInitialDraw.await(3, TimeUnit.SECONDS)
+
+            // When the view is hidden and restored, the initial draw of the surface should call
+            // onDrawMultiBufferedLayer once, passing an empty list of params.
+            surfaceView.post { surfaceView.setVisibility(View.INVISIBLE) }
+            untilSurfaceDestroyed.await(3, TimeUnit.SECONDS)
+            afterSurfaceDestroyedFrontDrawParams = frontDrawParams.toList()
+            afterSurfaceDestroyedFrontDrawCount = frontDrawCompleteCount.get()
+
+            surfaceView.post { surfaceView.setVisibility(View.VISIBLE) }
+            untilFirstDrawAfterSurfaceCreated.await(3, TimeUnit.SECONDS)
+
+            // At the end of this block, renderer.release(false) is called to complete
+            // in-progress renders.
+        }
+        assertTrue(afterSurfaceDestroyedFrontDrawParams!!.isEmpty())
+        assertEquals(0, afterSurfaceDestroyedFrontDrawCount)
+        assertTrue(frontDrawParams.isEmpty())
+        // Before this fix, this would be 1, as the underlying render request would happen
+        // (even though the user onDrawFrontBufferedLayer callback would not).
+        assertEquals(0, frontDrawCompleteCount.get())
+    }
+
+    @Test
+    fun stillOneDrawAfterClearWithPendingCommit() {
+        val multiBufferDraws: ConcurrentLinkedQueue<List<String>> = ConcurrentLinkedQueue()
+        var beforeClearMultiBufferDraws: List<List<String>>? = null
+        val latchToCountDownOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val latchToAwaitOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val callbacks =
+            object : GLFrontBufferedRenderer.Callback<String> {
+
+                override fun onDrawFrontBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    param: String
+                ) {}
+
+                override fun onDrawMultiBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    params: Collection<String>
+                ) {
+                    multiBufferDraws.add(params.toList())
+                    latchToCountDownOnMultiLayerDraw.get()?.countDown()
+                    latchToAwaitOnMultiLayerDraw.get()?.await(3, TimeUnit.SECONDS)
+                }
+            }
+        verifyGLFrontBufferedRenderer(callbacks) { _, renderer, _ ->
+            val untilInitialDraw = CountDownLatch(1)
+            val untilAfterClear = CountDownLatch(1)
+            latchToCountDownOnMultiLayerDraw.set(untilInitialDraw)
+            latchToAwaitOnMultiLayerDraw.set(untilAfterClear)
+            renderer.renderFrontBufferedLayer("STALLED")
+            renderer.commit() // This draw is still in progress on clear
+            renderer.renderFrontBufferedLayer("TOSSED")
+            renderer.commit() // This draw is deferred on clear and never happens
+
+            untilInitialDraw.await(3, TimeUnit.SECONDS)
+            beforeClearMultiBufferDraws = multiBufferDraws.toList()
+            renderer.clear()
+            untilAfterClear.countDown()
+
+            // At the end of this block, renderer.release(false) is called to complete
+            // in-progress renders.
+        }
+        assertEquals(listOf(listOf(), listOf("STALLED")), beforeClearMultiBufferDraws)
+        assertEquals(
+            // The draw with empty parameter list at the end happens on clear.
+            // Before this fix, that incorrectly happened a second time.
+            listOf(listOf(), listOf("STALLED"), listOf()),
+            multiBufferDraws.toList()
+        )
+    }
+
+    @Test
+    fun noFrontDrawAfterClearWithPendingCommit() {
+        val frontDrawParams = ConcurrentLinkedQueue<String>()
+        val frontDrawCompleteCount = AtomicInteger(0)
+        var beforeClearFrontDrawParams: List<String>? = null
+        var beforeClearFrontDrawCompleteCount: Int? = null
+        val latchToCountDownOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val latchToAwaitOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val callbacks =
+            object : GLFrontBufferedRenderer.Callback<String> {
+
+                override fun onDrawFrontBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    param: String
+                ) {
+                    frontDrawParams.add(param)
+                }
+
+                override fun onFrontBufferedLayerRenderComplete(
+                    frontBufferedLayerSurfaceControl: SurfaceControlCompat,
+                    transaction: SurfaceControlCompat.Transaction
+                ) {
+                    // This one is a little more awkward to record because the
+                    // onDrawFrontBufferedLayer
+                    // is in a block passed to ParamQueue.next, which doesn't run when the
+                    // ParamQueue
+                    // is actually empty. onFrontBufferedLayerRenderComplete gets called
+                    // unconditionally
+                    // so examine that instead.
+                    frontDrawCompleteCount.incrementAndGet()
+                }
+
+                override fun onDrawMultiBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    params: Collection<String>
+                ) {
+                    latchToCountDownOnMultiLayerDraw.get()?.countDown()
+                    latchToAwaitOnMultiLayerDraw.get()?.await(3, TimeUnit.SECONDS)
+                }
+            }
+        verifyGLFrontBufferedRenderer(
+            callbacks,
+        ) { _, renderer, _ ->
+            val untilInitialDraw = CountDownLatch(1)
+            val untilAfterClear = CountDownLatch(1)
+            latchToCountDownOnMultiLayerDraw.set(untilInitialDraw)
+            latchToAwaitOnMultiLayerDraw.set(untilAfterClear)
+            renderer.commit() // This draw is still in progress on clear
+
+            // This draw doesn't happen because pending draws are cancelled on clear.
+            renderer.renderFrontBufferedLayer("TOSSED")
+            untilInitialDraw.await(3, TimeUnit.SECONDS)
+            beforeClearFrontDrawParams = frontDrawParams.toList()
+            beforeClearFrontDrawCompleteCount = frontDrawCompleteCount.get()
+            renderer.clear()
+            untilAfterClear.countDown()
+
+            // At the end of this block, renderer.release(false) is called to complete
+            // in-progress renders.
+        }
+        assertTrue(beforeClearFrontDrawParams!!.isEmpty())
+        assertEquals(0, beforeClearFrontDrawCompleteCount)
+        assertTrue(frontDrawParams.isEmpty())
+        // Before this fix, this would be 1, as the underlying render request would happen
+        // (even though the user onDrawFrontBufferedLayer callback would not).
+        assertEquals(0, frontDrawCompleteCount.get())
+    }
+
+    @Test
+    fun deferredCommitsAreCompletedOnReleaseIfCancelPendingIsFalse() {
+        val multiBufferDraws: ConcurrentLinkedQueue<List<String>> = ConcurrentLinkedQueue()
+        var beforeStallMultiBufferDraws: List<List<String>>? = null
+        val latchToCountDownOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val latchToAwaitOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val callbacks =
+            object : GLFrontBufferedRenderer.Callback<String> {
+
+                override fun onDrawFrontBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    param: String
+                ) {}
+
+                override fun onDrawMultiBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    params: Collection<String>
+                ) {
+                    multiBufferDraws.add(params.toList())
+                    latchToCountDownOnMultiLayerDraw.get()?.countDown()
+                    latchToAwaitOnMultiLayerDraw.get()?.await(3, TimeUnit.SECONDS)
+                }
+            }
+        verifyGLFrontBufferedRenderer(callbacks) { _, renderer, _ ->
+            val untilInitialDraw = CountDownLatch(1)
+            val untilAllRendersRequested = CountDownLatch(1)
+            latchToCountDownOnMultiLayerDraw.set(untilInitialDraw)
+            latchToAwaitOnMultiLayerDraw.set(untilAllRendersRequested)
+            renderer.renderFrontBufferedLayer("STALLED")
+            renderer.commit() // This draw gets stuck until the end of the block.
+            untilInitialDraw.await(3, TimeUnit.SECONDS)
+            renderer.renderFrontBufferedLayer("DEFERRED")
+            renderer.commit() // This draw is deferred.
+
+            // At the end of this block, renderer.release(false) is called to complete
+            // in-progress renders.
+            beforeStallMultiBufferDraws = multiBufferDraws.toList()
+            untilAllRendersRequested.countDown()
+        }
+        assertEquals(listOf(listOf(), listOf("STALLED")), beforeStallMultiBufferDraws)
+        assertEquals(
+            listOf(listOf(), listOf("STALLED"), listOf("DEFERRED")),
+            multiBufferDraws.toList()
+        )
+    }
+
+    @Test
+    fun deferredFrontBufferedRendersAreCompletedOnReleaseIfCancelPendingIsFalse() {
+        val frontBufferDraws: ConcurrentLinkedQueue<String> = ConcurrentLinkedQueue()
+        val latchToCountDownOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        val latchToAwaitOnMultiLayerDraw = AtomicReference<CountDownLatch?>()
+        var beforeStallEndsFrontDraws: List<String>? = null
+        val callbacks =
+            object : GLFrontBufferedRenderer.Callback<String> {
+
+                override fun onDrawFrontBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    param: String
+                ) {
+                    frontBufferDraws.add(param)
+                }
+
+                override fun onDrawMultiBufferedLayer(
+                    eglManager: EGLManager,
+                    width: Int,
+                    height: Int,
+                    bufferInfo: BufferInfo,
+                    transform: FloatArray,
+                    params: Collection<String>
+                ) {
+                    latchToCountDownOnMultiLayerDraw.get()?.countDown()
+                    latchToAwaitOnMultiLayerDraw.get()?.await(3, TimeUnit.SECONDS)
+                }
+            }
+        verifyGLFrontBufferedRenderer(
+            callbacks,
+        ) { _, renderer, _ ->
+            val untilAllRendersRequested = CountDownLatch(1)
+            val untilInitialDraw = CountDownLatch(1)
+            latchToCountDownOnMultiLayerDraw.set(untilInitialDraw)
+            latchToAwaitOnMultiLayerDraw.set(untilAllRendersRequested)
+            renderer.commit() // This draw gets stuck until the end of the block.
+            untilInitialDraw.await(3, TimeUnit.SECONDS)
+            renderer.renderFrontBufferedLayer("FIRST")
+            renderer.renderFrontBufferedLayer("SECOND")
+
+            // At the end of this block, renderer.release(false) is called to complete
+            // in-progress renders.
+            beforeStallEndsFrontDraws = frontBufferDraws.toList()
+            untilAllRendersRequested.countDown()
+        }
+        // The assertion is here instead of above because if assert leaves the GL Thread stalled
+        // the error is confusing.
+        assertTrue(beforeStallEndsFrontDraws!!.isEmpty())
+        assertEquals(listOf("FIRST", "SECOND"), frontBufferDraws.toList())
+    }
+
     @RequiresApi(Build.VERSION_CODES.Q)
     private fun GLFrontBufferedRenderer<*>?.blockingRelease(timeoutMillis: Long = 3000) {
         if (this != null) {
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/GLFrontBufferedRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/GLFrontBufferedRenderer.kt
index 31125adb..f2e937b 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/GLFrontBufferedRenderer.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/GLFrontBufferedRenderer.kt
@@ -671,11 +671,27 @@
      * SurfaceControl instances
      */
     internal fun detachTargets(cancelPending: Boolean, onReleaseComplete: (() -> Unit)? = null) {
+        // If we're not cancelling the pending renders, dispatch requested but deferred renders
+        // immediately so they end up run before the thread is actually canceled.
+        if (!cancelPending) {
+            // This is the count of pending commits including an already-in-flight one, so update
+            // first to count and commit the remaining ones.
+            while (mCommitCount.updateAndGet { value -> max(value - 1, 0) } > 0) {
+                commitInternal()
+            }
+            // This is the count of deferred front-layer renders, so we update after to get the
+            // current count. Note that if there was a deferred commit, any deferred front-layer
+            // renders are preempted; the call to commitInternal sets mPendingRenderCount to 0.
+            while (mPendingRenderCount.getAndUpdate { value -> max(value - 1, 0) } > 0) {
+                mFrontBufferedRenderer?.render()
+            }
+        }
         mMultiBufferedRenderer?.release(cancelPending)
         mFrontBufferedRenderer?.release(cancelPending)
         val frontSc = mFrontBufferedLayerSurfaceControl
         val parentSc = mMultiBufferedLayerSurfaceControl
         mGLRenderer.execute {
+            // This is deferred until all the GL callbacks not canceled by release are complete.
             clearParamQueues()
             if (frontSc != null && frontSc.isValid() && parentSc != null && parentSc.isValid()) {
                 SurfaceControlCompat.Transaction()
@@ -741,7 +757,9 @@
 
     private fun clearParamQueues() {
         mActiveSegment.clear()
+        mCommitCount.set(0)
         mSegments.clear()
+        mPendingRenderCount.set(0)
     }
 
     internal companion object {
diff --git a/health/connect/connect-client/api/current.txt b/health/connect/connect-client/api/current.txt
index 1eb1a99..f01a72a 100644
--- a/health/connect/connect-client/api/current.txt
+++ b/health/connect/connect-client/api/current.txt
@@ -70,7 +70,7 @@
   }
 
   public final class AggregationResult {
-    method public operator boolean contains(androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!> metric);
+    method public operator boolean contains(androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?> metric);
     method public operator <T> T? get(androidx.health.connect.client.aggregate.AggregateMetric<? extends T> metric);
     method public java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> getDataOrigins();
     property public final java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOrigins;
@@ -1386,15 +1386,15 @@
 package androidx.health.connect.client.request {
 
   public final class AggregateGroupByDurationRequest {
-    ctor public AggregateGroupByDurationRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Duration timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
+    ctor public AggregateGroupByDurationRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Duration timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
   }
 
   public final class AggregateGroupByPeriodRequest {
-    ctor public AggregateGroupByPeriodRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Period timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
+    ctor public AggregateGroupByPeriodRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Period timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
   }
 
   public final class AggregateRequest {
-    ctor public AggregateRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
+    ctor public AggregateRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
   }
 
   public final class ChangesTokenRequest {
diff --git a/health/connect/connect-client/api/restricted_current.txt b/health/connect/connect-client/api/restricted_current.txt
index 6630b60..9c0d728 100644
--- a/health/connect/connect-client/api/restricted_current.txt
+++ b/health/connect/connect-client/api/restricted_current.txt
@@ -70,7 +70,7 @@
   }
 
   public final class AggregationResult {
-    method public operator boolean contains(androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!> metric);
+    method public operator boolean contains(androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?> metric);
     method public operator <T> T? get(androidx.health.connect.client.aggregate.AggregateMetric<? extends T> metric);
     method public java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> getDataOrigins();
     property public final java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOrigins;
@@ -1409,15 +1409,15 @@
 package androidx.health.connect.client.request {
 
   public final class AggregateGroupByDurationRequest {
-    ctor public AggregateGroupByDurationRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Duration timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
+    ctor public AggregateGroupByDurationRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Duration timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
   }
 
   public final class AggregateGroupByPeriodRequest {
-    ctor public AggregateGroupByPeriodRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Period timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
+    ctor public AggregateGroupByPeriodRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, java.time.Period timeRangeSlicer, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
   }
 
   public final class AggregateRequest {
-    ctor public AggregateRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object!>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
+    ctor public AggregateRequest(java.util.Set<? extends androidx.health.connect.client.aggregate.AggregateMetric<? extends java.lang.Object?>> metrics, androidx.health.connect.client.time.TimeRangeFilter timeRangeFilter, optional java.util.Set<androidx.health.connect.client.records.metadata.DataOrigin> dataOriginFilter);
   }
 
   public final class ChangesTokenRequest {
diff --git a/health/health-services-client/api/current.txt b/health/health-services-client/api/current.txt
index 5501ef6..2fd8af7 100644
--- a/health/health-services-client/api/current.txt
+++ b/health/health-services-client/api/current.txt
@@ -2,8 +2,8 @@
 package androidx.health.services.client {
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface ExerciseClient {
-    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addDebouncedGoalToActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addGoalToActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal);
+    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addDebouncedGoalToActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addGoalToActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> clearUpdateCallbackAsync(androidx.health.services.client.ExerciseUpdateCallback callback);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> endExerciseAsync();
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> flushAsync();
@@ -14,8 +14,8 @@
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> overrideBatchingModesForActiveExerciseAsync(java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModes);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> pauseExerciseAsync();
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> prepareExerciseAsync(androidx.health.services.client.data.WarmUpConfig configuration);
-    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeDebouncedGoalFromActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeGoalFromActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal);
+    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeDebouncedGoalFromActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeGoalFromActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> resumeExerciseAsync();
     method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
     method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
@@ -24,8 +24,8 @@
   }
 
   public final class ExerciseClientExtensionKt {
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addDebouncedGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addDebouncedGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? clearUpdateCallback(androidx.health.services.client.ExerciseClient, androidx.health.services.client.ExerciseUpdateCallback callback, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? endExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? flush(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
@@ -36,15 +36,15 @@
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? overrideBatchingModesForActiveExercise(androidx.health.services.client.ExerciseClient, java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModes, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? pauseExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? prepareExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.WarmUpConfig configuration, kotlin.coroutines.Continuation<? super kotlin.Unit>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeDebouncedGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeDebouncedGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super kotlin.Unit>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
   }
 
   public interface ExerciseUpdateCallback {
-    method public void onAvailabilityChanged(androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.data.Availability availability);
+    method public void onAvailabilityChanged(androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.data.Availability availability);
     method public default void onExerciseEventReceived(androidx.health.services.client.data.ExerciseEvent event);
     method public void onExerciseUpdateReceived(androidx.health.services.client.data.ExerciseUpdate update);
     method public void onLapSummaryReceived(androidx.health.services.client.data.ExerciseLapSummary lapSummary);
@@ -75,7 +75,7 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface MeasureCallback {
-    method public void onAvailabilityChanged(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.data.Availability availability);
+    method public void onAvailabilityChanged(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.data.Availability availability);
     method public void onDataReceived(androidx.health.services.client.data.DataPointContainer data);
     method public default void onRegistered();
     method public default void onRegistrationFailed(Throwable throwable);
@@ -83,14 +83,14 @@
 
   public interface MeasureClient {
     method public com.google.common.util.concurrent.ListenableFuture<androidx.health.services.client.data.MeasureCapabilities> getCapabilitiesAsync();
-    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.MeasureCallback callback);
-    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, java.util.concurrent.Executor executor, androidx.health.services.client.MeasureCallback callback);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> unregisterMeasureCallbackAsync(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.MeasureCallback callback);
+    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.MeasureCallback callback);
+    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, java.util.concurrent.Executor executor, androidx.health.services.client.MeasureCallback callback);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> unregisterMeasureCallbackAsync(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.MeasureCallback callback);
   }
 
   public final class MeasureClientExtensionKt {
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? getCapabilities(androidx.health.services.client.MeasureClient, kotlin.coroutines.Continuation<? super androidx.health.services.client.data.MeasureCapabilities>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? unregisterMeasureCallback(androidx.health.services.client.MeasureClient, androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.MeasureCallback callback, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? unregisterMeasureCallback(androidx.health.services.client.MeasureClient, androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.MeasureCallback callback, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface PassiveListenerCallback {
@@ -192,20 +192,20 @@
   }
 
   public final class DataPointContainer {
-    ctor public DataPointContainer(java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object!>> dataPointList);
-    ctor public DataPointContainer(java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object!>>> dataPoints);
-    method public java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object!>> getCumulativeDataPoints();
+    ctor public DataPointContainer(java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object?>> dataPointList);
+    ctor public DataPointContainer(java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object?>>> dataPoints);
+    method public java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object?>> getCumulativeDataPoints();
     method public <T extends java.lang.Number, D extends androidx.health.services.client.data.DataPoint<T>> D? getData(androidx.health.services.client.data.AggregateDataType<T,D> type);
     method public <T, D extends androidx.health.services.client.data.DataPoint<T>> java.util.List<D> getData(androidx.health.services.client.data.DeltaDataType<T,D> type);
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getDataTypes();
-    method public java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object!>> getIntervalDataPoints();
-    method public java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object!>> getSampleDataPoints();
-    method public java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object!>> getStatisticalDataPoints();
-    property public final java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object!>> cumulativeDataPoints;
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes;
-    property public final java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object!>> intervalDataPoints;
-    property public final java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object!>> sampleDataPoints;
-    property public final java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object!>> statisticalDataPoints;
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getDataTypes();
+    method public java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object?>> getIntervalDataPoints();
+    method public java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object?>> getSampleDataPoints();
+    method public java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object?>> getStatisticalDataPoints();
+    property public final java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object?>> cumulativeDataPoints;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes;
+    property public final java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object?>> intervalDataPoints;
+    property public final java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object?>> sampleDataPoints;
+    property public final java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object?>> statisticalDataPoints;
   }
 
   public abstract class DataType<T, D extends androidx.health.services.client.data.DataPoint<T>> {
@@ -351,8 +351,8 @@
   public final class DebouncedGoal<T extends java.lang.Number> {
     method public static <T extends java.lang.Number> androidx.health.services.client.data.DebouncedGoal<T> createAggregateDebouncedGoal(androidx.health.services.client.data.DebouncedDataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,androidx.health.services.client.data.StatisticalDataPoint<T>>> condition);
     method public static <T extends java.lang.Number> androidx.health.services.client.data.DebouncedGoal<T> createSampleDebouncedGoal(androidx.health.services.client.data.DebouncedDataTypeCondition<T,androidx.health.services.client.data.DeltaDataType<T,androidx.health.services.client.data.SampleDataPoint<T>>> condition);
-    method public androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object!> getDebouncedDataTypeCondition();
-    property public final androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object!> debouncedDataTypeCondition;
+    method public androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object?> getDebouncedDataTypeCondition();
+    property public final androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object?> debouncedDataTypeCondition;
     field public static final androidx.health.services.client.data.DebouncedGoal.Companion Companion;
   }
 
@@ -380,20 +380,20 @@
   }
 
   public final class ExerciseConfig {
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes, optional java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> debouncedGoals);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes, optional java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> debouncedGoals);
     method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
     method public java.util.Set<androidx.health.services.client.data.BatchingMode> getBatchingModeOverrides();
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getDataTypes();
-    method public java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> getDebouncedGoals();
-    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> getExerciseEventTypes();
-    method public java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> getExerciseGoals();
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getDataTypes();
+    method public java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> getDebouncedGoals();
+    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> getExerciseEventTypes();
+    method public java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> getExerciseGoals();
     method public android.os.Bundle getExerciseParams();
     method public androidx.health.services.client.data.ExerciseType getExerciseType();
     method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
@@ -401,10 +401,10 @@
     method public boolean isAutoPauseAndResumeEnabled();
     method public boolean isGpsEnabled();
     property public final java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides;
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes;
-    property public final java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> debouncedGoals;
-    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes;
-    property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes;
+    property public final java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> debouncedGoals;
+    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes;
+    property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals;
     property public final android.os.Bundle exerciseParams;
     property public final androidx.health.services.client.data.ExerciseType exerciseType;
     property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
@@ -419,10 +419,10 @@
     ctor public ExerciseConfig.Builder(androidx.health.services.client.data.ExerciseType exerciseType);
     method public androidx.health.services.client.data.ExerciseConfig build();
     method public androidx.health.services.client.data.ExerciseConfig.Builder setBatchingModeOverrides(java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setDebouncedGoals(java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> debouncedGoals);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseEventTypes(java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setDebouncedGoals(java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> debouncedGoals);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseEventTypes(java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals);
     method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
     method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
     method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
@@ -460,25 +460,25 @@
   }
 
   public final class ExerciseGoal<T extends java.lang.Number> implements android.os.Parcelable {
-    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition, T period);
+    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition, T period);
     method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestoneGoalWithUpdatedThreshold(androidx.health.services.client.data.ExerciseGoal<T> goal, T newThreshold);
-    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition);
+    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition);
     method public int describeContents();
-    method public androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> getDataTypeCondition();
+    method public androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> getDataTypeCondition();
     method public androidx.health.services.client.data.ExerciseGoalType getExerciseGoalType();
     method public T? getPeriod();
     method public void writeToParcel(android.os.Parcel dest, int flags);
-    property public final androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> dataTypeCondition;
+    property public final androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> dataTypeCondition;
     property public final androidx.health.services.client.data.ExerciseGoalType exerciseGoalType;
     property public final T? period;
-    field public static final android.os.Parcelable.Creator<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> CREATOR;
+    field public static final android.os.Parcelable.Creator<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> CREATOR;
     field public static final androidx.health.services.client.data.ExerciseGoal.Companion Companion;
   }
 
   public static final class ExerciseGoal.Companion {
-    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition, T period);
+    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition, T period);
     method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestoneGoalWithUpdatedThreshold(androidx.health.services.client.data.ExerciseGoal<T> goal, T newThreshold);
-    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition);
+    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition);
   }
 
   public final class ExerciseGoalType {
@@ -661,21 +661,21 @@
   }
 
   public final class ExerciseTypeCapabilities {
-    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume);
-    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities);
-    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities, optional java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals);
+    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume);
+    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities);
+    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities, optional java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals);
     method public <C extends androidx.health.services.client.data.ExerciseEventCapabilities> C? getExerciseEventCapabilityDetails(androidx.health.services.client.data.ExerciseEventType<C> exerciseEventType);
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypes();
-    method public java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedDebouncedGoals();
-    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> getSupportedExerciseEvents();
-    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedGoals();
-    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedMilestones();
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypes();
+    method public java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedDebouncedGoals();
+    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> getSupportedExerciseEvents();
+    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedGoals();
+    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedMilestones();
     method public boolean getSupportsAutoPauseAndResume();
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes;
-    property public final java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals;
-    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> supportedExerciseEvents;
-    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals;
-    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes;
+    property public final java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals;
+    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> supportedExerciseEvents;
+    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals;
+    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones;
     property public final boolean supportsAutoPauseAndResume;
   }
 
@@ -687,8 +687,8 @@
   }
 
   public final class ExerciseUpdate {
-    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object!> dataPoint);
-    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object!> dataPoint);
+    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object?> dataPoint);
+    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object?> dataPoint);
     method public androidx.health.services.client.data.ExerciseUpdate.ActiveDurationCheckpoint? getActiveDurationCheckpoint();
     method public androidx.health.services.client.data.ExerciseConfig? getExerciseConfig();
     method public androidx.health.services.client.data.ExerciseStateInfo getExerciseStateInfo();
@@ -876,9 +876,9 @@
   }
 
   public final class MeasureCapabilities {
-    ctor public MeasureCapabilities(java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesMeasure);
-    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypesMeasure();
-    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesMeasure;
+    ctor public MeasureCapabilities(java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesMeasure);
+    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypesMeasure();
+    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesMeasure;
   }
 
   public final class MilestoneMarkerSummary {
@@ -896,9 +896,9 @@
   }
 
   public final class PassiveGoal {
-    ctor public PassiveGoal(androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object!>> dataTypeCondition);
-    method public androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object!>> getDataTypeCondition();
-    property public final androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object!>> dataTypeCondition;
+    ctor public PassiveGoal(androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object?>> dataTypeCondition);
+    method public androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object?>> getDataTypeCondition();
+    property public final androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object?>> dataTypeCondition;
   }
 
   public final class PassiveListenerConfig {
@@ -919,7 +919,7 @@
     ctor public PassiveListenerConfig.Builder();
     method public androidx.health.services.client.data.PassiveListenerConfig build();
     method public androidx.health.services.client.data.PassiveListenerConfig.Builder setDailyGoals(java.util.Set<androidx.health.services.client.data.PassiveGoal> dailyGoals);
-    method public androidx.health.services.client.data.PassiveListenerConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes);
+    method public androidx.health.services.client.data.PassiveListenerConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes);
     method public androidx.health.services.client.data.PassiveListenerConfig.Builder setHealthEventTypes(java.util.Set<androidx.health.services.client.data.HealthEvent.Type> healthEventTypes);
     method public androidx.health.services.client.data.PassiveListenerConfig.Builder setShouldUserActivityInfoBeRequested(boolean shouldUserActivityInfoBeRequested);
   }
@@ -929,13 +929,13 @@
   }
 
   public final class PassiveMonitoringCapabilities {
-    ctor public PassiveMonitoringCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveMonitoring, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveGoals, java.util.Set<androidx.health.services.client.data.HealthEvent.Type> supportedHealthEventTypes, java.util.Set<androidx.health.services.client.data.UserActivityState> supportedUserActivityStates);
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypesPassiveGoals();
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypesPassiveMonitoring();
+    ctor public PassiveMonitoringCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveMonitoring, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveGoals, java.util.Set<androidx.health.services.client.data.HealthEvent.Type> supportedHealthEventTypes, java.util.Set<androidx.health.services.client.data.UserActivityState> supportedUserActivityStates);
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypesPassiveGoals();
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypesPassiveMonitoring();
     method public java.util.Set<androidx.health.services.client.data.HealthEvent.Type> getSupportedHealthEventTypes();
     method public java.util.Set<androidx.health.services.client.data.UserActivityState> getSupportedUserActivityStates();
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveGoals;
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveMonitoring;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveGoals;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveMonitoring;
     property public final java.util.Set<androidx.health.services.client.data.HealthEvent.Type> supportedHealthEventTypes;
     property public final java.util.Set<androidx.health.services.client.data.UserActivityState> supportedUserActivityStates;
   }
@@ -1020,10 +1020,10 @@
   }
 
   public final class WarmUpConfig {
-    ctor public WarmUpConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes);
-    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> getDataTypes();
+    ctor public WarmUpConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes);
+    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> getDataTypes();
     method public androidx.health.services.client.data.ExerciseType getExerciseType();
-    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes;
+    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes;
     property public final androidx.health.services.client.data.ExerciseType exerciseType;
   }
 
diff --git a/health/health-services-client/api/restricted_current.txt b/health/health-services-client/api/restricted_current.txt
index 54fce55..6b19869 100644
--- a/health/health-services-client/api/restricted_current.txt
+++ b/health/health-services-client/api/restricted_current.txt
@@ -2,8 +2,8 @@
 package androidx.health.services.client {
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface ExerciseClient {
-    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addDebouncedGoalToActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addGoalToActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal);
+    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addDebouncedGoalToActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> addGoalToActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> clearUpdateCallbackAsync(androidx.health.services.client.ExerciseUpdateCallback callback);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> endExerciseAsync();
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> flushAsync();
@@ -14,8 +14,8 @@
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> overrideBatchingModesForActiveExerciseAsync(java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModes);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> pauseExerciseAsync();
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> prepareExerciseAsync(androidx.health.services.client.data.WarmUpConfig configuration);
-    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeDebouncedGoalFromActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeGoalFromActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal);
+    method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeDebouncedGoalFromActiveExerciseAsync(androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> removeGoalFromActiveExerciseAsync(androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> resumeExerciseAsync();
     method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
     method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
@@ -24,8 +24,8 @@
   }
 
   public final class ExerciseClientExtensionKt {
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addDebouncedGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addDebouncedGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? addGoalToActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? clearUpdateCallback(androidx.health.services.client.ExerciseClient, androidx.health.services.client.ExerciseUpdateCallback callback, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? endExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? flush(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
@@ -36,15 +36,15 @@
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? overrideBatchingModesForActiveExercise(androidx.health.services.client.ExerciseClient, java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModes, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? pauseExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? prepareExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.WarmUpConfig configuration, kotlin.coroutines.Continuation<? super kotlin.Unit>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeDebouncedGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeDebouncedGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?> debouncedGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super kotlin.Unit>) throws androidx.health.services.client.HealthServicesException;
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
   }
 
   public interface ExerciseUpdateCallback {
-    method public void onAvailabilityChanged(androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.data.Availability availability);
+    method public void onAvailabilityChanged(androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.data.Availability availability);
     method public default void onExerciseEventReceived(androidx.health.services.client.data.ExerciseEvent event);
     method public void onExerciseUpdateReceived(androidx.health.services.client.data.ExerciseUpdate update);
     method public void onLapSummaryReceived(androidx.health.services.client.data.ExerciseLapSummary lapSummary);
@@ -75,7 +75,7 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface MeasureCallback {
-    method public void onAvailabilityChanged(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.data.Availability availability);
+    method public void onAvailabilityChanged(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.data.Availability availability);
     method public void onDataReceived(androidx.health.services.client.data.DataPointContainer data);
     method public default void onRegistered();
     method public default void onRegistrationFailed(Throwable throwable);
@@ -83,14 +83,14 @@
 
   public interface MeasureClient {
     method public com.google.common.util.concurrent.ListenableFuture<androidx.health.services.client.data.MeasureCapabilities> getCapabilitiesAsync();
-    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.MeasureCallback callback);
-    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, java.util.concurrent.Executor executor, androidx.health.services.client.MeasureCallback callback);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> unregisterMeasureCallbackAsync(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.MeasureCallback callback);
+    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.MeasureCallback callback);
+    method public void registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, java.util.concurrent.Executor executor, androidx.health.services.client.MeasureCallback callback);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> unregisterMeasureCallbackAsync(androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.MeasureCallback callback);
   }
 
   public final class MeasureClientExtensionKt {
     method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? getCapabilities(androidx.health.services.client.MeasureClient, kotlin.coroutines.Continuation<? super androidx.health.services.client.data.MeasureCapabilities>) throws androidx.health.services.client.HealthServicesException;
-    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? unregisterMeasureCallback(androidx.health.services.client.MeasureClient, androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!> dataType, androidx.health.services.client.MeasureCallback callback, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
+    method @kotlin.jvm.Throws(exceptionClasses=HealthServicesException::class) public static suspend Object? unregisterMeasureCallback(androidx.health.services.client.MeasureClient, androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?> dataType, androidx.health.services.client.MeasureCallback callback, kotlin.coroutines.Continuation<? super java.lang.Void>) throws androidx.health.services.client.HealthServicesException;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface PassiveListenerCallback {
@@ -192,20 +192,20 @@
   }
 
   public final class DataPointContainer {
-    ctor public DataPointContainer(java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object!>> dataPointList);
-    ctor public DataPointContainer(java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object!>>> dataPoints);
-    method public java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object!>> getCumulativeDataPoints();
+    ctor public DataPointContainer(java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object?>> dataPointList);
+    ctor public DataPointContainer(java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.List<? extends androidx.health.services.client.data.DataPoint<? extends java.lang.Object?>>> dataPoints);
+    method public java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object?>> getCumulativeDataPoints();
     method public <T extends java.lang.Number, D extends androidx.health.services.client.data.DataPoint<T>> D? getData(androidx.health.services.client.data.AggregateDataType<T,D> type);
     method public <T, D extends androidx.health.services.client.data.DataPoint<T>> java.util.List<D> getData(androidx.health.services.client.data.DeltaDataType<T,D> type);
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getDataTypes();
-    method public java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object!>> getIntervalDataPoints();
-    method public java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object!>> getSampleDataPoints();
-    method public java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object!>> getStatisticalDataPoints();
-    property public final java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object!>> cumulativeDataPoints;
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes;
-    property public final java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object!>> intervalDataPoints;
-    property public final java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object!>> sampleDataPoints;
-    property public final java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object!>> statisticalDataPoints;
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getDataTypes();
+    method public java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object?>> getIntervalDataPoints();
+    method public java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object?>> getSampleDataPoints();
+    method public java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object?>> getStatisticalDataPoints();
+    property public final java.util.List<androidx.health.services.client.data.CumulativeDataPoint<? extends java.lang.Object?>> cumulativeDataPoints;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes;
+    property public final java.util.List<androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object?>> intervalDataPoints;
+    property public final java.util.List<androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object?>> sampleDataPoints;
+    property public final java.util.List<androidx.health.services.client.data.StatisticalDataPoint<? extends java.lang.Object?>> statisticalDataPoints;
   }
 
   public abstract class DataType<T, D extends androidx.health.services.client.data.DataPoint<T>> {
@@ -351,8 +351,8 @@
   public final class DebouncedGoal<T extends java.lang.Number> {
     method public static <T extends java.lang.Number> androidx.health.services.client.data.DebouncedGoal<T> createAggregateDebouncedGoal(androidx.health.services.client.data.DebouncedDataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,androidx.health.services.client.data.StatisticalDataPoint<T>>> condition);
     method public static <T extends java.lang.Number> androidx.health.services.client.data.DebouncedGoal<T> createSampleDebouncedGoal(androidx.health.services.client.data.DebouncedDataTypeCondition<T,androidx.health.services.client.data.DeltaDataType<T,androidx.health.services.client.data.SampleDataPoint<T>>> condition);
-    method public androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object!> getDebouncedDataTypeCondition();
-    property public final androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object!> debouncedDataTypeCondition;
+    method public androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object?> getDebouncedDataTypeCondition();
+    property public final androidx.health.services.client.data.DebouncedDataTypeCondition<T,? extends java.lang.Object?> debouncedDataTypeCondition;
     field public static final androidx.health.services.client.data.DebouncedGoal.Companion Companion;
   }
 
@@ -380,20 +380,20 @@
   }
 
   public final class ExerciseConfig {
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes);
-    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes, optional java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> debouncedGoals);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes);
+    ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig, optional java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides, optional java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes, optional java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> debouncedGoals);
     method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
     method public java.util.Set<androidx.health.services.client.data.BatchingMode> getBatchingModeOverrides();
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getDataTypes();
-    method public java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> getDebouncedGoals();
-    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> getExerciseEventTypes();
-    method public java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> getExerciseGoals();
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getDataTypes();
+    method public java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> getDebouncedGoals();
+    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> getExerciseEventTypes();
+    method public java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> getExerciseGoals();
     method public android.os.Bundle getExerciseParams();
     method public androidx.health.services.client.data.ExerciseType getExerciseType();
     method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
@@ -401,10 +401,10 @@
     method public boolean isAutoPauseAndResumeEnabled();
     method public boolean isGpsEnabled();
     property public final java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides;
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes;
-    property public final java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> debouncedGoals;
-    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes;
-    property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes;
+    property public final java.util.List<androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> debouncedGoals;
+    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes;
+    property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals;
     property public final android.os.Bundle exerciseParams;
     property public final androidx.health.services.client.data.ExerciseType exerciseType;
     property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
@@ -419,10 +419,10 @@
     ctor public ExerciseConfig.Builder(androidx.health.services.client.data.ExerciseType exerciseType);
     method public androidx.health.services.client.data.ExerciseConfig build();
     method public androidx.health.services.client.data.ExerciseConfig.Builder setBatchingModeOverrides(java.util.Set<androidx.health.services.client.data.BatchingMode> batchingModeOverrides);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setDebouncedGoals(java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object!>> debouncedGoals);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseEventTypes(java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> exerciseEventTypes);
-    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> exerciseGoals);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setDebouncedGoals(java.util.List<? extends androidx.health.services.client.data.DebouncedGoal<? extends java.lang.Object?>> debouncedGoals);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseEventTypes(java.util.Set<? extends androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> exerciseEventTypes);
+    method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> exerciseGoals);
     method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
     method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
     method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
@@ -462,25 +462,25 @@
   }
 
   public final class ExerciseGoal<T extends java.lang.Number> implements android.os.Parcelable {
-    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition, T period);
+    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition, T period);
     method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestoneGoalWithUpdatedThreshold(androidx.health.services.client.data.ExerciseGoal<T> goal, T newThreshold);
-    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition);
+    method public static <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition);
     method public int describeContents();
-    method public androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> getDataTypeCondition();
+    method public androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> getDataTypeCondition();
     method public androidx.health.services.client.data.ExerciseGoalType getExerciseGoalType();
     method public T? getPeriod();
     method public void writeToParcel(android.os.Parcel dest, int flags);
-    property public final androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> dataTypeCondition;
+    property public final androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> dataTypeCondition;
     property public final androidx.health.services.client.data.ExerciseGoalType exerciseGoalType;
     property public final T? period;
-    field public static final android.os.Parcelable.Creator<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object!>> CREATOR;
+    field public static final android.os.Parcelable.Creator<androidx.health.services.client.data.ExerciseGoal<? extends java.lang.Object?>> CREATOR;
     field public static final androidx.health.services.client.data.ExerciseGoal.Companion Companion;
   }
 
   public static final class ExerciseGoal.Companion {
-    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition, T period);
+    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestone(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition, T period);
     method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createMilestoneGoalWithUpdatedThreshold(androidx.health.services.client.data.ExerciseGoal<T> goal, T newThreshold);
-    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object!>> condition);
+    method public <T extends java.lang.Number> androidx.health.services.client.data.ExerciseGoal<T> createOneTimeGoal(androidx.health.services.client.data.DataTypeCondition<T,androidx.health.services.client.data.AggregateDataType<T,? extends java.lang.Object?>> condition);
   }
 
   public final class ExerciseGoalType {
@@ -663,21 +663,21 @@
   }
 
   public final class ExerciseTypeCapabilities {
-    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume);
-    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities);
-    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities, optional java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals);
+    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume);
+    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities);
+    ctor public ExerciseTypeCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals, java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones, boolean supportsAutoPauseAndResume, optional java.util.Map<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>,? extends androidx.health.services.client.data.ExerciseEventCapabilities> exerciseEventCapabilities, optional java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,? extends java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals);
     method public <C extends androidx.health.services.client.data.ExerciseEventCapabilities> C? getExerciseEventCapabilityDetails(androidx.health.services.client.data.ExerciseEventType<C> exerciseEventType);
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypes();
-    method public java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedDebouncedGoals();
-    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> getSupportedExerciseEvents();
-    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedGoals();
-    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedMilestones();
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypes();
+    method public java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedDebouncedGoals();
+    method public java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> getSupportedExerciseEvents();
+    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedGoals();
+    method public java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> getSupportedMilestones();
     method public boolean getSupportsAutoPauseAndResume();
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypes;
-    property public final java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals;
-    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object!>> supportedExerciseEvents;
-    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals;
-    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object!,? extends java.lang.Object!>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypes;
+    property public final java.util.Map<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedDebouncedGoals;
+    property public final java.util.Set<androidx.health.services.client.data.ExerciseEventType<? extends java.lang.Object?>> supportedExerciseEvents;
+    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedGoals;
+    property public final java.util.Map<androidx.health.services.client.data.AggregateDataType<? extends java.lang.Object?,? extends java.lang.Object?>,java.util.Set<androidx.health.services.client.data.ComparisonType>> supportedMilestones;
     property public final boolean supportsAutoPauseAndResume;
   }
 
@@ -689,8 +689,8 @@
   }
 
   public final class ExerciseUpdate {
-    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object!> dataPoint);
-    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object!> dataPoint);
+    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<? extends java.lang.Object?> dataPoint);
+    method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<? extends java.lang.Object?> dataPoint);
     method public androidx.health.services.client.data.ExerciseUpdate.ActiveDurationCheckpoint? getActiveDurationCheckpoint();
     method public androidx.health.services.client.data.ExerciseConfig? getExerciseConfig();
     method public androidx.health.services.client.data.ExerciseStateInfo getExerciseStateInfo();
@@ -878,9 +878,9 @@
   }
 
   public final class MeasureCapabilities {
-    ctor public MeasureCapabilities(java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesMeasure);
-    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypesMeasure();
-    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesMeasure;
+    ctor public MeasureCapabilities(java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesMeasure);
+    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypesMeasure();
+    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesMeasure;
   }
 
   public final class MilestoneMarkerSummary {
@@ -898,9 +898,9 @@
   }
 
   public final class PassiveGoal {
-    ctor public PassiveGoal(androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object!>> dataTypeCondition);
-    method public androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object!>> getDataTypeCondition();
-    property public final androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object!>> dataTypeCondition;
+    ctor public PassiveGoal(androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object?>> dataTypeCondition);
+    method public androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object?>> getDataTypeCondition();
+    property public final androidx.health.services.client.data.DataTypeCondition<? extends java.lang.Number,? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Number,? extends java.lang.Object?>> dataTypeCondition;
   }
 
   public final class PassiveListenerConfig {
@@ -921,7 +921,7 @@
     ctor public PassiveListenerConfig.Builder();
     method public androidx.health.services.client.data.PassiveListenerConfig build();
     method public androidx.health.services.client.data.PassiveListenerConfig.Builder setDailyGoals(java.util.Set<androidx.health.services.client.data.PassiveGoal> dailyGoals);
-    method public androidx.health.services.client.data.PassiveListenerConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes);
+    method public androidx.health.services.client.data.PassiveListenerConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes);
     method public androidx.health.services.client.data.PassiveListenerConfig.Builder setHealthEventTypes(java.util.Set<androidx.health.services.client.data.HealthEvent.Type> healthEventTypes);
     method public androidx.health.services.client.data.PassiveListenerConfig.Builder setShouldUserActivityInfoBeRequested(boolean shouldUserActivityInfoBeRequested);
   }
@@ -931,13 +931,13 @@
   }
 
   public final class PassiveMonitoringCapabilities {
-    ctor public PassiveMonitoringCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveMonitoring, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveGoals, java.util.Set<androidx.health.services.client.data.HealthEvent.Type> supportedHealthEventTypes, java.util.Set<androidx.health.services.client.data.UserActivityState> supportedUserActivityStates);
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypesPassiveGoals();
-    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> getSupportedDataTypesPassiveMonitoring();
+    ctor public PassiveMonitoringCapabilities(java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveMonitoring, java.util.Set<? extends androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveGoals, java.util.Set<androidx.health.services.client.data.HealthEvent.Type> supportedHealthEventTypes, java.util.Set<androidx.health.services.client.data.UserActivityState> supportedUserActivityStates);
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypesPassiveGoals();
+    method public java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> getSupportedDataTypesPassiveMonitoring();
     method public java.util.Set<androidx.health.services.client.data.HealthEvent.Type> getSupportedHealthEventTypes();
     method public java.util.Set<androidx.health.services.client.data.UserActivityState> getSupportedUserActivityStates();
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveGoals;
-    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object!,? extends java.lang.Object!>> supportedDataTypesPassiveMonitoring;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveGoals;
+    property public final java.util.Set<androidx.health.services.client.data.DataType<? extends java.lang.Object?,? extends java.lang.Object?>> supportedDataTypesPassiveMonitoring;
     property public final java.util.Set<androidx.health.services.client.data.HealthEvent.Type> supportedHealthEventTypes;
     property public final java.util.Set<androidx.health.services.client.data.UserActivityState> supportedUserActivityStates;
   }
@@ -1022,10 +1022,10 @@
   }
 
   public final class WarmUpConfig {
-    ctor public WarmUpConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes);
-    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> getDataTypes();
+    ctor public WarmUpConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes);
+    method public java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> getDataTypes();
     method public androidx.health.services.client.data.ExerciseType getExerciseType();
-    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object!,? extends java.lang.Object!>> dataTypes;
+    property public final java.util.Set<androidx.health.services.client.data.DeltaDataType<? extends java.lang.Object?,? extends java.lang.Object?>> dataTypes;
     property public final androidx.health.services.client.data.ExerciseType exerciseType;
   }
 
diff --git a/kruth/kruth/api/current.txt b/kruth/kruth/api/current.txt
index 15c2676..717aa87 100644
--- a/kruth/kruth/api/current.txt
+++ b/kruth/kruth/api/current.txt
@@ -13,8 +13,8 @@
     method public void isTrue();
   }
 
-  public final class ClassSubject extends androidx.kruth.Subject<java.lang.Class<? extends java.lang.Object!>> {
-    method public void isAssignableTo(Class<? extends java.lang.Object!> clazz);
+  public final class ClassSubject extends androidx.kruth.Subject<java.lang.Class<? extends java.lang.Object?>> {
+    method public void isAssignableTo(Class<? extends java.lang.Object?> clazz);
   }
 
   public class ComparableSubject<T extends java.lang.Comparable<? super T>> extends androidx.kruth.Subject<T> {
@@ -139,29 +139,29 @@
   public class IterableSubject<T> extends androidx.kruth.Subject<java.lang.Iterable<? extends T>> {
     ctor protected IterableSubject(androidx.kruth.FailureMetadata metadata, Iterable<? extends T>? actual);
     method public final void contains(Object? element);
-    method public final void containsAnyIn(Iterable<? extends java.lang.Object!>? expected);
+    method public final void containsAnyIn(Iterable<? extends java.lang.Object?>? expected);
     method public final void containsAnyIn(Object?[]? expected);
     method public final void containsAnyOf(Object? first, Object? second, java.lang.Object?... rest);
     method public final androidx.kruth.Ordered containsAtLeast(Object? firstExpected, Object? secondExpected, java.lang.Object?... restOfExpected);
-    method public final androidx.kruth.Ordered containsAtLeastElementsIn(Iterable<? extends java.lang.Object!>? expected);
+    method public final androidx.kruth.Ordered containsAtLeastElementsIn(Iterable<? extends java.lang.Object?>? expected);
     method public final androidx.kruth.Ordered containsAtLeastElementsIn(Object?[]? expected);
     method public final androidx.kruth.Ordered containsExactly(java.lang.Object?... expected);
-    method public final androidx.kruth.Ordered containsExactlyElementsIn(Iterable<? extends java.lang.Object!>? required);
+    method public final androidx.kruth.Ordered containsExactlyElementsIn(Iterable<? extends java.lang.Object?>? required);
     method public final androidx.kruth.Ordered containsExactlyElementsIn(Object?[]? expected);
     method public final void containsNoDuplicates();
-    method public final void containsNoneIn(Iterable<? extends java.lang.Object!>? excluded);
+    method public final void containsNoneIn(Iterable<? extends java.lang.Object?>? excluded);
     method public final void containsNoneIn(Object?[]? excluded);
     method public final void containsNoneOf(Object? firstExcluded, Object? secondExcluded, java.lang.Object?... restOfExcluded);
     method public final void doesNotContain(Object? element);
     method public final void hasSize(int expectedSize);
     method public final void isEmpty();
     method public void isInOrder();
-    method public final void isInOrder(java.util.Comparator<? extends java.lang.Object!>? comparator);
+    method public final void isInOrder(java.util.Comparator<? extends java.lang.Object?>? comparator);
     method public void isInStrictOrder();
-    method public final void isInStrictOrder(java.util.Comparator<? extends java.lang.Object!>? comparator);
+    method public final void isInStrictOrder(java.util.Comparator<? extends java.lang.Object?>? comparator);
     method @Deprecated public void isNoneOf(Object? first, Object? second, java.lang.Object?... rest);
     method public final void isNotEmpty();
-    method @Deprecated public void isNotIn(Iterable<? extends java.lang.Object!>? iterable);
+    method @Deprecated public void isNotIn(Iterable<? extends java.lang.Object?>? iterable);
   }
 
   public final class Kruth {
@@ -202,7 +202,7 @@
     method public static <K, V> androidx.kruth.MultimapSubject<K,V> assertThat(com.google.common.collect.Multimap<K,V> actual);
     method public static <T> androidx.kruth.MultisetSubject<T> assertThat(com.google.common.collect.Multiset<T> actual);
     method public static <R, C, V> androidx.kruth.TableSubject<R,C,V> assertThat(com.google.common.collect.Table<R,C,V> actual);
-    method public static androidx.kruth.ClassSubject assertThat(Class<? extends java.lang.Object!> actual);
+    method public static androidx.kruth.ClassSubject assertThat(Class<? extends java.lang.Object?> actual);
     method public static androidx.kruth.BigDecimalSubject assertThat(java.math.BigDecimal actual);
   }
 
@@ -236,12 +236,12 @@
   }
 
   public class MultimapSubject<K, V> extends androidx.kruth.Subject<com.google.common.collect.Multimap<K,V>> {
-    method public final androidx.kruth.Ordered containsAtLeast(kotlin.Pair<? extends K,? extends java.lang.Object!>... entries);
-    method public final androidx.kruth.Ordered containsAtLeastEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object!>? expectedMultimap);
+    method public final androidx.kruth.Ordered containsAtLeast(kotlin.Pair<? extends K,? extends java.lang.Object?>... entries);
+    method public final androidx.kruth.Ordered containsAtLeastEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object?>? expectedMultimap);
     method public final void containsEntry(K key, Object? value);
     method public final androidx.kruth.Ordered containsExactly();
-    method public final androidx.kruth.Ordered containsExactly(kotlin.Pair<? extends K,? extends java.lang.Object!>... entries);
-    method public final androidx.kruth.Ordered containsExactlyEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object!>? expectedMultimap);
+    method public final androidx.kruth.Ordered containsExactly(kotlin.Pair<? extends K,? extends java.lang.Object?>... entries);
+    method public final androidx.kruth.Ordered containsExactlyEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object?>? expectedMultimap);
     method public final void containsKey(K key);
     method public final void doesNotContainEntry(K key, Object? value);
     method public final void doesNotContainKey(K key);
@@ -256,7 +256,7 @@
   }
 
   public final class ObjectArraySubject<T> extends androidx.kruth.Subject<T[]> {
-    method public androidx.kruth.IterableSubject<? extends java.lang.Object!> asList();
+    method public androidx.kruth.IterableSubject<? extends java.lang.Object?> asList();
     method public void hasLength(int length);
     method public void isEmpty();
     method public void isNotEmpty();
@@ -401,11 +401,11 @@
     method protected final androidx.kruth.StandardSubjectBuilder ignoreCheck();
     method public void isAnyOf(Object? first, Object? second, java.lang.Object?... rest);
     method public void isEqualTo(Object? expected);
-    method public void isIn(Iterable<? extends java.lang.Object!>? iterable);
+    method public void isIn(Iterable<? extends java.lang.Object?>? iterable);
     method public inline <reified V> void isInstanceOf();
     method public void isNoneOf(Object? first, Object? second, java.lang.Object?... rest);
     method public void isNotEqualTo(Object? unexpected);
-    method public void isNotIn(Iterable<? extends java.lang.Object!>? iterable);
+    method public void isNotIn(Iterable<? extends java.lang.Object?>? iterable);
     method public inline <reified V> void isNotInstanceOf();
     method public void isNotNull();
     method public void isNotSameInstanceAs(Object? unexpected);
diff --git a/kruth/kruth/api/restricted_current.txt b/kruth/kruth/api/restricted_current.txt
index 95d5a97..204fee0 100644
--- a/kruth/kruth/api/restricted_current.txt
+++ b/kruth/kruth/api/restricted_current.txt
@@ -13,8 +13,8 @@
     method public void isTrue();
   }
 
-  public final class ClassSubject extends androidx.kruth.Subject<java.lang.Class<? extends java.lang.Object!>> {
-    method public void isAssignableTo(Class<? extends java.lang.Object!> clazz);
+  public final class ClassSubject extends androidx.kruth.Subject<java.lang.Class<? extends java.lang.Object?>> {
+    method public void isAssignableTo(Class<? extends java.lang.Object?> clazz);
   }
 
   public class ComparableSubject<T extends java.lang.Comparable<? super T>> extends androidx.kruth.Subject<T> {
@@ -139,29 +139,29 @@
   public class IterableSubject<T> extends androidx.kruth.Subject<java.lang.Iterable<? extends T>> {
     ctor protected IterableSubject(androidx.kruth.FailureMetadata metadata, Iterable<? extends T>? actual);
     method public final void contains(Object? element);
-    method public final void containsAnyIn(Iterable<? extends java.lang.Object!>? expected);
+    method public final void containsAnyIn(Iterable<? extends java.lang.Object?>? expected);
     method public final void containsAnyIn(Object?[]? expected);
     method public final void containsAnyOf(Object? first, Object? second, java.lang.Object?... rest);
     method public final androidx.kruth.Ordered containsAtLeast(Object? firstExpected, Object? secondExpected, java.lang.Object?... restOfExpected);
-    method public final androidx.kruth.Ordered containsAtLeastElementsIn(Iterable<? extends java.lang.Object!>? expected);
+    method public final androidx.kruth.Ordered containsAtLeastElementsIn(Iterable<? extends java.lang.Object?>? expected);
     method public final androidx.kruth.Ordered containsAtLeastElementsIn(Object?[]? expected);
     method public final androidx.kruth.Ordered containsExactly(java.lang.Object?... expected);
-    method public final androidx.kruth.Ordered containsExactlyElementsIn(Iterable<? extends java.lang.Object!>? required);
+    method public final androidx.kruth.Ordered containsExactlyElementsIn(Iterable<? extends java.lang.Object?>? required);
     method public final androidx.kruth.Ordered containsExactlyElementsIn(Object?[]? expected);
     method public final void containsNoDuplicates();
-    method public final void containsNoneIn(Iterable<? extends java.lang.Object!>? excluded);
+    method public final void containsNoneIn(Iterable<? extends java.lang.Object?>? excluded);
     method public final void containsNoneIn(Object?[]? excluded);
     method public final void containsNoneOf(Object? firstExcluded, Object? secondExcluded, java.lang.Object?... restOfExcluded);
     method public final void doesNotContain(Object? element);
     method public final void hasSize(int expectedSize);
     method public final void isEmpty();
     method public void isInOrder();
-    method public final void isInOrder(java.util.Comparator<? extends java.lang.Object!>? comparator);
+    method public final void isInOrder(java.util.Comparator<? extends java.lang.Object?>? comparator);
     method public void isInStrictOrder();
-    method public final void isInStrictOrder(java.util.Comparator<? extends java.lang.Object!>? comparator);
+    method public final void isInStrictOrder(java.util.Comparator<? extends java.lang.Object?>? comparator);
     method @Deprecated public void isNoneOf(Object? first, Object? second, java.lang.Object?... rest);
     method public final void isNotEmpty();
-    method @Deprecated public void isNotIn(Iterable<? extends java.lang.Object!>? iterable);
+    method @Deprecated public void isNotIn(Iterable<? extends java.lang.Object?>? iterable);
   }
 
   public final class Kruth {
@@ -202,7 +202,7 @@
     method public static <K, V> androidx.kruth.MultimapSubject<K,V> assertThat(com.google.common.collect.Multimap<K,V> actual);
     method public static <T> androidx.kruth.MultisetSubject<T> assertThat(com.google.common.collect.Multiset<T> actual);
     method public static <R, C, V> androidx.kruth.TableSubject<R,C,V> assertThat(com.google.common.collect.Table<R,C,V> actual);
-    method public static androidx.kruth.ClassSubject assertThat(Class<? extends java.lang.Object!> actual);
+    method public static androidx.kruth.ClassSubject assertThat(Class<? extends java.lang.Object?> actual);
     method public static androidx.kruth.BigDecimalSubject assertThat(java.math.BigDecimal actual);
   }
 
@@ -236,12 +236,12 @@
   }
 
   public class MultimapSubject<K, V> extends androidx.kruth.Subject<com.google.common.collect.Multimap<K,V>> {
-    method public final androidx.kruth.Ordered containsAtLeast(kotlin.Pair<? extends K,? extends java.lang.Object!>... entries);
-    method public final androidx.kruth.Ordered containsAtLeastEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object!>? expectedMultimap);
+    method public final androidx.kruth.Ordered containsAtLeast(kotlin.Pair<? extends K,? extends java.lang.Object?>... entries);
+    method public final androidx.kruth.Ordered containsAtLeastEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object?>? expectedMultimap);
     method public final void containsEntry(K key, Object? value);
     method public final androidx.kruth.Ordered containsExactly();
-    method public final androidx.kruth.Ordered containsExactly(kotlin.Pair<? extends K,? extends java.lang.Object!>... entries);
-    method public final androidx.kruth.Ordered containsExactlyEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object!>? expectedMultimap);
+    method public final androidx.kruth.Ordered containsExactly(kotlin.Pair<? extends K,? extends java.lang.Object?>... entries);
+    method public final androidx.kruth.Ordered containsExactlyEntriesIn(com.google.common.collect.Multimap<K,? extends java.lang.Object?>? expectedMultimap);
     method public final void containsKey(K key);
     method public final void doesNotContainEntry(K key, Object? value);
     method public final void doesNotContainKey(K key);
@@ -256,7 +256,7 @@
   }
 
   public final class ObjectArraySubject<T> extends androidx.kruth.Subject<T[]> {
-    method public androidx.kruth.IterableSubject<? extends java.lang.Object!> asList();
+    method public androidx.kruth.IterableSubject<? extends java.lang.Object?> asList();
     method public void hasLength(int length);
     method public void isEmpty();
     method public void isNotEmpty();
@@ -402,11 +402,11 @@
     method protected final androidx.kruth.StandardSubjectBuilder ignoreCheck();
     method public void isAnyOf(Object? first, Object? second, java.lang.Object?... rest);
     method public void isEqualTo(Object? expected);
-    method public void isIn(Iterable<? extends java.lang.Object!>? iterable);
+    method public void isIn(Iterable<? extends java.lang.Object?>? iterable);
     method public inline <reified V> void isInstanceOf();
     method public void isNoneOf(Object? first, Object? second, java.lang.Object?... rest);
     method public void isNotEqualTo(Object? unexpected);
-    method public void isNotIn(Iterable<? extends java.lang.Object!>? iterable);
+    method public void isNotIn(Iterable<? extends java.lang.Object?>? iterable);
     method public inline <reified V> void isNotInstanceOf();
     method public void isNotNull();
     method public void isNotSameInstanceAs(Object? unexpected);
diff --git a/libraryversions.toml b/libraryversions.toml
index a3db872..24c971f 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -7,7 +7,7 @@
 ARCH_CORE = "2.3.0-alpha01"
 ASYNCLAYOUTINFLATER = "1.1.0-alpha02"
 AUTOFILL = "1.3.0-alpha02"
-BENCHMARK = "1.3.0-alpha05"
+BENCHMARK = "1.3.0-beta01"
 BIOMETRIC = "1.2.0-alpha06"
 BLUETOOTH = "1.0.0-alpha02"
 BROWSER = "1.9.0-alpha01"
@@ -63,7 +63,7 @@
 EXIFINTERFACE = "1.4.0-alpha01"
 FRAGMENT = "1.8.0-rc01"
 FUTURES = "1.2.0-rc01"
-GLANCE = "1.1.0-rc01"
+GLANCE = "1.2.0-alpha01"
 GLANCE_TEMPLATE = "1.0.0-alpha06"
 GLANCE_WEAR_TILES = "1.0.0-alpha06"
 GRAPHICS_CORE = "1.0.0"
diff --git a/lifecycle/lifecycle-process/api/current.txt b/lifecycle/lifecycle-process/api/current.txt
index 07d5eec..cb6ac2f 100644
--- a/lifecycle/lifecycle-process/api/current.txt
+++ b/lifecycle/lifecycle-process/api/current.txt
@@ -4,7 +4,7 @@
   public final class ProcessLifecycleInitializer implements androidx.startup.Initializer<androidx.lifecycle.LifecycleOwner> {
     ctor public ProcessLifecycleInitializer();
     method public androidx.lifecycle.LifecycleOwner create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
   public final class ProcessLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
diff --git a/lifecycle/lifecycle-process/api/restricted_current.txt b/lifecycle/lifecycle-process/api/restricted_current.txt
index 07d5eec..cb6ac2f 100644
--- a/lifecycle/lifecycle-process/api/restricted_current.txt
+++ b/lifecycle/lifecycle-process/api/restricted_current.txt
@@ -4,7 +4,7 @@
   public final class ProcessLifecycleInitializer implements androidx.startup.Initializer<androidx.lifecycle.LifecycleOwner> {
     ctor public ProcessLifecycleInitializer();
     method public androidx.lifecycle.LifecycleOwner create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
   public final class ProcessLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
diff --git a/lifecycle/lifecycle-viewmodel/api/current.txt b/lifecycle/lifecycle-viewmodel/api/current.txt
index 173f9890..df43e01 100644
--- a/lifecycle/lifecycle-viewmodel/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/current.txt
@@ -74,12 +74,12 @@
     method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass);
     method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass, androidx.lifecycle.viewmodel.CreationExtras extras);
     method public default <T extends androidx.lifecycle.ViewModel> T create(kotlin.reflect.KClass<T> modelClass, androidx.lifecycle.viewmodel.CreationExtras extras);
-    method public static androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object!>... initializers);
+    method public static androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object?>... initializers);
     field public static final androidx.lifecycle.ViewModelProvider.Factory.Companion Companion;
   }
 
   public static final class ViewModelProvider.Factory.Companion {
-    method public androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object!>... initializers);
+    method public androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object?>... initializers);
   }
 
   public static class ViewModelProvider.NewInstanceFactory implements androidx.lifecycle.ViewModelProvider.Factory {
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
index 173f9890..df43e01 100644
--- a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
@@ -74,12 +74,12 @@
     method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass);
     method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass, androidx.lifecycle.viewmodel.CreationExtras extras);
     method public default <T extends androidx.lifecycle.ViewModel> T create(kotlin.reflect.KClass<T> modelClass, androidx.lifecycle.viewmodel.CreationExtras extras);
-    method public static androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object!>... initializers);
+    method public static androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object?>... initializers);
     field public static final androidx.lifecycle.ViewModelProvider.Factory.Companion Companion;
   }
 
   public static final class ViewModelProvider.Factory.Companion {
-    method public androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object!>... initializers);
+    method public androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<? extends java.lang.Object?>... initializers);
   }
 
   public static class ViewModelProvider.NewInstanceFactory implements androidx.lifecycle.ViewModelProvider.Factory {
diff --git a/lint-checks/src/main/java/androidx/build/lint/ArrayNullnessMigration.kt b/lint-checks/src/main/java/androidx/build/lint/ArrayNullnessMigration.kt
new file mode 100644
index 0000000..7a143f2
--- /dev/null
+++ b/lint-checks/src/main/java/androidx/build/lint/ArrayNullnessMigration.kt
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.build.lint
+
+import com.android.tools.lint.client.api.UElementHandler
+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.Location
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.isKotlin
+import com.intellij.psi.PsiArrayType
+import com.intellij.psi.PsiEllipsisType
+import java.util.EnumSet
+import org.jetbrains.uast.UAnnotation
+import org.jetbrains.uast.UField
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.UParameter
+
+/**
+ * Repositions nullness annotations on arrays to facilitate migrating the nullness annotations to
+ * TYPE_USE. See the issue description in the companion object for more detail.
+ */
+class ArrayNullnessMigration : Detector(), Detector.UastScanner {
+    override fun getApplicableUastTypes() = listOf(UAnnotation::class.java)
+
+    override fun createUastHandler(context: JavaContext): UElementHandler {
+        return AnnotationChecker(context)
+    }
+
+    private inner class AnnotationChecker(val context: JavaContext) : UElementHandler() {
+        override fun visitAnnotation(node: UAnnotation) {
+            // Nullness annotations are only relevant for Java source.
+            if (isKotlin(node.lang)) return
+
+            // Verify this is a nullness annotation.
+            val annotationName = node.qualifiedName ?: return
+            if (annotationName !in nullnessAnnotations) return
+
+            // Find the type of the annotated element, and only continue if it is an array.
+            val annotated = node.uastParent ?: return
+            val type =
+                when (annotated) {
+                    is UParameter -> annotated.type
+                    is UMethod -> annotated.returnType
+                    is UField -> annotated.type
+                    else -> return
+                }
+            if (type !is PsiArrayType) return
+
+            // Determine the file location for the autofix. This is a bit complicated because it
+            // needs to avoid editing the wrong thing, like the doc comment preceding a method, but
+            // also is doing some reformatting in the area around the annotation.
+            // This is where the annotation itself is located.
+            val annotationLocation = context.getLocation(node)
+            // This is where the element being annotated is located.
+            val annotatedLocation = context.getLocation(annotated)
+            // If the annotation and annotated element aren't on the same line, that probably means
+            // the annotation is on its own line, with indentation before it. To also get rid of
+            // that indentation, start the range at the start of the annotation's line.
+            // If the annotation and annotated element are on the same line, just start at the
+            // annotation starting place to avoid including e.g. other parameters.
+            val startLocation =
+                if (annotatedLocation.start!!.sameLine(annotationLocation.start!!)) {
+                    annotationLocation.start!!
+                } else {
+                    Location.create(
+                            context.file,
+                            context.getContents()!!.toString(),
+                            annotationLocation.start!!.line
+                        )
+                        .start!!
+                }
+            val fixLocation =
+                Location.create(annotatedLocation.file, startLocation, annotatedLocation.end)
+
+            // Part 1 of the fix: remove the original annotation
+            val annotationString = node.asSourceString()
+            val removeOriginalAnnotation =
+                fix()
+                    .replace()
+                    .range(fixLocation)
+                    // In addition to the annotation, also remove any extra whitespace and trailing
+                    // new line. The reformat option unfortunately doesn't do this.
+                    .pattern("((    )*$annotationString ?\n?)")
+                    .with("")
+                    // Only remove one instance of the annotation.
+                    .repeatedly(false)
+                    .autoFix()
+                    .build()
+
+            // Vararg types are also arrays, determine which array marker is present here.
+            val arraySuffix =
+                if (type is PsiEllipsisType) {
+                    "..."
+                } else {
+                    "[]"
+                }
+            // Part 2 of the fix: add a new annotation.
+            val addNewAnnotation =
+                fix()
+                    .replace()
+                    .range(fixLocation)
+                    .text(arraySuffix)
+                    .with(" $annotationString $arraySuffix")
+                    // Only add one instance of the annotation. This will replace the first instance
+                    // of []/..., which is correct. In `String @Nullable [][]` the annotation
+                    // applies to the outer `String[][]` type, while in `String[] @Nullable []` it
+                    // applies to the inner `String[]` arrays.
+                    .repeatedly(false)
+                    .autoFix()
+                    .build()
+
+            // Combine the two elements of the fix and report.
+            val fix =
+                fix()
+                    .name("Move annotation")
+                    .composite()
+                    .add(removeOriginalAnnotation)
+                    .add(addNewAnnotation)
+                    .autoFix()
+                    .build()
+
+            val incident =
+                Incident(context)
+                    .message("Nullness annotation on array will apply to element")
+                    .issue(ISSUE)
+                    .location(context.getLocation(annotated))
+                    .scope(annotated)
+                    .fix(fix)
+            context.report(incident)
+        }
+    }
+
+    companion object {
+        val nullnessAnnotations =
+            listOf(
+                "androidx.annotation.NonNull",
+                "androidx.annotation.Nullable",
+            )
+        val ISSUE =
+            Issue.create(
+                "ArrayMigration",
+                "Migrate arrays to type-use nullness annotations",
+                """
+                    When nullness annotations do not target TYPE_USE, the following definition means
+                    that the type of `arg` is nullable:
+                        @Nullable String[] arg
+                    However, if the annotation targets TYPE_USE, it now applies to the component
+                    type of the array, meaning that `arg`'s type is an array of nullable strings.
+                    To retain the original meaning, the definition needs to be changed to this:
+                        String @Nullable [] arg
+                    This check performs that migration to enable converting nullness annotations to
+                    target TYPE_USE.
+                """,
+                Category.CORRECTNESS,
+                5,
+                Severity.ERROR,
+                Implementation(
+                    ArrayNullnessMigration::class.java,
+                    EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+                )
+            )
+    }
+}
diff --git a/lint-checks/src/test/java/androidx/build/lint/ArrayNullnessMigrationTest.kt b/lint-checks/src/test/java/androidx/build/lint/ArrayNullnessMigrationTest.kt
new file mode 100644
index 0000000..556cf75
--- /dev/null
+++ b/lint-checks/src/test/java/androidx/build/lint/ArrayNullnessMigrationTest.kt
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.build.lint
+
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestMode
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class ArrayNullnessMigrationTest :
+    AbstractLintDetectorTest(
+        useDetector = ArrayNullnessMigration(),
+        useIssues = listOf(ArrayNullnessMigration.ISSUE),
+        stubs = annotationStubs
+    ) {
+    @Test
+    fun `Nullness annotation on parameter`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.NonNull;
+                public class Foo {
+                    public void foo(@NonNull String[] arr) {}
+                }
+                """
+                    .trimIndent()
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:4: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                public void foo(@NonNull String[] arr) {}
+                                ~~~~~~~~~~~~~~~~~~~~~
+            1 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 4: Move annotation:
+            @@ -4 +4
+            -     public void foo(@NonNull String[] arr) {}
+            +     public void foo(String @NonNull [] arr) {}
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    @Test
+    fun `Nullness annotation on method return`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.Nullable;
+                public class Foo {
+                    @Nullable
+                    public String[] foo() { return null; }
+                }
+                """
+                    .trimIndent(),
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:5: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                public String[] foo() { return null; }
+                                ~~~
+            1 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 5: Move annotation:
+            @@ -4 +4
+            -     @Nullable
+            -     public String[] foo() { return null; }
+            +     public String @Nullable [] foo() { return null; }
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    @Test
+    fun `Nullness annotation on method return and parameter`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.Nullable;
+                public class Foo {
+                    @Nullable
+                    public String[] foo(@Nullable String[] arr) { return null; }
+                }
+                """
+                    .trimIndent()
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:5: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                public String[] foo(@Nullable String[] arr) { return null; }
+                                ~~~
+            src/test/pkg/Foo.java:5: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                public String[] foo(@Nullable String[] arr) { return null; }
+                                    ~~~~~~~~~~~~~~~~~~~~~~
+            2 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 5: Move annotation:
+            @@ -4 +4
+            -     @Nullable
+            -     public String[] foo(@Nullable String[] arr) { return null; }
+            +     public String @Nullable [] foo(@Nullable String[] arr) { return null; }
+            Autofix for src/test/pkg/Foo.java line 5: Move annotation:
+            @@ -5 +5
+            -     public String[] foo(@Nullable String[] arr) { return null; }
+            +     public String[] foo(String @Nullable [] arr) { return null; }
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    @Test
+    fun `Nullness annotation on field`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.Nullable;
+                public class Foo {
+                    @Nullable public String[] foo;
+                }
+                """
+                    .trimIndent()
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:4: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                @Nullable public String[] foo;
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+            1 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 4: Move annotation:
+            @@ -4 +4
+            -     @Nullable public String[] foo;
+            +     public String @Nullable [] foo;
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    @Test
+    fun `Nullness annotation on 2d array`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.Nullable;
+                public class Foo {
+                    @Nullable public String[][] foo;
+                }
+                """
+                    .trimIndent()
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:4: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                @Nullable public String[][] foo;
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+            1 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 4: Move annotation:
+            @@ -4 +4
+            -     @Nullable public String[][] foo;
+            +     public String @Nullable [][] foo;
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    @Test
+    fun `Nullness annotation on varargs`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.NonNull;
+                public class Foo {
+                    public void foo(@NonNull String... arr) {}
+                }
+                """
+                    .trimIndent(),
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:4: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                public void foo(@NonNull String... arr) {}
+                                ~~~~~~~~~~~~~~~~~~~~~~
+            1 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 4: Move annotation:
+            @@ -4 +4
+            -     public void foo(@NonNull String... arr) {}
+            +     public void foo(String @NonNull ... arr) {}
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    @Test
+    fun `Nullness annotation on method return with array in comments`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.Nullable;
+                public class Foo {
+                   /**
+                    * @return A String[]
+                    */
+                    @Nullable
+                    public String[] foo() { return null; }
+                }
+                """
+                    .trimIndent(),
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:8: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                public String[] foo() { return null; }
+                                ~~~
+            1 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 8: Move annotation:
+            @@ -7 +7
+            -     @Nullable
+            -     public String[] foo() { return null; }
+            +     public String @Nullable [] foo() { return null; }
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    @Test
+    fun `Nullness annotation on method return with annotation in comments`() {
+        val input =
+            java(
+                """
+                package test.pkg;
+                import androidx.annotation.Nullable;
+                public class Foo {
+                   /**
+                    * @return A @Nullable string array
+                    */
+                    @Nullable
+                    public String[] foo() { return null; }
+                }
+                """
+                    .trimIndent(),
+            )
+
+        val expected =
+            """
+            src/test/pkg/Foo.java:8: Error: Nullness annotation on array will apply to element [ArrayMigration]
+                public String[] foo() { return null; }
+                                ~~~
+            1 errors, 0 warnings
+            """
+                .trimIndent()
+
+        val expectedFixDiffs =
+            """
+            Autofix for src/test/pkg/Foo.java line 8: Move annotation:
+            @@ -7 +7
+            -     @Nullable
+            -     public String[] foo() { return null; }
+            +     public String @Nullable [] foo() { return null; }
+            """
+                .trimIndent()
+
+        runArrayNullnessTest(input, expected, expectedFixDiffs)
+    }
+
+    private fun runArrayNullnessTest(input: TestFile, expected: String, expectedFixDiffs: String) {
+        lint()
+            .files(*stubs, input)
+            .skipTestModes(TestMode.WHITESPACE)
+            .run()
+            .expect(expected)
+            .expectFixDiffs(expectedFixDiffs)
+    }
+
+    companion object {
+        val annotationStubs =
+            arrayOf(
+                kotlin(
+                    """
+                        package androidx.annotation
+                        annotation class NonNull
+                    """
+                ),
+                kotlin(
+                    """
+                        package androidx.annotation
+                        annotation class Nullable
+                    """
+                )
+            )
+    }
+}
diff --git a/navigation/navigation-common/api/2.8.0-beta03.txt b/navigation/navigation-common/api/2.8.0-beta03.txt
index dd8a43b..bb6ad19 100644
--- a/navigation/navigation-common/api/2.8.0-beta03.txt
+++ b/navigation/navigation-common/api/2.8.0-beta03.txt
@@ -107,13 +107,13 @@
     method public androidx.navigation.NavArgument build();
     method public Object? getDefaultValue();
     method public boolean getNullable();
-    method public androidx.navigation.NavType<? extends java.lang.Object!> getType();
+    method public androidx.navigation.NavType<? extends java.lang.Object?> getType();
     method public void setDefaultValue(Object?);
     method public void setNullable(boolean);
-    method public void setType(androidx.navigation.NavType<? extends java.lang.Object!>);
+    method public void setType(androidx.navigation.NavType<? extends java.lang.Object?>);
     property public final Object? defaultValue;
     property public final boolean nullable;
-    property public final androidx.navigation.NavType<? extends java.lang.Object!> type;
+    property public final androidx.navigation.NavType<? extends java.lang.Object?> type;
   }
 
   public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
@@ -161,7 +161,7 @@
     method public androidx.navigation.NavDeepLink.Builder setAction(String action);
     method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
     method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
-    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   @kotlin.DslMarker public @interface NavDeepLinkDsl {
@@ -181,7 +181,7 @@
   }
 
   public final class NavDeepLinkDslBuilderKt {
-    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
+    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
     method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
   }
 
@@ -248,8 +248,8 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
-    method public abstract Class<? extends java.lang.Object!> value();
-    property public abstract Class<? extends java.lang.Object!> value;
+    method public abstract Class<? extends java.lang.Object?> value();
+    property public abstract Class<? extends java.lang.Object?> value;
   }
 
   public static final class NavDestination.Companion {
@@ -262,7 +262,7 @@
   @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
     ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
     ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
     method public final void argument(String name, androidx.navigation.NavArgument argument);
     method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
@@ -326,9 +326,9 @@
 
   @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
     ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public final void addDestination(androidx.navigation.NavDestination destination);
     method public androidx.navigation.NavGraph build();
     method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
@@ -339,13 +339,13 @@
 
   public final class NavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavGraphKt {
@@ -377,7 +377,7 @@
     method @Deprecated @IdRes public int getPopUpTo();
     method @IdRes public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean isPopUpToInclusive();
     method public boolean shouldLaunchSingleTop();
@@ -389,7 +389,7 @@
     property @AnimRes @AnimatorRes public final int popExitAnim;
     property @IdRes public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
   }
 
@@ -418,7 +418,7 @@
     method @Deprecated public int getPopUpTo();
     method public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean getRestoreState();
     method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
@@ -432,7 +432,7 @@
     property @Deprecated public final int popUpTo;
     property public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
     property public final boolean restoreState;
   }
@@ -446,7 +446,7 @@
 
   public abstract class NavType<T> {
     ctor public NavType(boolean isNullableAllowed);
-    method public static androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public static androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
     method public abstract operator T? get(android.os.Bundle bundle, String key);
     method public String getName();
     method public boolean isNullableAllowed();
@@ -477,7 +477,7 @@
   }
 
   public static final class NavType.Companion {
-    method public androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
   }
 
   public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
@@ -587,7 +587,7 @@
   }
 
   public final class SavedStateHandleKt {
-    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
 }
diff --git a/navigation/navigation-common/api/current.txt b/navigation/navigation-common/api/current.txt
index dd8a43b..bb6ad19 100644
--- a/navigation/navigation-common/api/current.txt
+++ b/navigation/navigation-common/api/current.txt
@@ -107,13 +107,13 @@
     method public androidx.navigation.NavArgument build();
     method public Object? getDefaultValue();
     method public boolean getNullable();
-    method public androidx.navigation.NavType<? extends java.lang.Object!> getType();
+    method public androidx.navigation.NavType<? extends java.lang.Object?> getType();
     method public void setDefaultValue(Object?);
     method public void setNullable(boolean);
-    method public void setType(androidx.navigation.NavType<? extends java.lang.Object!>);
+    method public void setType(androidx.navigation.NavType<? extends java.lang.Object?>);
     property public final Object? defaultValue;
     property public final boolean nullable;
-    property public final androidx.navigation.NavType<? extends java.lang.Object!> type;
+    property public final androidx.navigation.NavType<? extends java.lang.Object?> type;
   }
 
   public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
@@ -161,7 +161,7 @@
     method public androidx.navigation.NavDeepLink.Builder setAction(String action);
     method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
     method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
-    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   @kotlin.DslMarker public @interface NavDeepLinkDsl {
@@ -181,7 +181,7 @@
   }
 
   public final class NavDeepLinkDslBuilderKt {
-    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
+    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
     method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
   }
 
@@ -248,8 +248,8 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
-    method public abstract Class<? extends java.lang.Object!> value();
-    property public abstract Class<? extends java.lang.Object!> value;
+    method public abstract Class<? extends java.lang.Object?> value();
+    property public abstract Class<? extends java.lang.Object?> value;
   }
 
   public static final class NavDestination.Companion {
@@ -262,7 +262,7 @@
   @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
     ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
     ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
     method public final void argument(String name, androidx.navigation.NavArgument argument);
     method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
@@ -326,9 +326,9 @@
 
   @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
     ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public final void addDestination(androidx.navigation.NavDestination destination);
     method public androidx.navigation.NavGraph build();
     method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
@@ -339,13 +339,13 @@
 
   public final class NavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavGraphKt {
@@ -377,7 +377,7 @@
     method @Deprecated @IdRes public int getPopUpTo();
     method @IdRes public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean isPopUpToInclusive();
     method public boolean shouldLaunchSingleTop();
@@ -389,7 +389,7 @@
     property @AnimRes @AnimatorRes public final int popExitAnim;
     property @IdRes public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
   }
 
@@ -418,7 +418,7 @@
     method @Deprecated public int getPopUpTo();
     method public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean getRestoreState();
     method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
@@ -432,7 +432,7 @@
     property @Deprecated public final int popUpTo;
     property public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
     property public final boolean restoreState;
   }
@@ -446,7 +446,7 @@
 
   public abstract class NavType<T> {
     ctor public NavType(boolean isNullableAllowed);
-    method public static androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public static androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
     method public abstract operator T? get(android.os.Bundle bundle, String key);
     method public String getName();
     method public boolean isNullableAllowed();
@@ -477,7 +477,7 @@
   }
 
   public static final class NavType.Companion {
-    method public androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
   }
 
   public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
@@ -587,7 +587,7 @@
   }
 
   public final class SavedStateHandleKt {
-    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
 }
diff --git a/navigation/navigation-common/api/restricted_2.8.0-beta03.txt b/navigation/navigation-common/api/restricted_2.8.0-beta03.txt
index dd8a43b..bb6ad19 100644
--- a/navigation/navigation-common/api/restricted_2.8.0-beta03.txt
+++ b/navigation/navigation-common/api/restricted_2.8.0-beta03.txt
@@ -107,13 +107,13 @@
     method public androidx.navigation.NavArgument build();
     method public Object? getDefaultValue();
     method public boolean getNullable();
-    method public androidx.navigation.NavType<? extends java.lang.Object!> getType();
+    method public androidx.navigation.NavType<? extends java.lang.Object?> getType();
     method public void setDefaultValue(Object?);
     method public void setNullable(boolean);
-    method public void setType(androidx.navigation.NavType<? extends java.lang.Object!>);
+    method public void setType(androidx.navigation.NavType<? extends java.lang.Object?>);
     property public final Object? defaultValue;
     property public final boolean nullable;
-    property public final androidx.navigation.NavType<? extends java.lang.Object!> type;
+    property public final androidx.navigation.NavType<? extends java.lang.Object?> type;
   }
 
   public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
@@ -161,7 +161,7 @@
     method public androidx.navigation.NavDeepLink.Builder setAction(String action);
     method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
     method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
-    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   @kotlin.DslMarker public @interface NavDeepLinkDsl {
@@ -181,7 +181,7 @@
   }
 
   public final class NavDeepLinkDslBuilderKt {
-    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
+    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
     method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
   }
 
@@ -248,8 +248,8 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
-    method public abstract Class<? extends java.lang.Object!> value();
-    property public abstract Class<? extends java.lang.Object!> value;
+    method public abstract Class<? extends java.lang.Object?> value();
+    property public abstract Class<? extends java.lang.Object?> value;
   }
 
   public static final class NavDestination.Companion {
@@ -262,7 +262,7 @@
   @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
     ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
     ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
     method public final void argument(String name, androidx.navigation.NavArgument argument);
     method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
@@ -326,9 +326,9 @@
 
   @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
     ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public final void addDestination(androidx.navigation.NavDestination destination);
     method public androidx.navigation.NavGraph build();
     method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
@@ -339,13 +339,13 @@
 
   public final class NavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavGraphKt {
@@ -377,7 +377,7 @@
     method @Deprecated @IdRes public int getPopUpTo();
     method @IdRes public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean isPopUpToInclusive();
     method public boolean shouldLaunchSingleTop();
@@ -389,7 +389,7 @@
     property @AnimRes @AnimatorRes public final int popExitAnim;
     property @IdRes public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
   }
 
@@ -418,7 +418,7 @@
     method @Deprecated public int getPopUpTo();
     method public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean getRestoreState();
     method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
@@ -432,7 +432,7 @@
     property @Deprecated public final int popUpTo;
     property public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
     property public final boolean restoreState;
   }
@@ -446,7 +446,7 @@
 
   public abstract class NavType<T> {
     ctor public NavType(boolean isNullableAllowed);
-    method public static androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public static androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
     method public abstract operator T? get(android.os.Bundle bundle, String key);
     method public String getName();
     method public boolean isNullableAllowed();
@@ -477,7 +477,7 @@
   }
 
   public static final class NavType.Companion {
-    method public androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
   }
 
   public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
@@ -587,7 +587,7 @@
   }
 
   public final class SavedStateHandleKt {
-    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
 }
diff --git a/navigation/navigation-common/api/restricted_current.txt b/navigation/navigation-common/api/restricted_current.txt
index dd8a43b..bb6ad19 100644
--- a/navigation/navigation-common/api/restricted_current.txt
+++ b/navigation/navigation-common/api/restricted_current.txt
@@ -107,13 +107,13 @@
     method public androidx.navigation.NavArgument build();
     method public Object? getDefaultValue();
     method public boolean getNullable();
-    method public androidx.navigation.NavType<? extends java.lang.Object!> getType();
+    method public androidx.navigation.NavType<? extends java.lang.Object?> getType();
     method public void setDefaultValue(Object?);
     method public void setNullable(boolean);
-    method public void setType(androidx.navigation.NavType<? extends java.lang.Object!>);
+    method public void setType(androidx.navigation.NavType<? extends java.lang.Object?>);
     property public final Object? defaultValue;
     property public final boolean nullable;
-    property public final androidx.navigation.NavType<? extends java.lang.Object!> type;
+    property public final androidx.navigation.NavType<? extends java.lang.Object?> type;
   }
 
   public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
@@ -161,7 +161,7 @@
     method public androidx.navigation.NavDeepLink.Builder setAction(String action);
     method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
     method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
-    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public inline <reified T> androidx.navigation.NavDeepLink.Builder setUriPattern(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   @kotlin.DslMarker public @interface NavDeepLinkDsl {
@@ -181,7 +181,7 @@
   }
 
   public final class NavDeepLinkDslBuilderKt {
-    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
+    method public static inline <reified T> androidx.navigation.NavDeepLink navDeepLink(String basePath, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
     method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
   }
 
@@ -248,8 +248,8 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
-    method public abstract Class<? extends java.lang.Object!> value();
-    property public abstract Class<? extends java.lang.Object!> value;
+    method public abstract Class<? extends java.lang.Object?> value();
+    property public abstract Class<? extends java.lang.Object?> value;
   }
 
   public static final class NavDestination.Companion {
@@ -262,7 +262,7 @@
   @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
     ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
     ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
     method public final void argument(String name, androidx.navigation.NavArgument argument);
     method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
@@ -326,9 +326,9 @@
 
   @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
     ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public final void addDestination(androidx.navigation.NavDestination destination);
     method public androidx.navigation.NavGraph build();
     method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
@@ -339,13 +339,13 @@
 
   public final class NavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavGraphKt {
@@ -377,7 +377,7 @@
     method @Deprecated @IdRes public int getPopUpTo();
     method @IdRes public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean isPopUpToInclusive();
     method public boolean shouldLaunchSingleTop();
@@ -389,7 +389,7 @@
     property @AnimRes @AnimatorRes public final int popExitAnim;
     property @IdRes public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
   }
 
@@ -418,7 +418,7 @@
     method @Deprecated public int getPopUpTo();
     method public int getPopUpToId();
     method public String? getPopUpToRoute();
-    method public kotlin.reflect.KClass<? extends java.lang.Object!>? getPopUpToRouteClass();
+    method public kotlin.reflect.KClass<? extends java.lang.Object?>? getPopUpToRouteClass();
     method public Object? getPopUpToRouteObject();
     method public boolean getRestoreState();
     method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
@@ -432,7 +432,7 @@
     property @Deprecated public final int popUpTo;
     property public final int popUpToId;
     property public final String? popUpToRoute;
-    property public final kotlin.reflect.KClass<? extends java.lang.Object!>? popUpToRouteClass;
+    property public final kotlin.reflect.KClass<? extends java.lang.Object?>? popUpToRouteClass;
     property public final Object? popUpToRouteObject;
     property public final boolean restoreState;
   }
@@ -446,7 +446,7 @@
 
   public abstract class NavType<T> {
     ctor public NavType(boolean isNullableAllowed);
-    method public static androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public static androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
     method public abstract operator T? get(android.os.Bundle bundle, String key);
     method public String getName();
     method public boolean isNullableAllowed();
@@ -477,7 +477,7 @@
   }
 
   public static final class NavType.Companion {
-    method public androidx.navigation.NavType<? extends java.lang.Object!> fromArgType(String? type, String? packageName);
+    method public androidx.navigation.NavType<? extends java.lang.Object?> fromArgType(String? type, String? packageName);
   }
 
   public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
@@ -587,7 +587,7 @@
   }
 
   public final class SavedStateHandleKt {
-    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static inline <reified T> T toRoute(androidx.lifecycle.SavedStateHandle, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
 }
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
index 17d983f..8b296b4 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
@@ -25,6 +25,7 @@
 import androidx.navigation.test.booleanArgument
 import androidx.navigation.test.intArgument
 import androidx.navigation.test.intArgumentUnknownDefault
+import androidx.navigation.test.intListArgument
 import androidx.navigation.test.nullableStringArgument
 import androidx.navigation.test.nullableStringArgumentUnknownDefault
 import androidx.navigation.test.stringArgument
@@ -369,6 +370,25 @@
 
     // Ensure case when matching the exact argument query (i.e. param names in braces) is handled
     @Test
+    fun deepLinkQueryParamNullableStringCollectionArgumentMatchParamsInBraces() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse(deepLinkArgument),
+                mapOf("myarg" to stringListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        // We allow {argName} values for String types
+        assertWithMessage("Args should contain the argument")
+            .that(matchArgs?.getStringArray("myarg"))
+            .asList()
+            .containsExactly("{myarg}")
+    }
+
+    // Ensure case when matching the exact argument query (i.e. param names in braces) is handled
+    @Test
     fun deepLinkQueryParamNullableNonStringArgumentMatchParamsInBraces() {
         val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}"
         val deepLink = NavDeepLink(deepLinkArgument)
@@ -393,6 +413,47 @@
 
     // Ensure case when matching the exact argument query (i.e. param names in braces) is handled
     @Test
+    fun deepLinkQueryParamNullableNonStringCollectionArgumentMatchParamsInBraces() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+        val intArrayArg =
+            NavArgument.Builder().setType(NavType.IntArrayType).setIsNullable(true).build()
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse(deepLinkArgument),
+                mapOf("myarg" to intArrayArg)
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        // For non-strings, {argName} values are invalid and considered lack of argument value
+        // If it's a collection type, it should default to emptyList when theres no default value
+        assertWithMessage("Args should an empty collection").that(matchArgsIntArray).isEmpty()
+    }
+
+    // Ensure case when matching the exact argument query (i.e. param names in braces) is handled
+    @Test
+    fun deepLinkQueryParamNullableNonStringCollectionArgumentMatchParamsInBracesDeferToDefault() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+        val intArrayArg =
+            NavArgument.Builder()
+                .setType(NavType.IntArrayType)
+                .setIsNullable(true)
+                .setDefaultValue(intArrayOf(1, 2))
+                .build()
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse(deepLinkArgument),
+                mapOf("myarg" to intArrayArg)
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+    }
+
+    // Ensure case when matching the exact argument query (i.e. param names in braces) is handled
+    @Test
     fun deepLinkQueryParamArgumentMatchParamsInBracesSameName() {
         val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users?myarg={myarg}"
         val deepLink = NavDeepLink(deepLinkArgument)
@@ -1333,6 +1394,315 @@
     }
 
     @Test
+    fun deepLinkStringListEmpty() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg="),
+                mapOf("myarg" to stringListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsStringArray = matchArgs?.getStringArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsStringArray).isNotNull()
+        assertWithMessage("Args should contain empty string")
+            .that(matchArgsStringArray)
+            .asList()
+            .containsExactly("")
+    }
+
+    @Test
+    fun deepLinkStringListMultipleEmpty() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=&myarg="),
+                mapOf("myarg" to stringListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsStringArray = matchArgs?.getStringArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsStringArray).isNotNull()
+        assertWithMessage("Args should contain empty string")
+            .that(matchArgsStringArray)
+            .asList()
+            .containsExactly("", "")
+    }
+
+    @Test
+    fun deepLinkStringListMissing() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse(DEEP_LINK_EXACT_HTTPS),
+                mapOf("myarg" to stringListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsStringArray = matchArgs?.getStringArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsStringArray).isNotNull()
+        assertWithMessage("Args should be empty list").that(matchArgsStringArray).asList().isEmpty()
+    }
+
+    @Test
+    fun deepLinkStringListMissingDeferToDefault() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse(DEEP_LINK_EXACT_HTTPS),
+                mapOf("myarg" to stringListArgument(listOf("one", "two")))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+    }
+
+    @Test
+    fun deepLinkStringListEmptyFirstValue() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=&myarg=two&myarg=three"),
+                mapOf("myarg" to stringListArgument(listOf("default1", "default2")))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsStringArray = matchArgs?.getStringArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsStringArray).isNotNull()
+        assertWithMessage("Args should contain all values")
+            .that(matchArgsStringArray)
+            .asList()
+            .containsExactly("", "two", "three")
+            .inOrder()
+    }
+
+    @Test
+    fun deepLinkStringListEmptyMiddleValue() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=one&myarg=&myarg=three"),
+                mapOf("myarg" to stringListArgument(listOf("default1", "default2")))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsStringArray = matchArgs?.getStringArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsStringArray).isNotNull()
+        assertWithMessage("Args should contain all values")
+            .that(matchArgsStringArray)
+            .asList()
+            .containsExactly("one", "", "three")
+            .inOrder()
+    }
+
+    @Test
+    fun deepLinkStringListEmptyLastValue() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=one&myarg=two&myarg="),
+                mapOf("myarg" to stringListArgument(listOf("default1", "default2")))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsStringArray = matchArgs?.getStringArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsStringArray).isNotNull()
+        assertWithMessage("Args should contain all values")
+            .that(matchArgsStringArray)
+            .asList()
+            .containsExactly("one", "two", "")
+            .inOrder()
+    }
+
+    @Test
+    fun deepLinkStringListEmptySingleQueryParamValueOnly() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?{myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?"),
+                mapOf("myarg" to stringListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsStringArray = matchArgs?.getStringArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsStringArray).isNotNull()
+        assertWithMessage("Args should be empty list")
+            .that(matchArgsStringArray)
+            .asList()
+            .containsExactly("")
+    }
+
+    @Test
+    fun deepLinkIntListEmpty() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg="),
+                mapOf("myarg" to intListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        assertWithMessage("Args should be empty list").that(matchArgsIntArray).asList().isEmpty()
+    }
+
+    @Test
+    fun deepLinkIntListMultipleEmpty() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=&myarg="),
+                mapOf("myarg" to intListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        assertWithMessage("Args should be empty list").that(matchArgsIntArray).asList().isEmpty()
+    }
+
+    @Test
+    fun deepLinkIntListEmptyDeferToDefault() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg="),
+                mapOf("myarg" to intListArgument(listOf(1, 2)))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+    }
+
+    @Test
+    fun deepLinkIntListMissing() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse(DEEP_LINK_EXACT_HTTPS),
+                mapOf("myarg" to intListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        assertWithMessage("Args should be empty list").that(matchArgsIntArray).asList().isEmpty()
+    }
+
+    @Test
+    fun deepLinkIntListMissingDeferToDefault() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse(DEEP_LINK_EXACT_HTTPS),
+                mapOf("myarg" to intListArgument(listOf(1, 2)))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+    }
+
+    @Test
+    fun deepLinkIntListEmptyFirstValue() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=&myarg=2&myarg=3"),
+                mapOf("myarg" to intListArgument(listOf(-1, -1)))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        assertWithMessage("Args should contain non-empty values")
+            .that(matchArgsIntArray)
+            .asList()
+            .containsExactly(2, 3)
+            .inOrder()
+    }
+
+    @Test
+    fun deepLinkIntListEmptyMiddleValue() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=1&myarg=&myarg=3"),
+                mapOf("myarg" to intListArgument(listOf(-1, -1)))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        assertWithMessage("Args should contain non-empty values")
+            .that(matchArgsIntArray)
+            .asList()
+            .containsExactly(1, 3)
+            .inOrder()
+    }
+
+    @Test
+    fun deepLinkIntListEmptyLastValue() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?myarg={myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("$DEEP_LINK_EXACT_HTTPS?myarg=1&myarg=2&myarg="),
+                mapOf("myarg" to intListArgument(listOf(-1, -1)))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        assertWithMessage("Args should contain non-empty values")
+            .that(matchArgsIntArray)
+            .asList()
+            .containsExactly(1, 2)
+            .inOrder()
+    }
+
+    @Test
+    fun deepLinkIntListMissingSingleQueryParamValueOnly() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?{myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("${DEEP_LINK_EXACT_HTTPS}?"),
+                mapOf("myarg" to intListArgument())
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+        val matchArgsIntArray = matchArgs?.getIntArray("myarg")
+        assertWithMessage("Args list should not be null").that(matchArgsIntArray).isNotNull()
+        assertWithMessage("Args should be empty list").that(matchArgsIntArray).asList().isEmpty()
+    }
+
+    @Test
+    fun deepLinkIntListMissingSingleQueryParamValueOnlyDeferToDefault() {
+        val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS?{myarg}"
+        val deepLink = NavDeepLink(deepLinkArgument)
+
+        val matchArgs =
+            deepLink.getMatchingArguments(
+                Uri.parse("${DEEP_LINK_EXACT_HTTPS}?"),
+                mapOf("myarg" to intListArgument(listOf(1, 2)))
+            )
+        assertWithMessage("Args should not be null").that(matchArgs).isNotNull()
+    }
+
+    @Test
     fun deepLinkExactMatchFromKClassNoScheme() {
         @Serializable class TestClass
 
@@ -1522,7 +1892,7 @@
             deepLink.getMatchingArguments(Uri.parse("http://$route"), mapOf(argName to navArg))
         assertThat(matchArgs).isNotNull()
         assertThat(matchArgs!!.containsKey(argName)).isTrue()
-        assertThat(navArg.type[matchArgs, argName]).isNull()
+        assertThat(matchArgs.getStringArray(argName)?.toList()).isEmpty()
     }
 
     @Test
@@ -1541,7 +1911,7 @@
             deepLink.getMatchingArguments(Uri.parse("http://$route"), mapOf(argName to navArg))
         assertThat(matchArgs).isNotNull()
         assertThat(matchArgs!!.containsKey(argName)).isTrue()
-        assertThat(navArg.type[matchArgs, argName]).isNull()
+        assertThat(matchArgs.getIntArray(argName)?.toList()).isEmpty()
     }
 
     @Test
@@ -1560,7 +1930,7 @@
             deepLink.getMatchingArguments(Uri.parse("http://$route"), mapOf(argName to navArg))
         assertThat(matchArgs).isNotNull()
         assertThat(matchArgs!!.containsKey(argName)).isTrue()
-        assertThat(navArg.type[matchArgs, argName]).isNull()
+        assertThat(matchArgs.getBooleanArray(argName)?.toList()).isEmpty()
     }
 
     @Test
@@ -1579,7 +1949,7 @@
             deepLink.getMatchingArguments(Uri.parse("http://$route"), mapOf(argName to navArg))
         assertThat(matchArgs).isNotNull()
         assertThat(matchArgs!!.containsKey(argName)).isTrue()
-        assertThat(navArg.type[matchArgs, argName]).isNull()
+        assertThat(matchArgs.getLongArray(argName)?.toList()).isEmpty()
     }
 
     @Test
@@ -1598,7 +1968,7 @@
             deepLink.getMatchingArguments(Uri.parse("http://$route"), mapOf(argName to navArg))
         assertThat(matchArgs).isNotNull()
         assertThat(matchArgs!!.containsKey(argName)).isTrue()
-        assertThat(navArg.type[matchArgs, argName]).isNull()
+        assertThat(matchArgs.getFloatArray(argName)?.toList()).isEmpty()
     }
 
     @Test
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
index 33fdf94..f025d03 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
@@ -245,56 +245,6 @@
     }
 
     @Test
-    fun putAndGetNullFromBundle() {
-        val key = "key"
-        val bundle = Bundle()
-
-        NavType.IntArrayType.put(bundle, key, null)
-        assertThat(NavType.IntArrayType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.IntListType.put(bundle, key, null)
-        assertThat(NavType.IntListType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.LongArrayType.put(bundle, key, null)
-        assertThat(NavType.LongArrayType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.LongListType.put(bundle, key, null)
-        assertThat(NavType.LongListType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.FloatArrayType.put(bundle, key, null)
-        assertThat(NavType.FloatArrayType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.FloatListType.put(bundle, key, null)
-        assertThat(NavType.FloatListType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.BoolArrayType.put(bundle, key, null)
-        assertThat(NavType.BoolArrayType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.BoolListType.put(bundle, key, null)
-        assertThat(NavType.BoolListType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.StringType.put(bundle, key, null)
-        assertThat(NavType.StringType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.StringArrayType.put(bundle, key, null)
-        assertThat(NavType.StringArrayType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-
-        NavType.StringListType.put(bundle, key, null)
-        assertThat(NavType.StringListType[bundle, key]).isEqualTo(null)
-        bundle.clear()
-    }
-
-    @Test
     fun parseValueWithHex() {
         assertThat(NavType.IntType.parseValue(referenceHex)).isEqualTo(reference)
 
@@ -309,81 +259,6 @@
     }
 
     @Test
-    fun parseNull() {
-        assertThat(NavType.IntArrayType.parseValue("null")).isNull()
-        assertThat(NavType.IntListType.parseValue("null")).isNull()
-
-        assertThat(NavType.LongArrayType.parseValue("null")).isNull()
-        assertThat(NavType.LongListType.parseValue("null")).isNull()
-
-        assertThat(NavType.FloatArrayType.parseValue("null")).isNull()
-        assertThat(NavType.FloatListType.parseValue("null")).isNull()
-
-        assertThat(NavType.BoolArrayType.parseValue("null")).isNull()
-        assertThat(NavType.BoolListType.parseValue("null")).isNull()
-
-        assertThat(NavType.StringType.parseValue("null")).isNull()
-        assertThat(NavType.StringArrayType.parseValue("null")).isNull()
-        assertThat(NavType.StringListType.parseValue("null")).isNull()
-    }
-
-    @Test
-    fun parseNullConsecutive() {
-        val stringArray = NavType.StringArrayType.parseValue("null")
-        assertThat(stringArray).isNull()
-        assertThat(NavType.StringArrayType.parseValue("null", stringArray)).isNull()
-        assertThat(NavType.StringArrayType.parseValue("test", stringArray))
-            .isEqualTo(arrayOf("test"))
-
-        val stringList = NavType.StringListType.parseValue("null")
-        assertThat(stringList).isNull()
-        assertThat(NavType.StringListType.parseValue("null", stringList)).isNull()
-        assertThat(NavType.StringListType.parseValue("test", stringList)).isEqualTo(listOf("test"))
-
-        val intArray = NavType.IntArrayType.parseValue("null")
-        assertThat(intArray).isNull()
-        assertThat(NavType.IntArrayType.parseValue("null", intArray)).isNull()
-        assertThat(NavType.IntArrayType.parseValue("1", intArray)).isEqualTo(intArrayOf(1))
-
-        val intList = NavType.IntListType.parseValue("null")
-        assertThat(stringList).isNull()
-        assertThat(NavType.IntListType.parseValue("null", intList)).isNull()
-        assertThat(NavType.IntListType.parseValue("1", intList)).isEqualTo(listOf(1))
-
-        val boolArray = NavType.BoolArrayType.parseValue("null")
-        assertThat(intArray).isNull()
-        assertThat(NavType.BoolArrayType.parseValue("null", boolArray)).isNull()
-        assertThat(NavType.BoolArrayType.parseValue("true", boolArray))
-            .isEqualTo(booleanArrayOf(true))
-
-        val boolList = NavType.BoolListType.parseValue("null")
-        assertThat(stringList).isNull()
-        assertThat(NavType.BoolListType.parseValue("null", boolList)).isNull()
-        assertThat(NavType.BoolListType.parseValue("true", boolList)).isEqualTo(listOf(true))
-
-        val floatArray = NavType.FloatArrayType.parseValue("null")
-        assertThat(floatArray).isNull()
-        assertThat(NavType.FloatArrayType.parseValue("null", floatArray)).isNull()
-        assertThat(NavType.FloatArrayType.parseValue("1.0F", floatArray))
-            .isEqualTo(floatArrayOf(1.0F))
-
-        val floatList = NavType.FloatListType.parseValue("null")
-        assertThat(floatArray).isNull()
-        assertThat(NavType.FloatListType.parseValue("null", floatList)).isNull()
-        assertThat(NavType.FloatListType.parseValue("1.0F", floatList)).isEqualTo(listOf(1.0F))
-
-        val longArray = NavType.LongArrayType.parseValue("null")
-        assertThat(longArray).isNull()
-        assertThat(NavType.LongArrayType.parseValue("null", longArray)).isNull()
-        assertThat(NavType.LongArrayType.parseValue("1L", longArray)).isEqualTo(longArrayOf(1L))
-
-        val longList = NavType.LongListType.parseValue("null")
-        assertThat(longList).isNull()
-        assertThat(NavType.LongListType.parseValue("null", longList)).isNull()
-        assertThat(NavType.LongListType.parseValue("1L", longList)).isEqualTo(listOf(1L))
-    }
-
-    @Test
     fun parcelableArrayValueEquals() {
         val type = NavType.ParcelableArrayType(TestParcelable::class.java)
         val array1 = arrayOf(TestParcelable(1), TestParcelable(2))
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt
index 7ba5689..bf4495d 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt
@@ -262,7 +262,7 @@
 
         val clazz = TestClass()
         assertThatRouteFilledFrom(clazz, listOf(intArrayArgument("array")))
-            .isEqualTo("$PATH_SERIAL_NAME?array=null")
+            .isEqualTo("$PATH_SERIAL_NAME")
     }
 
     @Test
@@ -632,7 +632,7 @@
                 nullable = true
             }
 
-        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo("$PATH_SERIAL_NAME?list=null")
+        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo("$PATH_SERIAL_NAME")
     }
 
     @Test
@@ -647,7 +647,71 @@
                 nullable = true
             }
 
-        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo("$PATH_SERIAL_NAME?list=null")
+        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo(PATH_SERIAL_NAME)
+    }
+
+    @Test
+    fun emptyStringList() {
+        @Serializable @SerialName(PATH_SERIAL_NAME) class TestClass(val list: List<String>)
+
+        val clazz = TestClass(emptyList())
+
+        val listArg =
+            navArgument("list") {
+                type = NavType.StringListType
+                nullable = false
+            }
+
+        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo("$PATH_SERIAL_NAME")
+    }
+
+    @Test
+    fun emptyIntList() {
+        @Serializable @SerialName(PATH_SERIAL_NAME) class TestClass(val list: List<Int>)
+
+        val clazz = TestClass(emptyList())
+
+        val listArg =
+            navArgument("list") {
+                type = NavType.IntListType
+                nullable = false
+            }
+
+        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo("$PATH_SERIAL_NAME")
+    }
+
+    @Test
+    fun defaultEmptyStringList() {
+        @Serializable
+        @SerialName(PATH_SERIAL_NAME)
+        class TestClass(val list: List<String> = emptyList())
+
+        val clazz = TestClass()
+
+        val listArg =
+            navArgument("list") {
+                type = NavType.StringListType
+                nullable = false
+            }
+
+        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo("$PATH_SERIAL_NAME")
+    }
+
+    @Test
+    fun defaultEmptyIntList() {
+        @Serializable
+        @SerialName(PATH_SERIAL_NAME)
+        class TestClass(val list: List<Int> = emptyList())
+
+        val clazz = TestClass()
+
+        val listArg =
+            navArgument("list") {
+                type = NavType.IntListType
+                nullable = false
+            }
+
+        assertThatRouteFilledFrom(clazz, listOf(listArg)).isEqualTo("$PATH_SERIAL_NAME")
     }
 }
 
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
index e0de36f..e6c02ff 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
@@ -19,6 +19,7 @@
 import androidx.navigation.NavArgument
 import androidx.navigation.NavType.Companion.BoolType
 import androidx.navigation.NavType.Companion.FloatType
+import androidx.navigation.NavType.Companion.IntListType
 import androidx.navigation.NavType.Companion.IntType
 import androidx.navigation.NavType.Companion.LongType
 import androidx.navigation.NavType.Companion.ReferenceType
@@ -106,4 +107,29 @@
 
 // region StringListType
 fun stringListArgument() = NavArgument.Builder().setType(StringListType).setIsNullable(true).build()
+
+// endregion
+
+// region StringListType
+fun stringListArgument(defaultValue: List<String>) =
+    NavArgument.Builder()
+        .setType(StringListType)
+        .setIsNullable(true)
+        .setDefaultValue(defaultValue)
+        .build()
+
+// endregion
+
+// region IntListType
+fun intListArgument() = NavArgument.Builder().setType(IntListType).setIsNullable(true).build()
+
+// endregion
+
+// region IntListType
+fun intListArgument(defaultValue: List<Int>) =
+    NavArgument.Builder()
+        .setType(IntListType)
+        .setIsNullable(true)
+        .setDefaultValue(defaultValue)
+        .build()
 // endregion
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/CollectionNavType.kt b/navigation/navigation-common/src/main/java/androidx/navigation/CollectionNavType.kt
index 8ef7e76..a38b956 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/CollectionNavType.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/CollectionNavType.kt
@@ -16,6 +16,8 @@
 
 package androidx.navigation
 
+import android.net.Uri
+
 /**
  * A [NavType] for [Collection] such as arrays, lists, maps.
  *
@@ -37,8 +39,10 @@
      * Each element in the collection should be converted to an individual String element of the
      * returned list.
      *
+     * Note: Elements should be encoded with [Uri.encode]
+     *
      * @param value a value of this NavType
-     * @return List containing serialized String representation of [value]
+     * @return List containing encoded and serialized String representation of [value]
      */
     public abstract fun serializeAsValues(value: T): List<String>
 
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.kt
index 6f070fb..73a5823 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.kt
@@ -284,10 +284,8 @@
                     inputParams = listOf(argValue)
                 }
             }
-            if (!parseInputParams(inputParams, storedParam, bundle, arguments)) {
-                // failed to parse input parameters
-                return false
-            }
+            val parseSuccess = parseInputParams(inputParams, storedParam, bundle, arguments)
+            if (!parseSuccess) return false
         }
         // parse success
         return true
@@ -301,13 +299,23 @@
      * @param storedParam the [ParamQuery] for a single Uri.queryParameter
      */
     private fun parseInputParams(
-        inputParams: List<String>?,
+        inputParams: List<String>,
         storedParam: ParamQuery,
         bundle: Bundle,
         arguments: Map<String, NavArgument?>,
     ): Boolean {
         val tempBundle = bundleOf()
-        inputParams?.forEach { inputParam ->
+        // try to start off by adding an empty bundle if there is no default value.
+        storedParam.arguments.forEach { argName ->
+            val argument = arguments[argName]
+            val navType = argument?.type
+            // for CollectionNavType, only fallback to empty collection if there isn't a default
+            // value
+            if (navType is CollectionNavType && !argument.isDefaultValuePresent) {
+                navType.put(tempBundle, argName, navType.emptyCollection())
+            }
+        }
+        inputParams.forEach { inputParam ->
             val argMatcher =
                 storedParam.paramRegex?.let {
                     Pattern.compile(it, Pattern.DOTALL).matcher(inputParam)
@@ -327,6 +335,7 @@
                 // [firstName to "John", lastName to "Doe"]
                 val value = argMatcher.group(index + 1) ?: ""
                 val argument = arguments[argName]
+
                 try {
                     if (!tempBundle.containsKey(argName)) {
                         // Passing in a value the exact same as the placeholder will be treated the
@@ -688,6 +697,7 @@
                     "argument and the pattern provided in your URI will be used to " +
                     "parse each query parameter instance."
             }
+            // example of singleQueryParamValueOnly "www.example.com?{arg}"
             val queryParam =
                 queryParams.firstOrNull() ?: paramName.apply { isSingleQueryParamValueOnly = true }
             val matcher = FILL_IN_PATTERN.matcher(queryParam)
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt
index 0fa0203..5496a6f 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt
@@ -129,8 +129,10 @@
      * This method can be override for custom serialization implementation on types such custom
      * NavType classes.
      *
+     * Note: Final output should be encoded with [Uri.encode]
+     *
      * @param value a value representing this NavType to be serialized into a String
-     * @return serialized String value of [value]
+     * @return encoded and serialized String value of [value]
      */
     public open fun serializeAsValue(value: T): String {
         return value.toString()
@@ -397,11 +399,12 @@
                     return bundle[key] as IntArray?
                 }
 
-                override fun parseValue(value: String): IntArray? =
-                    if (value == "null") null else intArrayOf(IntType.parseValue(value))
+                override fun parseValue(value: String): IntArray {
+                    return intArrayOf(IntType.parseValue(value))
+                }
 
-                override fun parseValue(value: String, previousValue: IntArray?): IntArray? {
-                    return previousValue?.plus(IntType.parseValue(value)) ?: parseValue(value)
+                override fun parseValue(value: String, previousValue: IntArray?): IntArray {
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: IntArray?, other: IntArray?): Boolean {
@@ -436,11 +439,12 @@
                     return (bundle[key] as IntArray?)?.toList()
                 }
 
-                override fun parseValue(value: String): List<Int>? =
-                    if (value == "null") null else listOf(IntType.parseValue(value))
+                override fun parseValue(value: String): List<Int> {
+                    return listOf(IntType.parseValue(value))
+                }
 
                 override fun parseValue(value: String, previousValue: List<Int>?): List<Int>? {
-                    return previousValue?.plus(IntType.parseValue(value)) ?: parseValue(value)
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: List<Int>?, other: List<Int>?): Boolean {
@@ -514,13 +518,12 @@
                     return bundle[key] as LongArray?
                 }
 
-                override fun parseValue(value: String): LongArray? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): LongArray {
                     return longArrayOf(LongType.parseValue(value))
                 }
 
                 override fun parseValue(value: String, previousValue: LongArray?): LongArray? {
-                    return previousValue?.plus(LongType.parseValue(value)) ?: parseValue(value)
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: LongArray?, other: LongArray?): Boolean {
@@ -555,13 +558,12 @@
                     return (bundle[key] as LongArray?)?.toList()
                 }
 
-                override fun parseValue(value: String): List<Long>? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): List<Long> {
                     return listOf(LongType.parseValue(value))
                 }
 
                 override fun parseValue(value: String, previousValue: List<Long>?): List<Long>? {
-                    return previousValue?.plus(LongType.parseValue(value)) ?: parseValue(value)
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: List<Long>?, other: List<Long>?): Boolean {
@@ -623,13 +625,12 @@
                     return bundle[key] as FloatArray?
                 }
 
-                override fun parseValue(value: String): FloatArray? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): FloatArray {
                     return floatArrayOf(FloatType.parseValue(value))
                 }
 
                 override fun parseValue(value: String, previousValue: FloatArray?): FloatArray? {
-                    return previousValue?.plus(FloatType.parseValue(value)) ?: parseValue(value)
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: FloatArray?, other: FloatArray?): Boolean {
@@ -664,13 +665,12 @@
                     return (bundle[key] as FloatArray?)?.toList()
                 }
 
-                override fun parseValue(value: String): List<Float>? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): List<Float> {
                     return listOf(FloatType.parseValue(value))
                 }
 
                 override fun parseValue(value: String, previousValue: List<Float>?): List<Float>? {
-                    return previousValue?.plus(FloatType.parseValue(value)) ?: parseValue(value)
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: List<Float>?, other: List<Float>?): Boolean {
@@ -740,8 +740,7 @@
                     return bundle[key] as BooleanArray?
                 }
 
-                override fun parseValue(value: String): BooleanArray? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): BooleanArray {
                     return booleanArrayOf(BoolType.parseValue(value))
                 }
 
@@ -749,7 +748,7 @@
                     value: String,
                     previousValue: BooleanArray?
                 ): BooleanArray? {
-                    return previousValue?.plus(BoolType.parseValue(value)) ?: parseValue(value)
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: BooleanArray?, other: BooleanArray?): Boolean {
@@ -784,8 +783,7 @@
                     return (bundle[key] as BooleanArray?)?.toList()
                 }
 
-                override fun parseValue(value: String): List<Boolean>? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): List<Boolean> {
                     return listOf(BoolType.parseValue(value))
                 }
 
@@ -793,7 +791,7 @@
                     value: String,
                     previousValue: List<Boolean>?
                 ): List<Boolean>? {
-                    return previousValue?.plus(BoolType.parseValue(value)) ?: parseValue(value)
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: List<Boolean>?, other: List<Boolean>?): Boolean {
@@ -871,8 +869,7 @@
                     return bundle[key] as Array<String>?
                 }
 
-                override fun parseValue(value: String): Array<String>? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): Array<String> {
                     return arrayOf(value)
                 }
 
@@ -880,12 +877,7 @@
                     value: String,
                     previousValue: Array<String>?
                 ): Array<String>? {
-                    val newValue = parseValue(value)
-                    return when {
-                        newValue == null -> previousValue
-                        previousValue == null -> newValue
-                        else -> previousValue.plus(newValue)
-                    }
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: Array<String>?, other: Array<String>?) =
@@ -917,8 +909,7 @@
                     return (bundle[key] as Array<String>?)?.toList()
                 }
 
-                override fun parseValue(value: String): List<String>? {
-                    if (value == "null") return null
+                override fun parseValue(value: String): List<String> {
                     return listOf(value)
                 }
 
@@ -926,12 +917,7 @@
                     value: String,
                     previousValue: List<String>?
                 ): List<String>? {
-                    val newValue = parseValue(value)
-                    return when {
-                        newValue == null -> previousValue
-                        previousValue == null -> newValue
-                        else -> previousValue.plus(newValue)
-                    }
+                    return previousValue?.plus(parseValue(value)) ?: parseValue(value)
                 }
 
                 override fun valueEquals(value: List<String>?, other: List<String>?): Boolean {
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteBuilder.kt b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteBuilder.kt
index 2751ca0..d71296a 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteBuilder.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteBuilder.kt
@@ -24,177 +24,87 @@
 import kotlinx.serialization.KSerializer
 
 /** Builds navigation routes from a destination class or instance. */
-internal sealed class RouteBuilder<T> private constructor() {
-    /** DSL to construct a route pattern */
-    class Pattern<T> : RouteBuilder<T> {
+internal class RouteBuilder<T> {
+    private val serializer: KSerializer<T>
+    private val path: String
+    private var pathArgs = ""
+    private var queryArgs = ""
 
-        private val builder: Builder<T>
-
-        /**
-         * Create a builder that builds a route pattern
-         *
-         * @param serializer The serializer for destination type T (class, object etc.) to build the
-         *   route for.
-         * @param typeMap map of destination arguments' name to its respective [NavType]
-         */
-        constructor(serializer: KSerializer<T>, typeMap: Map<String, NavType<Any?>>) : super() {
-            builder = Builder(serializer, typeMap)
-        }
-
-        /**
-         * Create a builder that builds a route pattern
-         *
-         * @param path The base uri path to which arguments are appended
-         * @param serializer The serializer for destination type T (class, object etc.) to build the
-         *   route for.
-         * @param typeMap map of destination arguments' name to its respective [NavType]
-         */
-        constructor(
-            path: String,
-            serializer: KSerializer<T>,
-            typeMap: Map<String, NavType<Any?>>
-        ) : super() {
-            builder = Builder(path, serializer, typeMap)
-        }
-
-        fun addArg(elementIndex: Int) {
-            builder.apply(elementIndex) { name, _, paramType ->
-                when (paramType) {
-                    ParamType.PATH -> addPath("{$name}")
-                    ParamType.QUERY -> addQuery(name, "{$name}")
-                }
-            }
-        }
-
-        fun build(): String = builder.build()
+    /**
+     * Create a builder that builds a route URL
+     *
+     * @param serializer The serializer for destination type T (class, object etc.) to build the
+     *   route for.
+     */
+    constructor(serializer: KSerializer<T>) {
+        this.serializer = serializer
+        path = serializer.descriptor.serialName
     }
 
     /**
-     * Builds a route filled with argument values
+     * Create a builder that builds a route URL
      *
-     * @param serializer The serializer for destination instance that you need to build the route
-     *   for.
-     * @param typeMap A map of argument name to the NavArgument of all serializable fields in this
-     *   destination instance
+     * @param path The base uri path to which arguments are appended
+     * @param serializer The serializer for destination type T (class, object etc.) to build the
+     *   route for.
      */
-    class Filled<T>(serializer: KSerializer<T>, private val typeMap: Map<String, NavType<Any?>>) :
-        RouteBuilder<T>() {
-
-        private val builder = Builder(serializer, typeMap)
-        private var elementIndex = -1
-
-        /** Set index of the argument that is currently getting encoded */
-        fun setElementIndex(idx: Int) {
-            elementIndex = idx
-        }
-
-        /** Adds argument value to the url */
-        fun addArg(value: Any?) {
-            require(!(value == null || value == "null")) {
-                "Expected non-null value but got $value"
-            }
-            builder.apply(elementIndex) { name, type, paramType ->
-                val parsedValue =
-                    if (type is CollectionNavType) {
-                        type.serializeAsValues(value)
-                    } else {
-                        listOf(type.serializeAsValue(value))
-                    }
-                when (paramType) {
-                    ParamType.PATH -> {
-                        // path arguments should be a single string value of primitive types
-                        require(parsedValue.size == 1) {
-                            "Expected one value for argument $name, found ${parsedValue.size}" +
-                                "values instead."
-                        }
-                        addPath(parsedValue.first())
-                    }
-                    ParamType.QUERY -> parsedValue.forEach { addQuery(name, it) }
-                }
-            }
-        }
-
-        /** Adds null value to the url */
-        fun addNull(value: Any?) {
-            require(value == null || value == "null") { "Expected null value but got $value" }
-            builder.apply(elementIndex) { name, _, paramType ->
-                when (paramType) {
-                    ParamType.PATH -> addPath("null")
-                    ParamType.QUERY -> addQuery(name, "null")
-                }
-            }
-        }
-
-        fun build(): String = builder.build()
+    constructor(path: String, serializer: KSerializer<T>) {
+        this.serializer = serializer
+        this.path = path
     }
 
-    enum class ParamType {
+    /** Returns final route */
+    fun build() = path + pathArgs + queryArgs
+
+    /** Append string to the route's (url) path */
+    private fun addPath(path: String) {
+        pathArgs += "/$path"
+    }
+
+    /** Append string to the route's (url) query parameter */
+    private fun addQuery(name: String, value: String) {
+        val symbol = if (queryArgs.isEmpty()) "?" else "&"
+        queryArgs += "$symbol$name=$value"
+    }
+
+    fun appendPattern(index: Int, name: String, type: NavType<Any?>) {
+        val paramType = computeParamType(index, type)
+        when (paramType) {
+            ParamType.PATH -> addPath("{$name}")
+            ParamType.QUERY -> addQuery(name, "{$name}")
+        }
+    }
+
+    fun appendArg(index: Int, name: String, type: NavType<Any?>, value: List<String>) {
+        val paramType = computeParamType(index, type)
+        when (paramType) {
+            ParamType.PATH -> {
+                // path arguments should be a single string value of primitive types
+                require(value.size == 1) {
+                    "Expected one value for argument $name, found ${value.size}" + "values instead."
+                }
+                addPath(value.first())
+            }
+            ParamType.QUERY -> value.forEach { addQuery(name, it) }
+        }
+    }
+
+    /**
+     * Given the descriptor of [T], computes the [ParamType] of the element (argument) at [index].
+     *
+     * Query args if either conditions met:
+     * 1. has default value
+     * 2. is of [CollectionNavType]
+     */
+    private fun computeParamType(index: Int, type: NavType<Any?>) =
+        if (type is CollectionNavType || serializer.descriptor.isElementOptional(index)) {
+            ParamType.QUERY
+        } else {
+            ParamType.PATH
+        }
+
+    private enum class ParamType {
         PATH,
         QUERY
     }
-
-    /** Internal builder that generates the final url output */
-    private class Builder<T> {
-        private val serializer: KSerializer<T>
-        private val typeMap: Map<String, NavType<Any?>>
-        private val path: String
-        private var pathArgs = ""
-        private var queryArgs = ""
-
-        constructor(serializer: KSerializer<T>, typeMap: Map<String, NavType<Any?>>) {
-            this.serializer = serializer
-            this.typeMap = typeMap
-            path = serializer.descriptor.serialName
-        }
-
-        constructor(path: String, serializer: KSerializer<T>, typeMap: Map<String, NavType<Any?>>) {
-            this.serializer = serializer
-            this.typeMap = typeMap
-            this.path = path
-        }
-
-        /** Returns final route */
-        fun build() = path + pathArgs + queryArgs
-
-        /** Append string to the route's (url) path */
-        fun addPath(path: String) {
-            pathArgs += "/$path"
-        }
-
-        /** Append string to the route's (url) query parameter */
-        fun addQuery(name: String, value: String) {
-            val symbol = if (queryArgs.isEmpty()) "?" else "&"
-            queryArgs += "$symbol$name=$value"
-        }
-
-        fun apply(
-            index: Int,
-            block: Builder<T>.(name: String, type: NavType<Any?>, paramType: ParamType) -> Unit
-        ) {
-            val descriptor = serializer.descriptor
-            val elementName = descriptor.getElementName(index)
-            val type = typeMap[elementName]
-            checkNotNull(type) {
-                "Cannot find NavType for argument $elementName. Please provide NavType through" +
-                    "typeMap."
-            }
-            val paramType = computeParamType(index, type)
-            this.block(elementName, type, paramType)
-        }
-
-        /**
-         * Given the descriptor of [T], computes the [ParamType] of the element (argument) at
-         * [index].
-         *
-         * Query args if either conditions met:
-         * 1. has default value
-         * 2. is of [CollectionNavType]
-         */
-        private fun computeParamType(index: Int, type: NavType<Any?>) =
-            if (type is CollectionNavType || serializer.descriptor.isElementOptional(index)) {
-                ParamType.QUERY
-            } else {
-                ParamType.PATH
-            }
-    }
 }
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteEncoder.kt b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteEncoder.kt
index 42d4776..550ffbd 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteEncoder.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteEncoder.kt
@@ -16,6 +16,7 @@
 
 package androidx.navigation.serialization
 
+import androidx.navigation.CollectionNavType
 import androidx.navigation.NavType
 import kotlinx.serialization.ExperimentalSerializationApi
 import kotlinx.serialization.KSerializer
@@ -32,7 +33,8 @@
     private val typeMap: Map<String, NavType<Any?>>
 ) : AbstractEncoder() {
     override val serializersModule: SerializersModule = EmptySerializersModule()
-    private val builder = RouteBuilder.Filled(serializer, typeMap)
+    val map: MutableMap<String, List<String>> = mutableMapOf()
+    var elementIndex: Int = -1
 
     /**
      * Entry point to set up and start encoding [T].
@@ -43,9 +45,9 @@
      * to the default entry by directly calling [super.encodeSerializableValue].
      */
     @Suppress("UNCHECKED_CAST")
-    fun encodeRouteWithArgs(value: Any): String {
+    fun encodeToArgMap(value: Any): Map<String, List<String>> {
         super.encodeSerializableValue(serializer, value as T)
-        return builder.build()
+        return map
     }
 
     /**
@@ -58,16 +60,12 @@
      * String literal "null" is considered non-null value.
      */
     override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) {
-        if (value == "null") {
-            builder.addNull(value)
-        } else {
-            builder.addArg(value)
-        }
+        internalEncodeValue(value)
     }
 
     /** Essentially called for every single argument. */
     override fun encodeElement(descriptor: SerialDescriptor, index: Int): Boolean {
-        builder.setElementIndex(index)
+        elementIndex = index
         return true
     }
 
@@ -77,15 +75,24 @@
      * String literal "null" is considered non-null value.
      */
     override fun encodeValue(value: Any) {
-        if (value == "null") {
-            builder.addNull(value)
-        } else {
-            builder.addArg(value)
-        }
+        internalEncodeValue(value)
     }
 
     /** Called for primitive / non-primitives of null value */
     override fun encodeNull() {
-        builder.addNull(null)
+        internalEncodeValue(null)
+    }
+
+    private fun internalEncodeValue(value: Any?) {
+        val argName = serializer.descriptor.getElementName(elementIndex)
+        val navType = typeMap[argName]
+        checkNotNull(navType) { "MISSING NAV TYPE" }
+        val parsedValue =
+            if (navType is CollectionNavType) {
+                navType.serializeAsValues(value)
+            } else {
+                listOf(navType.serializeAsValue(value))
+            }
+        map[argName] = parsedValue
     }
 }
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteSerializer.kt b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteSerializer.kt
index a3b96bd..956c363 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteSerializer.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/RouteSerializer.kt
@@ -35,8 +35,7 @@
  * of class T where T is a concrete class or object.
  *
  * The generated route pattern contains the path, path args, and query args. See
- * [RouteBuilder.Builder.computeParamType] for logic on how parameter type (path or query) is
- * computed.
+ * [RouteBuilder.computeParamType] for logic on how parameter type (path or query) is computed.
  *
  * @param [typeMap] A mapping of KType to the custom NavType<*>. For example given an argument of
  *   "val userId: UserId", the map should contain [typeOf<UserId>() to MyNavType].
@@ -54,21 +53,14 @@
                 "concrete classes or objects."
         )
     }
-
-    val map = mutableMapOf<String, NavType<Any?>>()
-    for (i in 0 until descriptor.elementsCount) {
-        val argName = descriptor.getElementName(i)
-        val type = descriptor.getElementDescriptor(i).computeNavType(argName, typeMap)
-        map[argName] = type
-    }
     val builder =
         if (path != null) {
-            RouteBuilder.Pattern(path, this, map)
+            RouteBuilder(path, this)
         } else {
-            RouteBuilder.Pattern(this, map)
+            RouteBuilder(this)
         }
-    for (elementIndex in 0 until descriptor.elementsCount) {
-        builder.addArg(elementIndex)
+    forEachIndexed(typeMap) { index, argName, navType ->
+        builder.appendPattern(index, argName, navType)
     }
     return builder.build()
 }
@@ -127,13 +119,20 @@
  * [::navigate] from a destination instance of type T.
  *
  * The generated route pattern contains the path, path args, and query args. See
- * [RouteBuilder.Builder.computeParamType] for logic on how parameter type (path or query) is
- * computed.
+ * [RouteBuilder.computeParamType] for logic on how parameter type (path or query) is computed.
  */
 @OptIn(InternalSerializationApi::class)
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public fun <T : Any> generateRouteWithArgs(route: T, typeMap: Map<String, NavType<Any?>>): String =
-    RouteEncoder(route::class.serializer(), typeMap).encodeRouteWithArgs(route)
+public fun <T : Any> generateRouteWithArgs(route: T, typeMap: Map<String, NavType<Any?>>): String {
+    val serializer = route::class.serializer()
+    val argMap: Map<String, List<String>> = RouteEncoder(serializer, typeMap).encodeToArgMap(route)
+    val builder = RouteBuilder(serializer)
+    serializer.forEachIndexed(typeMap) { index, argName, navType ->
+        val value = argMap[argName]!!
+        builder.appendArg(index, argName, navType, value)
+    }
+    return builder.build()
+}
 
 private fun <T> KSerializer<T>.assertNotAbstractClass(handler: () -> Unit) {
     // abstract class
@@ -165,3 +164,28 @@
     }
     return result as NavType<Any?>
 }
+
+@JvmName("forEachIndexedKType")
+private fun <T> KSerializer<T>.forEachIndexed(
+    typeMap: Map<KType, NavType<*>> = emptyMap(),
+    operation: (index: Int, argName: String, navType: NavType<Any?>) -> Unit
+) {
+    for (i in 0 until descriptor.elementsCount) {
+        val argName = descriptor.getElementName(i)
+        val navType = descriptor.getElementDescriptor(i).computeNavType(argName, typeMap)
+        operation(i, argName, navType)
+    }
+}
+
+@JvmName("forEachIndexedName")
+private fun <T> KSerializer<T>.forEachIndexed(
+    typeMap: Map<String, NavType<Any?>>,
+    operation: (index: Int, argName: String, navType: NavType<Any?>) -> Unit
+) {
+    for (i in 0 until descriptor.elementsCount) {
+        val argName = descriptor.getElementName(i)
+        val navType = typeMap[argName]
+        checkNotNull(navType) { "MISSING NAV TYPE" }
+        operation(i, argName, navType)
+    }
+}
diff --git a/navigation/navigation-compose/api/2.8.0-beta03.txt b/navigation/navigation-compose/api/2.8.0-beta03.txt
index d659376..f4411f7 100644
--- a/navigation/navigation-compose/api/2.8.0-beta03.txt
+++ b/navigation/navigation-compose/api/2.8.0-beta03.txt
@@ -17,7 +17,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class ComposeNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.ComposeNavigator.Destination> {
     ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, String route, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public androidx.navigation.compose.ComposeNavigator.Destination build();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? getEnterTransition();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? getExitTransition();
@@ -52,7 +52,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class DialogNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.DialogNavigator.Destination> {
     ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, String route, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method protected androidx.navigation.compose.DialogNavigator.Destination instantiateDestination();
   }
 
@@ -64,14 +64,14 @@
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostControllerKt {
@@ -83,11 +83,11 @@
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-compose/api/current.txt b/navigation/navigation-compose/api/current.txt
index d659376..f4411f7 100644
--- a/navigation/navigation-compose/api/current.txt
+++ b/navigation/navigation-compose/api/current.txt
@@ -17,7 +17,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class ComposeNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.ComposeNavigator.Destination> {
     ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, String route, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public androidx.navigation.compose.ComposeNavigator.Destination build();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? getEnterTransition();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? getExitTransition();
@@ -52,7 +52,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class DialogNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.DialogNavigator.Destination> {
     ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, String route, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method protected androidx.navigation.compose.DialogNavigator.Destination instantiateDestination();
   }
 
@@ -64,14 +64,14 @@
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostControllerKt {
@@ -83,11 +83,11 @@
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-compose/api/restricted_2.8.0-beta03.txt b/navigation/navigation-compose/api/restricted_2.8.0-beta03.txt
index d659376..f4411f7 100644
--- a/navigation/navigation-compose/api/restricted_2.8.0-beta03.txt
+++ b/navigation/navigation-compose/api/restricted_2.8.0-beta03.txt
@@ -17,7 +17,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class ComposeNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.ComposeNavigator.Destination> {
     ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, String route, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public androidx.navigation.compose.ComposeNavigator.Destination build();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? getEnterTransition();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? getExitTransition();
@@ -52,7 +52,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class DialogNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.DialogNavigator.Destination> {
     ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, String route, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method protected androidx.navigation.compose.DialogNavigator.Destination instantiateDestination();
   }
 
@@ -64,14 +64,14 @@
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostControllerKt {
@@ -83,11 +83,11 @@
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-compose/api/restricted_current.txt b/navigation/navigation-compose/api/restricted_current.txt
index d659376..f4411f7 100644
--- a/navigation/navigation-compose/api/restricted_current.txt
+++ b/navigation/navigation-compose/api/restricted_current.txt
@@ -17,7 +17,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class ComposeNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.ComposeNavigator.Destination> {
     ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, String route, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public ComposeNavigatorDestinationBuilder(androidx.navigation.compose.ComposeNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public androidx.navigation.compose.ComposeNavigator.Destination build();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? getEnterTransition();
     method public kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? getExitTransition();
@@ -52,7 +52,7 @@
 
   @androidx.navigation.NavDestinationDsl public final class DialogNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.compose.DialogNavigator.Destination> {
     ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, String route, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public DialogNavigatorDestinationBuilder(androidx.navigation.compose.DialogNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method protected androidx.navigation.compose.DialogNavigator.Destination instantiateDestination();
   }
 
@@ -64,14 +64,14 @@
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void composable(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
     method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition?>? popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.NavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition?>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition?>? popExitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostControllerKt {
@@ -83,11 +83,11 @@
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, Object startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition> popExitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.SizeTransform?>? sizeTransform, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-dynamic-features-fragment/api/2.8.0-beta03.txt b/navigation/navigation-dynamic-features-fragment/api/2.8.0-beta03.txt
index 5c3fcc6..575de0b 100644
--- a/navigation/navigation-dynamic-features-fragment/api/2.8.0-beta03.txt
+++ b/navigation/navigation-dynamic-features-fragment/api/2.8.0-beta03.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
     ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String fragmentClassName);
+    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String fragmentClassName);
     method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
     method public String? getModuleName();
     method public void setModuleName(String?);
@@ -30,10 +30,10 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
     method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
diff --git a/navigation/navigation-dynamic-features-fragment/api/current.txt b/navigation/navigation-dynamic-features-fragment/api/current.txt
index 5c3fcc6..575de0b 100644
--- a/navigation/navigation-dynamic-features-fragment/api/current.txt
+++ b/navigation/navigation-dynamic-features-fragment/api/current.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
     ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String fragmentClassName);
+    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String fragmentClassName);
     method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
     method public String? getModuleName();
     method public void setModuleName(String?);
@@ -30,10 +30,10 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
     method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
diff --git a/navigation/navigation-dynamic-features-fragment/api/restricted_2.8.0-beta03.txt b/navigation/navigation-dynamic-features-fragment/api/restricted_2.8.0-beta03.txt
index 5c3fcc6..575de0b 100644
--- a/navigation/navigation-dynamic-features-fragment/api/restricted_2.8.0-beta03.txt
+++ b/navigation/navigation-dynamic-features-fragment/api/restricted_2.8.0-beta03.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
     ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String fragmentClassName);
+    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String fragmentClassName);
     method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
     method public String? getModuleName();
     method public void setModuleName(String?);
@@ -30,10 +30,10 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
     method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
diff --git a/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt b/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt
index 5c3fcc6..575de0b 100644
--- a/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt
+++ b/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
     ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String fragmentClassName);
+    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String fragmentClassName);
     method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
     method public String? getModuleName();
     method public void setModuleName(String?);
@@ -30,10 +30,10 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
     method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String fragmentClassName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
diff --git a/navigation/navigation-dynamic-features-runtime/api/2.8.0-beta03.txt b/navigation/navigation-dynamic-features-runtime/api/2.8.0-beta03.txt
index a5187c86..2761db9 100644
--- a/navigation/navigation-dynamic-features-runtime/api/2.8.0-beta03.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/2.8.0-beta03.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
     ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
     method public String? getAction();
     method public String? getActivityClassName();
@@ -42,7 +42,7 @@
   public final class DynamicActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
     ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
     ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String moduleName, String graphResourceName);
+    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String moduleName, String graphResourceName);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
     method public String? getGraphPackage();
     method public void setGraphPackage(String?);
@@ -103,8 +103,8 @@
     method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicInstallManager {
@@ -126,9 +126,9 @@
 
   @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
     ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public String? getModuleName();
     method public int getProgressDestination();
     method public String? getProgressDestinationRoute();
@@ -142,27 +142,27 @@
 
   public final class DynamicNavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-dynamic-features-runtime/api/current.txt b/navigation/navigation-dynamic-features-runtime/api/current.txt
index a5187c86..2761db9 100644
--- a/navigation/navigation-dynamic-features-runtime/api/current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/current.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
     ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
     method public String? getAction();
     method public String? getActivityClassName();
@@ -42,7 +42,7 @@
   public final class DynamicActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
     ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
     ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String moduleName, String graphResourceName);
+    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String moduleName, String graphResourceName);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
     method public String? getGraphPackage();
     method public void setGraphPackage(String?);
@@ -103,8 +103,8 @@
     method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicInstallManager {
@@ -126,9 +126,9 @@
 
   @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
     ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public String? getModuleName();
     method public int getProgressDestination();
     method public String? getProgressDestinationRoute();
@@ -142,27 +142,27 @@
 
   public final class DynamicNavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_2.8.0-beta03.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_2.8.0-beta03.txt
index a5187c86..2761db9 100644
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_2.8.0-beta03.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_2.8.0-beta03.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
     ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
     method public String? getAction();
     method public String? getActivityClassName();
@@ -42,7 +42,7 @@
   public final class DynamicActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
     ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
     ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String moduleName, String graphResourceName);
+    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String moduleName, String graphResourceName);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
     method public String? getGraphPackage();
     method public void setGraphPackage(String?);
@@ -103,8 +103,8 @@
     method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicInstallManager {
@@ -126,9 +126,9 @@
 
   @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
     ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public String? getModuleName();
     method public int getProgressDestination();
     method public String? getProgressDestinationRoute();
@@ -142,27 +142,27 @@
 
   public final class DynamicNavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
index a5187c86..2761db9 100644
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
@@ -17,7 +17,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
     ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
     method public String? getAction();
     method public String? getActivityClassName();
@@ -42,7 +42,7 @@
   public final class DynamicActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
     ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
     ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object!> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, String moduleName, String graphResourceName);
+    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, kotlin.reflect.KClass<? extends java.lang.Object?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, String moduleName, String graphResourceName);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
     method public String? getGraphPackage();
     method public void setGraphPackage(String?);
@@ -103,8 +103,8 @@
     method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified T> void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String moduleName, String graphResourceName, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public class DynamicInstallManager {
@@ -126,9 +126,9 @@
 
   @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
     ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, Object startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, kotlin.reflect.KClass<? extends java.lang.Object!>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, kotlin.reflect.KClass<? extends java.lang.Object?>? route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public String? getModuleName();
     method public int getProgressDestination();
     method public String? getProgressDestinationRoute();
@@ -142,27 +142,27 @@
 
   public final class DynamicNavGraphBuilderKt {
     method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, Object startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-fragment/api/2.8.0-beta03.txt b/navigation/navigation-fragment/api/2.8.0-beta03.txt
index 084f4e3..0db42b8 100644
--- a/navigation/navigation-fragment/api/2.8.0-beta03.txt
+++ b/navigation/navigation-fragment/api/2.8.0-beta03.txt
@@ -41,7 +41,7 @@
   @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
     ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
   }
 
@@ -50,8 +50,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentKt {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     method public androidx.navigation.fragment.FragmentNavigator.Destination build();
   }
 
@@ -100,8 +100,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentNavigatorExtrasKt {
diff --git a/navigation/navigation-fragment/api/current.txt b/navigation/navigation-fragment/api/current.txt
index 084f4e3..0db42b8 100644
--- a/navigation/navigation-fragment/api/current.txt
+++ b/navigation/navigation-fragment/api/current.txt
@@ -41,7 +41,7 @@
   @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
     ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
   }
 
@@ -50,8 +50,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentKt {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     method public androidx.navigation.fragment.FragmentNavigator.Destination build();
   }
 
@@ -100,8 +100,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentNavigatorExtrasKt {
diff --git a/navigation/navigation-fragment/api/restricted_2.8.0-beta03.txt b/navigation/navigation-fragment/api/restricted_2.8.0-beta03.txt
index 084f4e3..0db42b8 100644
--- a/navigation/navigation-fragment/api/restricted_2.8.0-beta03.txt
+++ b/navigation/navigation-fragment/api/restricted_2.8.0-beta03.txt
@@ -41,7 +41,7 @@
   @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
     ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
   }
 
@@ -50,8 +50,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentKt {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     method public androidx.navigation.fragment.FragmentNavigator.Destination build();
   }
 
@@ -100,8 +100,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentNavigatorExtrasKt {
diff --git a/navigation/navigation-fragment/api/restricted_current.txt b/navigation/navigation-fragment/api/restricted_current.txt
index 084f4e3..0db42b8 100644
--- a/navigation/navigation-fragment/api/restricted_current.txt
+++ b/navigation/navigation-fragment/api/restricted_current.txt
@@ -41,7 +41,7 @@
   @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
     ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
   }
 
@@ -50,8 +50,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment, reified T> void dialog(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentKt {
@@ -91,7 +91,7 @@
   @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
     ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     method public androidx.navigation.fragment.FragmentNavigator.Destination build();
   }
 
@@ -100,8 +100,8 @@
     method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
+    method public static inline <reified F extends androidx.fragment.app.Fragment, reified T> void fragment(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class FragmentNavigatorExtrasKt {
diff --git a/navigation/navigation-runtime/api/2.8.0-beta03.txt b/navigation/navigation-runtime/api/2.8.0-beta03.txt
index ece9b64..b801964 100644
--- a/navigation/navigation-runtime/api/2.8.0-beta03.txt
+++ b/navigation/navigation-runtime/api/2.8.0-beta03.txt
@@ -61,7 +61,7 @@
   @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
     ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.ActivityNavigator.Destination build();
     method public String? getAction();
     method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
@@ -83,7 +83,7 @@
   public final class ActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class ActivityNavigatorExtrasKt {
@@ -172,9 +172,9 @@
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavDeepLinkBuilder {
@@ -214,9 +214,9 @@
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavInflater {
diff --git a/navigation/navigation-runtime/api/current.txt b/navigation/navigation-runtime/api/current.txt
index ece9b64..b801964 100644
--- a/navigation/navigation-runtime/api/current.txt
+++ b/navigation/navigation-runtime/api/current.txt
@@ -61,7 +61,7 @@
   @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
     ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.ActivityNavigator.Destination build();
     method public String? getAction();
     method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
@@ -83,7 +83,7 @@
   public final class ActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class ActivityNavigatorExtrasKt {
@@ -172,9 +172,9 @@
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavDeepLinkBuilder {
@@ -214,9 +214,9 @@
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavInflater {
diff --git a/navigation/navigation-runtime/api/restricted_2.8.0-beta03.txt b/navigation/navigation-runtime/api/restricted_2.8.0-beta03.txt
index ece9b64..b801964 100644
--- a/navigation/navigation-runtime/api/restricted_2.8.0-beta03.txt
+++ b/navigation/navigation-runtime/api/restricted_2.8.0-beta03.txt
@@ -61,7 +61,7 @@
   @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
     ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.ActivityNavigator.Destination build();
     method public String? getAction();
     method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
@@ -83,7 +83,7 @@
   public final class ActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class ActivityNavigatorExtrasKt {
@@ -172,9 +172,9 @@
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavDeepLinkBuilder {
@@ -214,9 +214,9 @@
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavInflater {
diff --git a/navigation/navigation-runtime/api/restricted_current.txt b/navigation/navigation-runtime/api/restricted_current.txt
index ece9b64..b801964 100644
--- a/navigation/navigation-runtime/api/restricted_current.txt
+++ b/navigation/navigation-runtime/api/restricted_current.txt
@@ -61,7 +61,7 @@
   @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
     ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
     ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, kotlin.reflect.KClass<?> route, java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
     method public androidx.navigation.ActivityNavigator.Destination build();
     method public String? getAction();
     method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
@@ -83,7 +83,7 @@
   public final class ActivityNavigatorDestinationBuilderKt {
     method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified T> void activity(androidx.navigation.NavGraphBuilder, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
   public final class ActivityNavigatorExtrasKt {
@@ -172,9 +172,9 @@
 
   public final class NavControllerKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavDeepLinkBuilder {
@@ -214,9 +214,9 @@
 
   public final class NavHostKt {
     method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, Object startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object!> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object!>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, kotlin.reflect.KClass<? extends java.lang.Object?> startDestination, optional kotlin.reflect.KClass<? extends java.lang.Object?>? route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavInflater {
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
index c75c6be..818d220 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
@@ -3757,6 +3757,76 @@
 
     @UiThreadTest
     @Test
+    fun testNavigateWithEmptyStringList() {
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = "start") {
+                test(route = "start?arg={arg}") {
+                    argument("arg") { type = NavType.StringListType }
+                }
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("start?arg={arg}")
+        val arg = navController.currentBackStackEntry?.arguments?.getStringArray("arg")
+        assertThat(arg).isNotNull()
+        assertThat(arg).asList().isEmpty()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithEmptyStringListUseDefault() {
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = "start") {
+                test(route = "start?arg={arg}") {
+                    argument("arg") {
+                        type = NavType.StringListType
+                        defaultValue = listOf("one", "two")
+                    }
+                }
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("start?arg={arg}")
+        val arg = navController.currentBackStackEntry?.arguments?.getStringArray("arg")
+        assertThat(arg).isNotNull()
+        assertThat(arg).asList().containsExactly("one", "two")
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithEmptyIntList() {
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = "start?arg=") {
+                test(route = "start?arg={arg}") { argument("arg") { type = NavType.IntListType } }
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("start?arg={arg}")
+        val arg = navController.currentBackStackEntry?.arguments?.getIntArray("arg")
+        assertThat(arg).isNotNull()
+        assertThat(arg).asList().isEmpty()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithEmptyIntListUseDefault() {
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = "start?arg=") {
+                test(route = "start?arg={arg}") {
+                    argument("arg") {
+                        type = NavType.IntListType
+                        defaultValue = listOf(1, 2)
+                    }
+                }
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("start?arg={arg}")
+        val arg = navController.currentBackStackEntry?.arguments?.getIntArray("arg")
+        assertThat(arg).isNotNull()
+        assertThat(arg).asList().containsExactly(1, 2)
+    }
+
+    @UiThreadTest
+    @Test
     fun testNavigateWithObjectListArg() {
         @Serializable class TestClass(val arg: MutableList<Boolean>)
 
@@ -3831,11 +3901,37 @@
             navController.createGraph(startDestination = TestClass(null)) { test<TestClass>() }
         assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
         val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isEmpty()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectNullStringListUseDefaultNull() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<String>? = null)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(null)) { test<TestClass>() }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
         assertThat(route!!.arg).isNull()
     }
 
     @UiThreadTest
     @Test
+    fun testNavigateWithObjectNullStringListUseDefaultList() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<String>? = listOf("one"))
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(null)) { test<TestClass>() }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).containsExactly("one")
+    }
+
+    @UiThreadTest
+    @Test
     fun testNavigateWithObjectNullIntList() {
         @Serializable @SerialName("test") class TestClass(val arg: List<Int>?)
 
@@ -3844,11 +3940,154 @@
             navController.createGraph(startDestination = TestClass(null)) { test<TestClass>() }
         assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
         val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isEmpty()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectNullIntListUseDefault() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<Int>? = null)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(null)) { test<TestClass>() }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
         assertThat(route!!.arg).isNull()
     }
 
     @UiThreadTest
     @Test
+    fun testNavigateWithObjectEmptyStringList() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<String>)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(emptyList())) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).isEmpty()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectEmptyStringListUseDefault() {
+        @Serializable
+        @SerialName("test")
+        class TestClass(val arg: List<String> = listOf("one", "two"))
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(emptyList())) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).containsExactly("one", "two").inOrder()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectStringListEmptyString() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<String>)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(listOf(""))) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).containsExactly("")
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectStringListEmptyStringFirstValue() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<String>)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(listOf("", "two", "three"))) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).containsExactly("", "two", "three").inOrder()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectStringListEmptyStringMiddleValue() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<String>)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(listOf("one", "", "three"))) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).containsExactly("one", "", "three").inOrder()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectStringListEmptyStringLastValue() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<String>)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(listOf("one", "two", ""))) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).containsExactly("one", "two", "").inOrder()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectEmptyIntList() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<Int>)
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(emptyList())) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).isEmpty()
+    }
+
+    @UiThreadTest
+    @Test
+    fun testNavigateWithObjectEmptyIntListUseDefault() {
+        @Serializable @SerialName("test") class TestClass(val arg: List<Int> = listOf(1, 2))
+
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = TestClass(emptyList())) {
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("test?arg={arg}")
+        val route = navController.currentBackStackEntry?.toRoute<TestClass>()
+        assertThat(route!!.arg).isNotNull()
+        assertThat(route.arg).containsExactly(1, 2).inOrder()
+    }
+
+    @UiThreadTest
+    @Test
     fun testDeepLinkFromNavGraph() {
         val navController = createNavController()
         navController.graph = nav_simple_route_graph
diff --git a/navigation/navigation-testing/api/2.8.0-beta03.txt b/navigation/navigation-testing/api/2.8.0-beta03.txt
index 6e1e2354..ebd90df 100644
--- a/navigation/navigation-testing/api/2.8.0-beta03.txt
+++ b/navigation/navigation-testing/api/2.8.0-beta03.txt
@@ -2,7 +2,7 @@
 package androidx.navigation.testing {
 
   public final class SavedStateHandleFactoryKt {
-    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   public final class TestNavHostController extends androidx.navigation.NavHostController {
diff --git a/navigation/navigation-testing/api/current.txt b/navigation/navigation-testing/api/current.txt
index 6e1e2354..ebd90df 100644
--- a/navigation/navigation-testing/api/current.txt
+++ b/navigation/navigation-testing/api/current.txt
@@ -2,7 +2,7 @@
 package androidx.navigation.testing {
 
   public final class SavedStateHandleFactoryKt {
-    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   public final class TestNavHostController extends androidx.navigation.NavHostController {
diff --git a/navigation/navigation-testing/api/restricted_2.8.0-beta03.txt b/navigation/navigation-testing/api/restricted_2.8.0-beta03.txt
index 6e1e2354..ebd90df 100644
--- a/navigation/navigation-testing/api/restricted_2.8.0-beta03.txt
+++ b/navigation/navigation-testing/api/restricted_2.8.0-beta03.txt
@@ -2,7 +2,7 @@
 package androidx.navigation.testing {
 
   public final class SavedStateHandleFactoryKt {
-    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   public final class TestNavHostController extends androidx.navigation.NavHostController {
diff --git a/navigation/navigation-testing/api/restricted_current.txt b/navigation/navigation-testing/api/restricted_current.txt
index 6e1e2354..ebd90df 100644
--- a/navigation/navigation-testing/api/restricted_current.txt
+++ b/navigation/navigation-testing/api/restricted_current.txt
@@ -2,7 +2,7 @@
 package androidx.navigation.testing {
 
   public final class SavedStateHandleFactoryKt {
-    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object!>> typeMap);
+    method public static operator androidx.lifecycle.SavedStateHandle invoke(androidx.lifecycle.SavedStateHandle.Companion, Object route, optional java.util.Map<kotlin.reflect.KType,androidx.navigation.NavType<? extends java.lang.Object?>> typeMap);
   }
 
   public final class TestNavHostController extends androidx.navigation.NavHostController {
diff --git a/paging/paging-common/api/current.txt b/paging/paging-common/api/current.txt
index 3d1ee0d..776b8df 100644
--- a/paging/paging-common/api/current.txt
+++ b/paging/paging-common/api/current.txt
@@ -200,7 +200,7 @@
     method @Deprecated public abstract void detach();
     method @Deprecated public T? get(int index);
     method @Deprecated public final androidx.paging.PagedList.Config getConfig();
-    method @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object!,T> getDataSource();
+    method @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object?,T> getDataSource();
     method @Deprecated public abstract Object? getLastKey();
     method @Deprecated public final int getLoadedCount();
     method @Deprecated public final int getPositionOffset();
@@ -213,7 +213,7 @@
     method @Deprecated public void retry();
     method @Deprecated public final java.util.List<T> snapshot();
     property @Deprecated public final androidx.paging.PagedList.Config config;
-    property @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object!,T> dataSource;
+    property @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object?,T> dataSource;
     property @Deprecated public abstract boolean isDetached;
     property @Deprecated public boolean isImmutable;
     property @Deprecated public abstract Object? lastKey;
diff --git a/paging/paging-common/api/restricted_current.txt b/paging/paging-common/api/restricted_current.txt
index 3d1ee0d..776b8df 100644
--- a/paging/paging-common/api/restricted_current.txt
+++ b/paging/paging-common/api/restricted_current.txt
@@ -200,7 +200,7 @@
     method @Deprecated public abstract void detach();
     method @Deprecated public T? get(int index);
     method @Deprecated public final androidx.paging.PagedList.Config getConfig();
-    method @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object!,T> getDataSource();
+    method @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object?,T> getDataSource();
     method @Deprecated public abstract Object? getLastKey();
     method @Deprecated public final int getLoadedCount();
     method @Deprecated public final int getPositionOffset();
@@ -213,7 +213,7 @@
     method @Deprecated public void retry();
     method @Deprecated public final java.util.List<T> snapshot();
     property @Deprecated public final androidx.paging.PagedList.Config config;
-    property @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object!,T> dataSource;
+    property @Deprecated public final androidx.paging.DataSource<? extends java.lang.Object?,T> dataSource;
     property @Deprecated public abstract boolean isDetached;
     property @Deprecated public boolean isImmutable;
     property @Deprecated public abstract Object? lastKey;
diff --git a/paging/paging-runtime/api/current.txt b/paging/paging-runtime/api/current.txt
index 0f200ba..ec190c6 100644
--- a/paging/paging-runtime/api/current.txt
+++ b/paging/paging-runtime/api/current.txt
@@ -3,7 +3,7 @@
 
   @Deprecated public class AsyncPagedListDiffer<T> {
     ctor @Deprecated public AsyncPagedListDiffer(androidx.recyclerview.widget.ListUpdateCallback listUpdateCallback, androidx.recyclerview.widget.AsyncDifferConfig<T> config);
-    ctor @Deprecated public AsyncPagedListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter<? extends java.lang.Object!> adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T> diffCallback);
+    ctor @Deprecated public AsyncPagedListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter<? extends java.lang.Object?> adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T> diffCallback);
     method @Deprecated public void addLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
     method @Deprecated public void addPagedListListener(androidx.paging.AsyncPagedListDiffer.PagedListListener<T> listener);
     method @Deprecated public final void addPagedListListener(kotlin.jvm.functions.Function2<? super androidx.paging.PagedList<T>?,? super androidx.paging.PagedList<T>?,kotlin.Unit> callback);
@@ -94,9 +94,9 @@
     method @Deprecated public void removeLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
     method @Deprecated public void submitList(androidx.paging.PagedList<T>? pagedList);
     method @Deprecated public void submitList(androidx.paging.PagedList<T>? pagedList, Runnable? commitCallback);
-    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
-    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header);
-    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
+    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
+    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header);
+    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
     property @Deprecated public androidx.paging.PagedList<T>? currentList;
   }
 
@@ -122,9 +122,9 @@
     method public final androidx.paging.ItemSnapshotList<T> snapshot();
     method public final void submitData(androidx.lifecycle.Lifecycle lifecycle, androidx.paging.PagingData<T> pagingData);
     method public final suspend Object? submitData(androidx.paging.PagingData<T> pagingData, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
-    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header);
-    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
+    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
+    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header);
+    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
     property public final kotlinx.coroutines.flow.Flow<androidx.paging.CombinedLoadStates> loadStateFlow;
     property public final kotlinx.coroutines.flow.Flow<kotlin.Unit> onPagesUpdatedFlow;
   }
diff --git a/paging/paging-runtime/api/restricted_current.txt b/paging/paging-runtime/api/restricted_current.txt
index 0f200ba..ec190c6 100644
--- a/paging/paging-runtime/api/restricted_current.txt
+++ b/paging/paging-runtime/api/restricted_current.txt
@@ -3,7 +3,7 @@
 
   @Deprecated public class AsyncPagedListDiffer<T> {
     ctor @Deprecated public AsyncPagedListDiffer(androidx.recyclerview.widget.ListUpdateCallback listUpdateCallback, androidx.recyclerview.widget.AsyncDifferConfig<T> config);
-    ctor @Deprecated public AsyncPagedListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter<? extends java.lang.Object!> adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T> diffCallback);
+    ctor @Deprecated public AsyncPagedListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter<? extends java.lang.Object?> adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T> diffCallback);
     method @Deprecated public void addLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
     method @Deprecated public void addPagedListListener(androidx.paging.AsyncPagedListDiffer.PagedListListener<T> listener);
     method @Deprecated public final void addPagedListListener(kotlin.jvm.functions.Function2<? super androidx.paging.PagedList<T>?,? super androidx.paging.PagedList<T>?,kotlin.Unit> callback);
@@ -94,9 +94,9 @@
     method @Deprecated public void removeLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
     method @Deprecated public void submitList(androidx.paging.PagedList<T>? pagedList);
     method @Deprecated public void submitList(androidx.paging.PagedList<T>? pagedList, Runnable? commitCallback);
-    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
-    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header);
-    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
+    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
+    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header);
+    method @Deprecated public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
     property @Deprecated public androidx.paging.PagedList<T>? currentList;
   }
 
@@ -122,9 +122,9 @@
     method public final androidx.paging.ItemSnapshotList<T> snapshot();
     method public final void submitData(androidx.lifecycle.Lifecycle lifecycle, androidx.paging.PagingData<T> pagingData);
     method public final suspend Object? submitData(androidx.paging.PagingData<T> pagingData, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
-    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header);
-    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object!> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object!> footer);
+    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
+    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeader(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header);
+    method public final androidx.recyclerview.widget.ConcatAdapter withLoadStateHeaderAndFooter(androidx.paging.LoadStateAdapter<? extends java.lang.Object?> header, androidx.paging.LoadStateAdapter<? extends java.lang.Object?> footer);
     property public final kotlinx.coroutines.flow.Flow<androidx.paging.CombinedLoadStates> loadStateFlow;
     property public final kotlinx.coroutines.flow.Flow<kotlin.Unit> onPagesUpdatedFlow;
   }
diff --git a/pdf/integration-tests/testapp/src/main/AndroidManifest.xml b/pdf/integration-tests/testapp/src/main/AndroidManifest.xml
index 2c55785..4a33224 100644
--- a/pdf/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/pdf/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -28,7 +28,9 @@
         tools:replace="android:label">
         <activity
             android:name=".MainActivity"
-            android:exported="true">
+            android:exported="true"
+            android:windowSoftInputMode="adjustResize"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
diff --git a/pdf/integration-tests/testapp/src/main/res/layout/activity_main.xml b/pdf/integration-tests/testapp/src/main/res/layout/activity_main.xml
index a56fd05..7820e52 100644
--- a/pdf/integration-tests/testapp/src/main/res/layout/activity_main.xml
+++ b/pdf/integration-tests/testapp/src/main/res/layout/activity_main.xml
@@ -21,6 +21,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_gravity="center"
+    android:fitsSystemWindows="true"
     android:orientation="vertical"
     tools:context=".MainActivity">
 
diff --git a/pdf/pdf-viewer/src/androidTest/java/androidx/pdf/util/GestureTrackingViewTest.java b/pdf/pdf-viewer/src/androidTest/java/androidx/pdf/util/GestureTrackingViewTest.java
index 719398d..fc73215 100644
--- a/pdf/pdf-viewer/src/androidTest/java/androidx/pdf/util/GestureTrackingViewTest.java
+++ b/pdf/pdf-viewer/src/androidTest/java/androidx/pdf/util/GestureTrackingViewTest.java
@@ -30,7 +30,6 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.os.Build;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.FrameLayout;
@@ -140,11 +139,7 @@
 
         @Override
         protected boolean interceptGesture(GestureTracker gestureTracker) {
-            boolean intercepted = gestureTracker.matches(mInterceptedGestures);
-            if (intercepted) {
-                Log.i(TAG, "Intercepted: " + gestureTracker.getLog());
-            }
-            return intercepted;
+            return gestureTracker.matches(mInterceptedGestures);
         }
     }
 
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/DisplayData.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/DisplayData.java
index b415923..3024526 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/DisplayData.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/DisplayData.java
@@ -24,7 +24,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.pdf.data.Openable.Open;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.Preconditions;
 
 import java.io.IOException;
@@ -85,7 +84,6 @@
         try {
             return open(opener).getFd();
         } catch (IOException e) {
-            ErrorLog.log(TAG, "openFd", e);
             return null;
         }
     }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FileOpenable.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FileOpenable.java
index 5b8b58e..12cc0ea 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FileOpenable.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FileOpenable.java
@@ -24,7 +24,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.Preconditions;
 import androidx.pdf.util.Uris;
 
@@ -150,7 +149,6 @@
                     try {
                         return new FileOpenable(makeFile(parcel.readString()), parcel.readString());
                     } catch (FileNotFoundException e) {
-                        ErrorLog.log(TAG, "File not found.", e);
                         return null;
                     }
                 }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FutureValues.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FutureValues.java
index 281affd..d2bf169 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FutureValues.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/FutureValues.java
@@ -20,7 +20,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.WorkerThread;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.ObservableValue;
 import androidx.pdf.util.Preconditions;
 
@@ -71,7 +70,7 @@
             }
 
             @Override
-            public void failed(Throwable thrown) {
+            public void failed(@NonNull Throwable thrown) {
                 targetFuture.fail(thrown);
             }
 
@@ -103,7 +102,7 @@
                     }
 
                     @Override
-                    public void failed(Throwable thrown) {
+                    public void failed(@NonNull Throwable thrown) {
                         target.failed(thrown);
                     }
 
@@ -198,7 +197,7 @@
 
     /**
      * A convenient base implementation of {@link FutureValue.Callback} that does nothing. It
-     * assumes no failures are reported and thus handles them with {@link ErrorLog#logAndThrow}.
+     * assumes no failures are reported and thus handles them.
      * Subclasses should override {@link #failed} if failures are expected.
      *
      * @param <T> the type of result
@@ -211,7 +210,6 @@
 
         @Override
         public void failed(@NonNull Throwable thrown) {
-            ErrorLog.logAndThrow(toString(), "failed", thrown);
         }
 
         @Override
@@ -304,7 +302,7 @@
         }
 
         @Override
-        public void get(@NonNull Callback<T> callback) {
+        public void get(@Nullable Callback<T> callback) {
             try {
                 mComputation.supply(progress -> {
                 }).get(callback);
@@ -385,7 +383,7 @@
         }
 
         @Override
-        public void get(@NonNull Callback<T> callback) {
+        public void get(@Nullable Callback<T> callback) {
             if (mValue != null) {
                 callback.available(mValue);
             } else if (mThrown != null) {
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/UiFutureValues.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/UiFutureValues.java
index c3c98f9..0021531 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/data/UiFutureValues.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/data/UiFutureValues.java
@@ -16,8 +16,6 @@
 
 package androidx.pdf.data;
 
-import android.util.Log;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.VisibleForTesting;
@@ -63,7 +61,6 @@
     private static final Executor DEFAULT_EXECUTOR = Executors.newFixedThreadPool(4,
             new ThreadFactoryBuilder().setNameFormat("PdfViewer-" + TAG + "-%d").build());
     private static Executor sExecutor = DEFAULT_EXECUTOR;
-    private static boolean sDebug;
 
     private UiFutureValues() {
     }
@@ -104,12 +101,6 @@
         return callback -> ThreadUtils.runOnUiThread(() -> callback.failed(error));
     }
 
-    /** Log the calling threads stack trace when exceptions occur in the background thread. */
-    public static void setDebugTrace(boolean debug) {
-        Log.v(TAG, "Setting debug trace to " + debug);
-        UiFutureValues.sDebug = debug;
-    }
-
     /** Wraps up a {@link Supplier} to supply a converted value. */
     @NonNull
     public static <F, T> Supplier<T> postConvert(final @NonNull Supplier<F> supplier,
@@ -117,7 +108,7 @@
         return new Supplier<T>() {
 
             @Override
-            public T supply(Progress progress) throws Exception {
+            public T supply(@NonNull Progress progress) throws Exception {
                 return converter.convert(supplier.supply(progress));
             }
         };
@@ -190,7 +181,7 @@
             }
 
             @Override
-            public void failed(final Throwable thrown) {
+            public void failed(@NonNull final Throwable thrown) {
                 if (ThreadUtils.isUiThread()) {
                     targetCallback.failed(thrown);
                 } else {
@@ -225,7 +216,7 @@
             }
 
             @Override
-            public void failed(final Throwable thrown) {
+            public void failed(@NonNull final Throwable thrown) {
                 ThreadUtils.runOnUiThread(() -> destFuture.fail(thrown));
             }
 
@@ -248,15 +239,10 @@
         private final FutureValues.SettableFutureValue<T> mFuture;
         // Any throwable caught during the call to supply() is kept here for onPostExecute.
         private Throwable mCaught;
-        // Debug exception to trace the calling threads stack.
-        private Exception mDebugTraceException;
 
         FutureAsyncTask(Supplier<T> supplier, SettableFutureValue<T> settable) {
             this.mSupplier = supplier;
             this.mFuture = settable;
-            if (sDebug) {
-                this.mDebugTraceException = new Exception("A debug stack trace");
-            }
         }
 
         @Override
@@ -271,12 +257,6 @@
                 };
                 return mSupplier.supply(progress);
             } catch (Throwable e) {
-                if (mDebugTraceException != null) {
-                    Log.d(TAG, "Exception during background processing: ", e);
-                    Log.d(TAG, "Problem during background called from:", mDebugTraceException);
-                } else {
-                    Log.d(TAG, "Exception during background processing: " + e);
-                }
                 mCaught = e;
                 return null;
             }
@@ -297,13 +277,8 @@
                 } else {
                     mFuture.set(result);
                 }
-            } catch (Exception e) {
-                if (mDebugTraceException != null) {
-                    Log.e(TAG, "Exception during post processing: ", e);
-                    Log.e(TAG, "Problem in post-execute called from:", mDebugTraceException);
-                } else {
-                    Log.w(TAG, "Exception during post processing: ", e);
-                }
+            } catch (Exception ignored) {
+                // TODO: Rethrow exception or return error code
             }
         }
     }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/models/GotoLink.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/models/GotoLink.java
index b51abea..b029958 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/models/GotoLink.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/models/GotoLink.java
@@ -36,7 +36,7 @@
  */
 // TODO: Use android.graphics.pdf.content.PdfPageGotoLinkContent and remove this class
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation", "unchecked"})
 @SuppressLint("BanParcelableUsage")
 public class GotoLink implements Parcelable {
 
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapParcel.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapParcel.java
index ff7b200..aa6979e 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapParcel.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapParcel.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Bitmap;
 import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -66,7 +65,6 @@
             // TODO: StrictMode - close() is not explicitly called.
             pipe = ParcelFileDescriptor.createPipe();
         } catch (IOException e) {
-            ErrorLog.log(TAG, "createPipe-IOX", e);
             return null;
         }
         ParcelFileDescriptor source = pipe[0];
@@ -81,11 +79,7 @@
             boolean timedOut = false;
             try {
                 timedOut = !mCountDownLatch.await(5, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                Log.w(TAG, "Reading thread was interrupted ??", e);
-            }
-            if (timedOut) {
-                Log.w(TAG, "Reading thread took more than 5 seconds ??");
+            } catch (InterruptedException ignored) {
             }
         }
     }
@@ -97,8 +91,6 @@
                 () -> {
                     Timer t = Timer.start();
                     receiveBitmap(mBitmap, source);
-                    Log.v(TAG, "Receive bitmap native: " + t.time() + " ms.");
-                    Log.v(TAG, "Finished transfer: " + mTimer.time() + " ms.");
                     mCountDownLatch.countDown();
                 },
                 "Pico-AsyncPipedFdNative.receiveAsync")
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapRecycler.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapRecycler.java
index 59d71fa..6a1934f 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapRecycler.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/BitmapRecycler.java
@@ -17,7 +17,6 @@
 package androidx.pdf.util;
 
 import android.graphics.Bitmap;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -60,9 +59,6 @@
                 } else if (bitmap.getWidth() == dimensions.getWidth()
                         && bitmap.getHeight() == dimensions.getHeight()) {
                     iterator.remove();
-                    Log.v(TAG,
-                            "Recycle bitmap dim=" + dimensions + ", [" + getMemSizeKb(bitmap)
-                                    + "K]");
                     return bitmap;
                 }
             }
@@ -90,11 +86,9 @@
             Bitmap bitmap =
                     Bitmap.createBitmap(dimensions.getWidth(), dimensions.getHeight(),
                             Bitmap.Config.ARGB_8888);
-            Log.v(TAG, "Allocated bitmap dim=" + dimensions + ", [" + getMemSizeKb(bitmap) + "K]");
             dump();
             return bitmap;
         } catch (OutOfMemoryError e) {
-            Log.w(TAG, "Can't allocate bitmap dim=" + dimensions);
             dump();
             return null;
         }
@@ -120,9 +114,6 @@
         }
 
         sb.append(") /mem = " + mem);
-        if (mem != 0) {
-            Log.v(TAG, String.valueOf(sb));
-        }
     }
 
     @SuppressWarnings("ObjectToString")
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/ContentUriOpener.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/ContentUriOpener.java
index a00c8d3..327e204 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/ContentUriOpener.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/ContentUriOpener.java
@@ -24,7 +24,6 @@
 import android.os.Bundle;
 import android.provider.MediaStore.MediaColumns;
 import android.text.TextUtils;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -90,6 +89,7 @@
     }
 
     /**
+     *
      */
     @Nullable
     public String getContentType(@NonNull Uri contentUri) {
@@ -97,7 +97,7 @@
             String[] availableTypes = mContentResolver.getStreamTypes(contentUri, "*/*");
             String declaredType = mContentResolver.getType(contentUri);
             // Sometimes the declared type is actually not available, then pick an available type
-          // instead.
+            // instead.
             String useType = null;
             if (availableTypes != null) {
                 for (String type : availableTypes) {
@@ -106,17 +106,13 @@
                     } else if (type.equals(declaredType)) {
                         useType = declaredType;
                     }
-                    Log.v(TAG, String.format("available type: %s", type));
                 }
             }
-            Log.v(TAG,
-                    String.format("Use content type %s (declared was %s)", useType, declaredType));
             if (useType == null) {
                 useType = declaredType;
             }
             return useType;
         } catch (SecurityException se) {
-            ErrorLog.log(TAG, "content:" + contentUri.getAuthority(), se);
             return null;
         }
     }
@@ -140,12 +136,12 @@
                 return new String[]{mContentResolver.getType(contentUri)};
             }
         } catch (SecurityException se) {
-            ErrorLog.log(TAG, "content:" + contentUri.getAuthority(), se);
             return new String[]{};
         }
     }
 
     /**
+     *
      */
     @Nullable
     public static String extractContentName(@NonNull ContentResolver contentResolver,
@@ -165,7 +161,7 @@
                 }
             } catch (Exception e) {
                 // Misbehaved app!
-                ErrorLog.log(TAG, "extractName", e);
+                // TODO: Rethrow exception or return an error code
             } finally {
                 if (cursor != null) {
                     cursor.close();
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/ErrorLog.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/ErrorLog.java
deleted file mode 100644
index 7b0819e..0000000
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/ErrorLog.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.pdf.util;
-
-import android.os.Build;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
-
-/**
- * Error logging utility. Logs errors on the internal Log system and tracks analytics.
- *
- * <p>Guidelines for this class:
- *
- * <ul>
- *   <li>Privacy: Do not track any PII (user personal info)
- *   <li>Only track Exception classes and generic messages (no getMessage(), no user info)
- *   <li>(Re-)throw RuntimeExceptions only in Dev builds, swallow them on release builds.
- * </ul>
- */
-// TODO: Track errors.
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-public class ErrorLog {
-
-    private ErrorLog() {
-    }
-
-    /** Logs and tracks the error message. */
-    public static void log(@NonNull String tag, @NonNull String message) {
-        Log.e(tag, message);
-    }
-
-    /** Logs and tracks the error message. The 'details' arg is only used locally. */
-    public static void log(@NonNull String tag, @NonNull String message, @NonNull String details) {
-        Log.e(tag, message + " " + details);
-    }
-
-    /**
-     * Logs and tracks the exception (tracks only the exception name). Doesn't re-throw the
-     * exception.
-     */
-    public static void log(@NonNull String tag, @NonNull String method, @NonNull Throwable e) {
-        Log.e(tag, method, e);
-    }
-
-    /** Logs and tracks the exception. If running a dev build, re-throws the exception. */
-    public static void logAndThrow(@NonNull String tag, @NonNull String method,
-            @NonNull Throwable e) {
-        log(tag, method, e);
-        if (isDebuggable()) {
-            Log.e(tag, "In method " + method + ": ", e);
-            throw asRuntimeException(e);
-        }
-    }
-
-    /** Logs and tracks the error message. If running a dev build, throws a runtime exception. */
-    public static void logAndThrow(@NonNull String tag, @NonNull String method,
-            @NonNull String message) {
-        Log.e(tag, method + ": " + message);
-        if (isDebuggable()) {
-            throw new RuntimeException(message);
-        }
-    }
-
-    private static RuntimeException asRuntimeException(Throwable e) {
-        if (e instanceof RuntimeException) {
-            return (RuntimeException) e;
-        }
-        return new RuntimeException(e);
-    }
-
-    /** Logs and tracks the exception, then rethrows it. */
-    public static void logAndAlwaysThrow(@NonNull String tag, @NonNull String method,
-            @NonNull Throwable e) {
-        log(tag, method, e);
-        throw asRuntimeException(e);
-    }
-
-    /**
-     * A safer version of Preconditions.checkState that will log instead of throw in release builds.
-     *
-     * <p>Checks <code>condition</code> and {@link #logAndThrow} the error message as an {@link
-     * IllegalArgumentException} if it is false.
-     */
-    public static void checkState(boolean condition, @NonNull String tag, @NonNull String method,
-            @NonNull String message) {
-        if (!condition) {
-            IllegalArgumentException e = new IllegalArgumentException(message);
-            logAndThrow(tag, method, e);
-        }
-    }
-
-    /** Convert int value to range. */
-    public static @NonNull String bracketValue(int value) {
-        if (value == 0) {
-            return "0";
-        } else if (value == 1) {
-            return "1";
-        } else if (value <= 10) {
-            return "up to 10";
-        } else if (value <= 100) {
-            return "up to 100";
-        } else if (value <= 1000) {
-            return "up to 1000";
-        } else {
-            return "more than 1000";
-        }
-    }
-
-    private static boolean isDebuggable() {
-        return "eng".equals(Build.TYPE) || "userdebug".equals(Build.TYPE);
-    }
-}
\ No newline at end of file
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/GestureTracker.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/GestureTracker.java
index cc5158e..fa953b2 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/GestureTracker.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/GestureTracker.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.graphics.PointF;
-import android.util.Log;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.MotionEvent;
@@ -136,8 +135,6 @@
             }
         }
     }
-
-    private final String mViewTag;
     private final int mMoveSlop;
 
     private final ScaleGestureDetector mZoomDetector;
@@ -171,7 +168,6 @@
     public GestureTracker(@NonNull String tag, @NonNull Context context) {
         ViewConfiguration config = ViewConfiguration.get(context);
         mMoveSlop = config.getScaledTouchSlop();
-        mViewTag = tag;
         DetectorListener listener = new DetectorListener();
         mMoveDetector = new GestureDetector(context, listener);
         mZoomDetector = new ScaleGestureDetector(context, listener);
@@ -229,7 +225,6 @@
             // Call onGestureStart as soon as we start handling a gesture - even if we
             // missed the ACTION_DOWN part of the gesture.
             if (mDelegate != null && handle && !mHandling) {
-                log("Gesture start");
                 mDelegate.onGestureStart();
             }
             mHandling = handle;
@@ -237,9 +232,7 @@
             mLog.append(getEventTag(event));
             mMoveDetector.onTouchEvent(event);
 
-            if (mQuickScaleBypassDecider.shouldSkipZoomDetector(event, mLastEvent)) {
-                log("Skipping zoom detector!");
-            } else {
+            if (!mQuickScaleBypassDecider.shouldSkipZoomDetector(event, mLastEvent)) {
                 mZoomDetector.onTouchEvent(event);
             }
             mDoubleTapDetector.onTouchEvent(event);
@@ -301,7 +294,6 @@
             if (mDetectedGesture == Gesture.DOUBLE_TAP && mDelegate != null) {
                 // tracking might be false, if this happens after the regular endGesture() has
                 // been called.
-                log("handle double tap ");
                 mDelegate.onDoubleTap(ev);
                 endGesture();
             }
@@ -311,7 +303,6 @@
     private void endGesture() {
         mTracking = false;
         mLog.append('/');
-        log("End gesture");
         if (mHandling && mDelegate != null) {
             mDelegate.onGestureEnd(mDetectedGesture);
         }
@@ -418,14 +409,6 @@
         mLog.setLength(0);
         mTouchDown.set(x, y);
         mDetectedGesture = Gesture.TOUCH;
-        log(String.format("Start tracking (%d, %d)", (int) x, (int) y));
-    }
-
-    private void log(String msg) {
-        Log.v(TAG,
-                String.format("[%s] %s %s (%s) [Handling: %s]", mViewTag, msg, mDetectedGesture,
-                        mLog,
-                        mHandling));
     }
 
     /** A recipient for all gesture handling. */
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Intents.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Intents.java
index 0c057ef..be4a315 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Intents.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Intents.java
@@ -43,7 +43,6 @@
             context.startActivity(intent);
             return true;
         } catch (Exception e) {
-            ErrorLog.log(logTag, "startActivity: " + toLongString(intent), e);
             return false;
         }
     }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Observables.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Observables.java
index 4a6d3ed..d97ad87 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Observables.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Observables.java
@@ -80,10 +80,6 @@
 
         @Override
         protected void finalize() throws Throwable {
-            if (hasObservers()) {
-                ErrorLog.log(TAG, "Leaking " + mObservers.size() + " observers, e.g. "
-                        + mObservers.iterator().next());
-            }
             super.finalize();
         }
 
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Screen.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Screen.java
index 66fb3d0..3831df8 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Screen.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Screen.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
@@ -44,7 +43,6 @@
     public Screen(@NonNull Context ctx) {
         this.mCtx = ctx.getApplicationContext();
         mRes = this.mCtx.getResources();
-        Log.v(TAG, "10dp = " + pxFromDp(10) + "; dpi = " + getDensityDpi());
     }
 
     /** Converts a value given in dp to pixels, based on the screen density. */
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/TileBoard.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/TileBoard.java
index 5c0da8e..db90fed 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/TileBoard.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/TileBoard.java
@@ -19,7 +19,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
@@ -148,11 +147,9 @@
     /** Returns true if the tile is still relevant and was saved. */
     public boolean setTile(@NonNull TileInfo tileInfo, @NonNull Bitmap tile) {
         if (!isTileVisible(tileInfo)) {
-            Log.v(mTag, String.format("Request to set tile %s outside visible area", tileInfo));
             return false;
         }
         if (!tileInfo.belongsTo(this)) {
-            Log.v(mTag, String.format("Discard %s (%s)", tileInfo, mBounds.getWidth()));
             return false;
         }
         mTiles[tileInfo.getIndex()] = tile;
@@ -198,7 +195,6 @@
 
         // Accumulate tiles that we still need here, then replace 'tiles' with it.
         Bitmap[] retainedTiles = new Bitmap[mTiles.length];
-        int retainedCount = 0;
         List<TileInfo> newTiles = new ArrayList<>(mVisibleArea.size());
         List<Integer> retainRequests = new ArrayList<>(mPendingTileRequests.size());
         for (int k : areaIndexes(mVisibleArea)) {
@@ -212,7 +208,6 @@
                 }
             } else {
                 retainedTiles[k] = tile;
-                retainedCount++;
                 mTiles[k] = null;
             }
         }
@@ -245,16 +240,6 @@
 
         System.arraycopy(retainedTiles, 0, mTiles, 0, mTiles.length);
         if (!newTiles.isEmpty()) {
-            Log.v(
-                    mTag,
-                    String.format(
-                            "ViewArea has %d new tiles (had tiles: %d), discard: %d, cancel: %d,"
-                                    + "pending requests(%d)",
-                            newTiles.size(),
-                            retainedCount,
-                            disposed.size(),
-                            staleRequests.size(),
-                            retainRequests.size()));
             callback.requestNewTiles(newTiles);
             for (TileInfo requestedTile : newTiles) {
                 mPendingTileRequests.add(requestedTile.getIndex());
@@ -349,36 +334,19 @@
     }
 
     private void logMem() {
-        int memSize = 0;
-        int count = 0;
         int i = 0;
         StringBuilder out = new StringBuilder();
         for (Bitmap bitmap : mTiles) {
             if (bitmap != null) {
-                count++;
-                memSize += BitmapRecycler.getMemSizeKb(bitmap);
                 out.append(i).append(",");
             }
             i++;
         }
-        Log.v(
-                mTag,
-                String.format(
-                        "Tile Mem usage (%s): %d tiles (out of %d) / %d K. %s",
-                        mTag, count, mTiles.length, memSize, out));
     }
 
     @Override
     protected void finalize() throws Throwable {
         super.finalize();
-        int k = 0;
-        for (Bitmap tile : mTiles) {
-            if (tile != null) {
-                ErrorLog.log(mTag,
-                        "Finalize -- Memory leak candidate (bitmap not null) " + mTileInfos[k]);
-            }
-            k++;
-        }
     }
 
     /**
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Timer.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Timer.java
index 3db7d7e..5574741 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Timer.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/util/Timer.java
@@ -16,22 +16,14 @@
 
 package androidx.pdf.util;
 
-import android.annotation.SuppressLint;
 import android.os.SystemClock;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.FormatMethod;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
 /**
  * Simple timer for profiling methods.
  */
-@SuppressLint("BanConcurrentHashMap")
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class Timer {
 
@@ -56,83 +48,4 @@
     private static long getElapsedTimeMs() {
         return SystemClock.elapsedRealtime();
     }
-
-    /** A logger that times every event it receives and outputs all events and their timestamp. */
-    public static class LogBuilder {
-
-        /** Using a StringBuffer because we need this to be thread-safe. */
-        private final StringBuilder mLog = new StringBuilder();
-
-        private final Timer mTimer = Timer.start();
-
-        {
-            track("Created");
-        }
-
-        /**
-         *
-         */
-        @NonNull
-        @CanIgnoreReturnValue
-        public LogBuilder track(@NonNull String event) {
-            mLog.append(event).append(":").append(mTimer.time()).append("; ");
-            return this;
-        }
-
-        /**
-         *
-         */
-        @NonNull
-        @CanIgnoreReturnValue
-        @FormatMethod
-        public LogBuilder trackFmt(@NonNull String eventFmt, @NonNull Object... args) {
-            mLog.append(String.format(eventFmt, args)).append(":").append(mTimer.time()).append(
-                    "; ");
-            return this;
-        }
-
-        /**
-         *
-         */
-        @NonNull
-        @Override
-        public String toString() {
-            return mLog.toString();
-        }
-    }
-
-    /** Keeps a concurrent collection of loggers and allows them to be easily retrieved. */
-    public static class Loggers {
-        private final Map<String, LogBuilder> mNameToTimer = new ConcurrentHashMap<>();
-
-        /**
-         *
-         */
-        public void start(@NonNull String key) {
-            mNameToTimer.put(key, new LogBuilder());
-        }
-
-        /**
-         *
-         */
-        public void track(@NonNull String key, @NonNull String event) {
-            LogBuilder logger = mNameToTimer.get(key);
-            if (logger != null) {
-                logger.track(event);
-            }
-        }
-
-        /**
-         *
-         */
-        @NonNull
-        public String stop(@NonNull String key) {
-            LogBuilder logger = mNameToTimer.remove(key);
-            if (logger != null) {
-                return logger.toString();
-            } else {
-                return "No logger for key " + key;
-            }
-        }
-    }
 }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/LoadingViewer.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/LoadingViewer.java
index 3428c76..3090813 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/LoadingViewer.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/LoadingViewer.java
@@ -27,7 +27,6 @@
 import androidx.annotation.RestrictTo;
 import androidx.pdf.data.DisplayData;
 import androidx.pdf.fetcher.Fetcher;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.Preconditions;
 
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
@@ -94,7 +93,7 @@
 
     @NonNull
     @Override
-    public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container,
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
             @Nullable Bundle savedState) {
         View result = super.onCreateView(inflater, container, savedState);
         if (mFetcher == null) {
@@ -102,7 +101,6 @@
             // instance with a null fetcher stays around, even though it has been detached from the
             // view hierarchy, which is when this case happens. Logging it is sufficient as the
             // second instance will have the fetcher injected as expected.
-            ErrorLog.log(getLogTag(), "onCreateView", "Missing fetcher " + getEventlog());
             mViewState.set(ViewState.ERROR);
             return result;
         }
@@ -124,9 +122,6 @@
     @Override
     public void onStop() {
         super.onStop();
-        if (mDelayedContentsAvailable != null) {
-            ErrorLog.log(getLogTag(), "mDelayedContentsAvailable not null");
-        }
     }
 
     @Override
@@ -155,13 +150,9 @@
      */
     protected void postContentsAvailable(final @NonNull DisplayData contents,
             @Nullable final Bundle savedState) {
-        if (mHasContents) {
-            log('L', "Replacing contents ");
-        }
         Preconditions.checkState(mDelayedContentsAvailable == null, "Already waits for contents");
 
         if (isStarted()) {
-            log('C', "Got contents (direct) " + contents);
             onContentsAvailable(contents, savedState);
             mHasContents = true;
         } else {
@@ -170,7 +161,6 @@
                         Preconditions.checkState(
                                 !mHasContents, "Received contents while restoring another copy");
                         onContentsAvailable(contents, savedState);
-                        log('D', "Got contents (delayed)");
                         mDelayedContentsAvailable = null;
                         mHasContents = true;
                     };
@@ -193,13 +183,11 @@
         if (dataBundle != null) {
             try {
                 DisplayData restoredData = DisplayData.fromBundle(dataBundle);
-                log('R', String.format("Restore contents %s", restoredData));
                 postContentsAvailable(restoredData, savedState);
             } catch (Exception e) {
                 // This can happen if the data is an instance of StreamOpenable, and the client
                 // app that owns it has been killed by the system. We will still recover,
                 // but log this.
-                ErrorLog.log(getLogTag(), "restoreContents", e);
                 mViewState.set(ViewState.ERROR);
             }
         }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PageLinksView.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PageLinksView.java
index 1366045..63a2236 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PageLinksView.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PageLinksView.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -40,6 +39,7 @@
 import androidx.pdf.widget.ZoomView;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * A transparent container for virtual views representing clickable links within the Page. NOTE:
@@ -196,7 +196,7 @@
                 // The AccessibilityNodeInfo isn't automatically scaled by the scaling of the View
                 // it is part of, so we have to do that ourselves - in contrast to
                 // #getVirtualViewAt.
-                float zoom = mZoomScroll.get().zoom;
+                float zoom = Objects.requireNonNull(mZoomScroll.get()).zoom;
 
                 // Explicitly cast to int after scaling
                 bounds.top = (int) (bounds.top * zoom);
@@ -209,7 +209,6 @@
         }
 
         private boolean isLinkLoaded(int virtualViewId) {
-            Log.d(TAG, String.format("virtualViewId %d", virtualViewId));
             // Links can be deleted as we unload pages as the user scrolls around - if this
             // happens but an event for the link somehow happens afterward, we should ignore it
             // and try not to crash. Also, the accessibility framework sometimes requests links
@@ -220,7 +219,6 @@
         }
 
         private String getContentDescription(int virtualViewId) {
-            Log.d(TAG, String.format("virtualViewId %d", virtualViewId));
             int linkSize = mUrlLinks != null ? mUrlLinks.size() : 0;
             int gotoLinksSize = mGotoLinks != null ? mGotoLinks.size() : 0;
             if (virtualViewId < linkSize) {
@@ -230,7 +228,6 @@
                         virtualViewId - linkSize).getDestination().getPageNumber();
                 return getContext().getString(R.string.desc_goto_link, pageNum);
             }
-            Log.e(TAG, "Unknown link " + virtualViewId);
             return "";
         }
 
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PaginationModel.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PaginationModel.java
index 27f5f40..06e7505 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PaginationModel.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PaginationModel.java
@@ -17,13 +17,11 @@
 package androidx.pdf.viewer;
 
 import android.graphics.Rect;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.pdf.data.Range;
 import androidx.pdf.models.Dimensions;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.Preconditions;
 import androidx.pdf.util.Screen;
 
@@ -124,8 +122,11 @@
         Preconditions.checkArgument(numPages >= 0, "Num pages should be >= 0, " + numPages);
         if (isInitialized()) {
             // Already initialized, don't overwrite existing data.
-            ErrorLog.checkState(mMaxPages == numPages, TAG, "init",
-                    String.format("called with different value %d, was %d.", numPages, mMaxPages));
+            if (mMaxPages != numPages) {
+                throw new IllegalArgumentException(
+                        String.format("called with different value %d, was %d.", numPages,
+                                mMaxPages));
+            }
             return;
         }
 
@@ -174,18 +175,13 @@
     public void addPage(int pageNum, @NonNull Dimensions pageSize) {
         Preconditions.checkNotNull(pageSize);
         if (pageNum < mSize) {
-            ErrorLog.log(TAG, "addPage", String.format("ignored add page#%d < %d", pageNum, mSize));
             return;
         }
         if (pageNum >= mMaxPages) {
-            ErrorLog.log(TAG, "addPage",
-                    String.format("cant add page - not initialized?" + "page#%d >= maxpages:%d",
-                            pageNum, mMaxPages));
             return;
         }
         for (int i = mSize; i < pageNum; i++) {
             // Edge case: there are missing pages. Create them temporarily as clones of this one.
-            ErrorLog.log(TAG, "Backfill page# " + i);
             mPages[i] = pageSize;
         }
         mPages[pageNum] = pageSize;
@@ -203,8 +199,7 @@
         int p = 0;
         while (p < mSize - 1) {
             if (mPages[p] == null) {
-                ErrorLog.logAndThrow(TAG, "computeTops",
-                        String.format("Missing page %d in (0,%d)", p, mSize));
+                throw new RuntimeException(String.format("Missing page %d in (0,%d)", p, mSize));
             }
             mPageStops[p + 1] = mPageStops[p] + mPages[p].getHeight() + 2 * mPageSpacingPx;
             p++;
@@ -297,7 +292,6 @@
         mTempViewArea.set(viewArea);
         if (!mTempViewArea.intersect(
                 0, 0, getWidth(), getEstimatedFullHeight())) { // Modifies tempViewArea.
-            Log.w(TAG, String.format("PaginationModel is outside view area. %s", mTempViewArea));
         }
         if (!mTempViewArea.equals(this.mViewArea)) {
             this.mViewArea.set(mTempViewArea);
@@ -434,11 +428,6 @@
     /** Just makes sure to clear any observers that have been set. */
     @Override
     protected void finalize() throws Throwable {
-        if (!mObservers.isEmpty()) {
-            ErrorLog.log(TAG, String.format(
-                    "PaginationModel still has %d registered observers during garabage "
-                            + "collection. They" + " will be removed.", mObservers.size()));
-        }
         mObservers.clear();
         super.finalize();
     }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PdfViewer.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PdfViewer.java
index 1176a3c..83e38a3 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PdfViewer.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/PdfViewer.java
@@ -24,13 +24,13 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -69,7 +69,6 @@
 import androidx.pdf.models.PageSelection;
 import androidx.pdf.models.SelectionBoundary;
 import androidx.pdf.util.CycleRange;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.ExternalLinks;
 import androidx.pdf.util.GestureTracker;
 import androidx.pdf.util.GestureTracker.GestureHandler;
@@ -324,6 +323,7 @@
 
         mPageIndicator = new PageIndicator(getActivity(), mFastScrollView);
         applyReservedSpace();
+        adjustZoomViewMargins();
         mFastscrollerPositionObserver.onChange(null, mFastScrollView.getScrollerPositionY().get());
         mFastscrollerPositionObserverKey =
                 mFastScrollView.getScrollerPositionY().addObserver(mFastscrollerPositionObserver);
@@ -403,6 +403,30 @@
         mZoomViewBasePaddingSaved = true;
     }
 
+    /**
+     * Adjusts the horizontal margins (left and right padding) of the ZoomView based on the
+     * screen width to optimize the display of PDF content.
+     *
+     * This method applies different margin values depending on the screen size:
+     * - For screens with a screen width of 840dp or greater, a larger margin is applied
+     * to enhance readability on larger displays.
+     * - For screens with a screen width < 840dp, no margin is used to
+     * maximize the use of available space.
+     *
+     * This dynamic adjustment is achieved through the use of resource qualifiers (values-w840dp)
+     * that define different margin values for different screen sizes.
+     *
+     * Note: This method does not affect the top or bottom padding of the ZoomView.
+     */
+    private void adjustZoomViewMargins() {
+        int margin = getResources().getDimensionPixelSize(R.dimen.viewer_doc_padding_x);
+
+        mZoomView.setPadding(margin,
+                mZoomView.getPaddingTop(),
+                margin,
+                mZoomView.getPaddingBottom());
+    }
+
     @Override
     public void onActivityCreated(@NonNull Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
@@ -420,7 +444,6 @@
 
         // TODO: StrictMode- disk read 58ms.
         int lengthMb = StrictModeUtils.bypassAndReturn(() -> (int) (contents.length() >> 20));
-        Log.v(TAG, "File length in MB: " + lengthMb);
         createContentModel(
                 PdfLoader.create(
                         getActivity().getApplicationContext(),
@@ -433,7 +456,6 @@
             int layoutReach = savedState.getInt(KEY_LAYOUT_REACH);
             mEditingAuthorized = savedState.getBoolean(KEY_EDITING_AUTHORIZED);
             mInitialPageLayoutReach = Math.max(mInitialPageLayoutReach, layoutReach);
-            Log.v(TAG, "Restore current reach " + mInitialPageLayoutReach);
         }
     }
 
@@ -568,12 +590,17 @@
     @Override
     public void onSaveInstanceState(@NonNull Bundle outState) {
         outState.putInt(KEY_LAYOUT_REACH, mPageLayoutReach);
-        Log.v(TAG, "Saved current reach " + mPageLayoutReach);
 
         outState.putBoolean(KEY_EDITING_AUTHORIZED, mEditingAuthorized);
     }
 
     @Override
+    public void onConfigurationChanged(@NonNull Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        adjustZoomViewMargins();
+    }
+
+    @Override
     public long getContentLength() {
         return getPageCount();
     }
@@ -597,7 +624,6 @@
             validateFileUri(fileUri);
         } catch (SecurityException e) {
             // TODO Toaster.LONG.popToast(this, R.string.problem_with_file);
-            Log.e(TAG, e.getMessage());
             finishActivity();
         }
 
@@ -636,8 +662,7 @@
                     }
 
                     @Override
-                    public void failed(Throwable thrown) {
-                        ErrorLog.log(TAG, "fetchFile:" + fileUri.getScheme(), thrown);
+                    public void failed(@NonNull Throwable thrown) {
                         finishActivity();
                     }
 
@@ -713,7 +738,6 @@
      */
     private void layoutPages(int untilPage) {
         if (mPdfLoader == null) {
-            ErrorLog.log(TAG, "ERROR Can't layout pages as no pdfLoader " + mPageLayoutReach);
             return;
         }
         boolean pushed = false;
@@ -724,10 +748,6 @@
             requestLayoutPage++;
             pushed = true;
         }
-
-        if (pushed) {
-            Log.v(TAG, "Pushed the boundaries of known pages to " + requestLayoutPage);
-        }
     }
 
     private PageView createPage(final int pageNum) {
@@ -735,25 +755,26 @@
                 new BitmapSource() {
 
                     @Override
-                    public void requestPageBitmap(Dimensions pageSize,
+                    public void requestPageBitmap(@NonNull Dimensions pageSize,
                             boolean alsoRequestingTiles) {
                         mPdfLoader.loadPageBitmap(pageNum, pageSize);
                     }
 
                     @Override
-                    public void requestNewTiles(Dimensions pageSize, Iterable<TileInfo> tiles) {
+                    public void requestNewTiles(@NonNull Dimensions pageSize,
+                            @NonNull Iterable<TileInfo> tiles) {
                         mPdfLoader.loadTileBitmaps(pageNum, pageSize, tiles);
                     }
 
                     @Override
-                    public void cancelTiles(Iterable<Integer> tileIds) {
+                    public void cancelTiles(@NonNull Iterable<Integer> tileIds) {
                         mPdfLoader.cancelTileBitmaps(pageNum, tileIds);
                     }
                 };
         Dimensions dimensions = mPaginationModel.getPageSize(pageNum);
         PageView pageView =
                 PageViewFactory.createPageView(
-                        getActivity(),
+                        requireActivity(),
                         pageNum,
                         dimensions,
                         bitmapSource,
@@ -814,6 +835,7 @@
     }
 
     private void loadPageAssets(ZoomScroll position) {
+        Range oldVisiblePages = mVisiblePages;
 
         // 1. Refresh visible pages and view area.
         mVisiblePages = computeVisibleRange(position);
@@ -1172,12 +1194,12 @@
         }
 
         @Override
-        public boolean onDown(MotionEvent e) {
+        public boolean onDown(@NonNull MotionEvent e) {
             return true;
         }
 
         @Override
-        public boolean onSingleTapConfirmed(MotionEvent e) {
+        public boolean onSingleTapConfirmed(@NonNull MotionEvent e) {
             return handleSingleTapNoFormFilling(e);
         }
 
@@ -1383,7 +1405,7 @@
                     }
 
                     @Override
-                    public void documentNotLoaded(PdfStatus status) {
+                    public void documentNotLoaded(@NonNull PdfStatus status) {
                         if (viewState().get() != ViewState.NO_VIEW) {
                             dismissPasswordDialog();
                             if (getArguments().getBoolean(KEY_QUIT_ON_ERROR)) {
@@ -1434,7 +1456,7 @@
                     }
 
                     @Override
-                    public void setPageDimensions(int pageNum, Dimensions dimensions) {
+                    public void setPageDimensions(int pageNum, @NonNull Dimensions dimensions) {
                         if (viewState().get() != ViewState.NO_VIEW) {
                             mPaginationModel.addPage(pageNum, dimensions);
                             mPageLayoutReach = mPaginationModel.getSize();
@@ -1488,14 +1510,15 @@
                     }
 
                     @Override
-                    public void setTileBitmap(int pageNum, TileInfo tileInfo, Bitmap bitmap) {
+                    public void setTileBitmap(int pageNum, @NonNull TileInfo tileInfo,
+                            @NonNull Bitmap bitmap) {
                         if (viewState().get() != ViewState.NO_VIEW && isPageCreated(pageNum)) {
                             getPage(pageNum).getPageView().setTileBitmap(tileInfo, bitmap);
                         }
                     }
 
                     @Override
-                    public void setPageBitmap(int pageNum, Bitmap bitmap) {
+                    public void setPageBitmap(int pageNum, @NonNull Bitmap bitmap) {
                         // We announce that the viewer is ready as soon as a bitmap is loaded
                         // (not before).
                         if (mViewState.get() == ViewState.VIEW_CREATED) {
@@ -1508,14 +1531,15 @@
                     }
 
                     @Override
-                    public void setPageText(int pageNum, String text) {
+                    public void setPageText(int pageNum, @NonNull String text) {
                         if (viewState().get() != ViewState.NO_VIEW && isPageCreated(pageNum)) {
                             getPage(pageNum).getPageView().setPageText(text);
                         }
                     }
 
                     @Override
-                    public void setSearchResults(String query, int pageNum, MatchRects matches) {
+                    public void setSearchResults(@NonNull String query, int pageNum,
+                            @NonNull MatchRects matches) {
                         if (viewState().get() != ViewState.NO_VIEW && query.equals(
                                 mSearchModel.query().get())) {
                             mSearchModel.updateMatches(query, pageNum, matches);
@@ -1546,7 +1570,7 @@
                     }
 
                     @Override
-                    public void setPageUrlLinks(int pageNum, LinkRects links) {
+                    public void setPageUrlLinks(int pageNum, @NonNull LinkRects links) {
                         if (viewState().get() != ViewState.NO_VIEW && links != null
                                 && isPageCreated(pageNum)) {
                             getPage(pageNum).setPageUrlLinks(links);
@@ -1554,7 +1578,7 @@
                     }
 
                     @Override
-                    public void setPageGotoLinks(int pageNum, List<GotoLink> links) {
+                    public void setPageGotoLinks(int pageNum, @NonNull List<GotoLink> links) {
                         if (viewState().get() != ViewState.NO_VIEW && isPageCreated(pageNum)) {
                             getPage(pageNum).setPageGotoLinks(links);
                         }
@@ -1582,7 +1606,7 @@
                      * appropriate page view to redraw them.
                      */
                     @Override
-                    public void setInvalidRects(int pageNum, List<Rect> invalidRects) {
+                    public void setInvalidRects(int pageNum, @NonNull List<Rect> invalidRects) {
                         if (viewState().get() != ViewState.NO_VIEW && isPageCreated(pageNum)) {
                             if (invalidRects == null || invalidRects.isEmpty()) {
                                 return;
@@ -1666,7 +1690,6 @@
 
     /**
      * Set up the find in file menu.
-     * @param visibility
      */
     public void setFindInFileView(boolean visibility) {
         if (visibility) {
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/Viewer.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/Viewer.java
index a5600a5..64a949d 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/Viewer.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/Viewer.java
@@ -18,7 +18,6 @@
 
 import android.annotation.SuppressLint;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -29,7 +28,6 @@
 import androidx.annotation.RestrictTo;
 import androidx.fragment.app.Fragment;
 import androidx.pdf.data.DisplayData;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.ObservableValue;
 import androidx.pdf.util.Observables;
 import androidx.pdf.util.Observables.ExposedValue;
@@ -154,36 +152,28 @@
     }
 
     @Override
-    public void onCreate(@NonNull Bundle savedInstanceState) {
+    public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        if (mEventlog.length() > 1) { // 'B' is logged before onCreate.
-            log('<', "Reuse an existing instance: " + getEventlog());
-        } else {
-            log('<', "onCreate");
-        }
 
         // editFabTarget = new BaseViewerEditFabTargetImpl(requireActivity(), this);
     }
 
     @Nullable
     @Override
-    public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container,
-            @NonNull Bundle savedState) {
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedState) {
         if (container == null) {
             // Don't throw an exception here, as this may happen during restoreInstanceState for
             // Viewers that we don't need anymore.
-            ErrorLog.log(getTag(), "Can't recreate Viewer, make sure the file frame exists.");
             return null;
         }
         this.mContainer = container;
-        log('V', "onCreateView " + savedState);
         return null;
     }
 
     @Override
-    public void onActivityCreated(@NonNull Bundle savedInstanceState) {
+    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        log('A', "onActivityCreated " + mViewState.get());
         if (mViewState.get() == ViewState.NO_VIEW || mViewState.get() == ViewState.ERROR) {
             mViewState.set(ViewState.VIEW_CREATED);
         }
@@ -192,7 +182,6 @@
     @Override
     public void onStart() {
         super.onStart();
-        log('S', "onStart ");
         mStarted = true;
         if (mDelayedEnter || mOnScreen) {
             onEnter();
@@ -205,9 +194,6 @@
      * when the Viewer is started.
      */
     public void postEnter() {
-        if (mDelayedEnter) {
-            Log.w(getLogTag(), "Already had delayed enter");
-        }
 
         mOnScreen = true;
         if (mStarted) {
@@ -227,7 +213,6 @@
     /** Called after this viewer enters the screen and becomes visible. */
     @CallSuper
     protected void onEnter() {
-        log('E', "onEnter");
         // TODO: Track file opened event, content length and view progress.
         participateInAccessibility(true);
     }
@@ -235,7 +220,6 @@
     /** Called after this viewer exits the screen and becomes invisible to the user. */
     @CallSuper
     protected void onExit() {
-        log('e', "onExit");
         // TODO: Track file closed event, content length and view progress.
         participateInAccessibility(false);
     }
@@ -245,7 +229,6 @@
         if (mOnScreen) {
             onExit();
         }
-        log('s', "onStop");
         mStarted = false;
         super.onStop();
     }
@@ -254,7 +237,6 @@
     public void onDestroyView() {
         destroyView();
         mContainer = null;
-        log('v', "onDestroyView");
         super.onDestroyView();
     }
 
@@ -289,7 +271,6 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
-        log('>', "Destroying: " + getEventlog());
     }
 
     /**
@@ -331,13 +312,6 @@
     /** Save the {@link DisplayData}'s content reference (not the contents itself) to arguments. */
     protected void saveToArguments(@NonNull DisplayData data) {
         getArguments().putBundle(KEY_DATA, data.asBundle());
-        log('B', "Saved arg " + data.asBundle());
-    }
-
-    /** Logs a step in the life-cycle of this Viewer (e.g. onStop). */
-    protected void log(char tag, @NonNull String step) {
-        Log.v(getLogTag(), "Lifecycle: " + step);
-        mEventlog.append(tag);
     }
 
     /** Returns a compact event log for this Viewer that helps investigating lifecycle issues. */
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractPdfTask.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractPdfTask.java
index 1f575e0..fafea44 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractPdfTask.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractPdfTask.java
@@ -17,15 +17,12 @@
 package androidx.pdf.viewer.loader;
 
 import android.os.RemoteException;
-import android.util.Log;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.pdf.models.PdfDocumentRemote;
 import androidx.pdf.pdflib.PdfDocumentRemoteProto;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.ThreadUtils;
-import androidx.pdf.util.Timer;
 
 /**
  * Performs one command on the PDF Document asynchronously, like rendering a page's bitmap or
@@ -88,8 +85,6 @@
     }
 
     protected final T findPdfAndDoInBackground() {
-        Log.v(getLogTag(), "Start task: " + this);
-        Timer timer = Timer.start();
         T result;
         try {
             PdfDocumentRemote pdfDocument = getPdfDocument();
@@ -98,21 +93,13 @@
                             ? doInBackground(new PdfDocumentRemoteProto(pdfDocument))
                             : doInBackground();
             if (result != null) {
-                Log.v(getLogTag(),
-                        "Finish task: " + this + ", result = " + resultToString(result)
-                                + ", time = "
-                                + timer.time() + "ms");
                 return result;
-            } else {
-                Log.w(getLogTag(),
-                        "Task " + this + " result is null (time=" + timer.time() + "ms).");
             }
         } catch (RemoteException e) {
             mReportError = true;
-            ErrorLog.log(getLogTag(), "doInBackground", e);
         } catch (RuntimeException rx) {
             mReportError = true;
-            ErrorLog.logAndThrow(getLogTag(), "doInBackground", rx);
+            throw rx;
         } finally {
             mPdfLoader.releasePdfDocument();
         }
@@ -146,7 +133,6 @@
      * @return The result of the command. Returning @code{null} cancels the task.
      */
     protected T doInBackground() {
-        Log.w(getLogTag(), "No PdfDocumentRemote available... service crashed ? -- Try reconnect.");
         mPdfLoader.reconnect();
         return null;
     }
@@ -198,15 +184,9 @@
     }
 
     private void onCancelled() {
-        Log.v(getLogTag(), "Task cancelled: " + this);
         if (mReportError) {
             reportError(mPdfLoader.getCallbacks());
         }
         cleanup();
     }
-
-    // Implementations may override to get better logging of results.
-    protected String resultToString(T result) {
-        return result == null ? "null" : result.toString();
-    }
 }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractWriteTask.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractWriteTask.java
index 8881812..ce69c0cb 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractWriteTask.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/AbstractWriteTask.java
@@ -18,11 +18,9 @@
 
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.util.Log;
 
 import androidx.annotation.RestrictTo;
 import androidx.pdf.pdflib.PdfDocumentRemoteProto;
-import androidx.pdf.util.ErrorLog;
 
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
@@ -57,7 +55,6 @@
                 return false;
             }
         } catch (IOException e) {
-            Log.w(getLogTag(), "Error creating a file descriptor from open file.", e);
             return false;
         }
 
@@ -68,7 +65,6 @@
                 return false;
             }
         } catch (IOException e) {
-            ErrorLog.log(getLogTag(), "Error creating ParcelFileDescriptor.", e);
             return false;
         }
 
@@ -77,13 +73,13 @@
         try {
             parcelFileDescriptor.close();
         } catch (IOException e) {
-            ErrorLog.log(getLogTag(), "Error closing parcelFileDescriptor.", e);
+            // TODO: Handle exceptions by sending back error codes
         }
 
         try {
             mFileOutputStream.close();
         } catch (IOException e) {
-            ErrorLog.log(getLogTag(), "Error closing fileOutputStream.", e);
+            // TODO: Handle exceptions by sending back error codes
         }
 
         return result;
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfConnection.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfConnection.java
index 0b93d50..5758c6a 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfConnection.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfConnection.java
@@ -22,13 +22,11 @@
 import android.content.ServiceConnection;
 import android.net.Uri;
 import android.os.IBinder;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.pdf.models.PdfDocumentRemote;
 import androidx.pdf.pdflib.PdfDocumentService;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.Preconditions;
 
 import java.util.concurrent.locks.Condition;
@@ -108,9 +106,7 @@
      * </ul>
      */
     public void setDocumentLoaded() {
-        if (mPdfRemote == null) {
-            ErrorLog.log(TAG, "setDocumentLoaded", "Document loaded but Remote == null");
-        } else {
+        if (mPdfRemote != null) {
             mHasSuccessfullyConnectedEver = true;
             mIsLoaded = true;
         }
@@ -118,7 +114,6 @@
 
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
-        Log.i(TAG, String.format("Service connected %s", name));
         mConnected = true;
         mIsLoaded = false;
         mLock.lock();
@@ -139,25 +134,17 @@
         if (mCurrentTask != null) {
             // A task was in progress, we want to report the crash and restart the service.
             mNumCrashes++;
-            ErrorLog.log(mCurrentTask, "Service crash ~ " + ErrorLog.bracketValue(mNumCrashes));
             TaskDenyList.maybeDenyListTask(mCurrentTask);
 
             // We have never connected to this document, and we have crashed repeatedly.
             if (!mHasSuccessfullyConnectedEver && mNumCrashes >= MAX_CONNECT_RETRIES) {
-                Log.w(TAG,
-                        "Failed to ever connect successfully - stuck in a crash loop, "
-                                + "disconnecting.");
                 disconnect();
                 if (mOnConnectFailure != null) {
                     mOnConnectFailure.run();
-                } else {
-                    ErrorLog.logAndAlwaysThrow(TAG, "onServiceDisconnected",
-                            new RepeatedCrashException());
                 }
             }
         } else {
             // No task was in progress, probably just system cleaning up idle resources.
-            Log.d(TAG, "Service was killed by system, let it go. " + name);
             disconnect();
         }
 
@@ -167,7 +154,6 @@
         mLock.lock();
         try {
             mPdfRemote = null;
-            Log.i(TAG, "Service disconnected for task " + mCurrentTask);
         } finally {
             mLock.unlock();
         }
@@ -180,19 +166,14 @@
         Intent intent = new Intent(mContext, PdfDocumentService.class);
         // Data is only required here to make sure we start a new service per document.
         intent.setData(uri);
-        Log.d(TAG, "Connecting to service " + uri);
         mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
     }
 
     void disconnect() {
         if (mConnected) {
-            Log.d(TAG, "Disconnecting service.");
             mContext.unbindService(this);
             mConnected = false;
         }
     }
 
-    private static class RepeatedCrashException extends RuntimeException {
-    }
-
 }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfLoader.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfLoader.java
index 9ec260d..2884cd6 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfLoader.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfLoader.java
@@ -34,7 +34,6 @@
 import androidx.pdf.models.SelectionBoundary;
 import androidx.pdf.pdflib.PdfDocumentRemoteProto;
 import androidx.pdf.util.BitmapRecycler;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.TileBoard.TileInfo;
 
 import java.io.FileOutputStream;
@@ -375,7 +374,6 @@
         protected PdfStatus doInBackground(PdfDocumentRemoteProto pdfDocument)
                 throws RemoteException {
             if (mData == null) {
-                ErrorLog.log(TAG, "Can't load file (data unavailable)");
                 return PdfStatus.FILE_ERROR;
             }
 
@@ -385,7 +383,6 @@
             ParcelFileDescriptor fd = mData.openFd(mOpener);
 
             if (fd == null || fd.getFd() == -1) {
-                ErrorLog.log(TAG, "Can't load file (doesn't open) ", mData.toString());
                 return PdfStatus.FILE_ERROR;
             }
             int statusIndex = pdfDocument.getPdfDocumentRemote().create(fd, mPassword);
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfPageLoader.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfPageLoader.java
index 113b60a..61cddc6 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfPageLoader.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfPageLoader.java
@@ -20,7 +20,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.os.RemoteException;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
@@ -289,7 +288,6 @@
     private void setBroken() {
         // TODO: Track the broken state of the FileInfo object.
         if (!mIsBroken) {
-            Log.w(TAG, String.format("Page %d is broken", mPageNum));
             mIsBroken = true;
         }
     }
@@ -486,11 +484,6 @@
         public String toString() {
             return String.format("GetPageTextTask(page=%d)", mPageNum);
         }
-
-        @Override
-        public String resultToString(String result) {
-            return result.length() + "characters";
-        }
     }
 
     /** AsyncTask for searching a page's text. */
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfTaskExecutor.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfTaskExecutor.java
index 3a1516b..20bc2745 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfTaskExecutor.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/PdfTaskExecutor.java
@@ -16,12 +16,9 @@
 
 package androidx.pdf.viewer.loader;
 
-import android.util.Log;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.ThreadUtils;
 
 import java.util.Iterator;
@@ -69,7 +66,6 @@
                 // Could wait indefinitely for a notify(), but this is safer.
                 this.wait(10000);  // Wait 10 seconds.
             } catch (InterruptedException e) {
-                ErrorLog.log(TAG, "Unexpected interrupt while waiting for next task", e);
                 throw new RuntimeException(e);
             }
         }
@@ -83,7 +79,6 @@
     /** Schedule the given task. */
     public void schedule(@NonNull AbstractPdfTask<?> task) {
         synchronized (this) {
-            Log.v(TAG, "Schedule task: " + task.toString());
             mScheduledTasks.add(task);
             this.notifyAll();
         }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/WeakPdfLoaderCallbacks.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/WeakPdfLoaderCallbacks.java
index 2b8f087..1553092 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/WeakPdfLoaderCallbacks.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/viewer/loader/WeakPdfLoaderCallbacks.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Bitmap;
 import android.graphics.Rect;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
@@ -182,9 +181,6 @@
 
     private PdfLoaderCallbacks getCallbacks() {
         PdfLoaderCallbacks callbacks = mDelegate.get();
-        if (callbacks == null) {
-            Log.w(TAG, "Callbacks have been garbage collected - nothing to do.");
-        }
         return callbacks;
     }
 }
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/MosaicView.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/MosaicView.java
index bd7f55f..07f2d10 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/MosaicView.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/MosaicView.java
@@ -28,7 +28,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.MotionEvent;
@@ -41,7 +40,6 @@
 import androidx.annotation.RestrictTo;
 import androidx.pdf.models.Dimensions;
 import androidx.pdf.util.BitmapRecycler;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.Preconditions;
 import androidx.pdf.util.RectUtils;
 import androidx.pdf.util.TileBoard;
@@ -195,9 +193,6 @@
     public void init(@NonNull Dimensions dimensions, @NonNull BitmapRecycler bitmapRecycler,
             @NonNull BitmapSource bitmapSource) {
         mBounds.set(0, 0, dimensions.getWidth(), dimensions.getHeight());
-        if (mBounds.isEmpty()) {
-            ErrorLog.log(TAG, "Page with empty bounds");
-        }
         this.mBitmapRecycler = bitmapRecycler;
         this.mBitmapSource = bitmapSource;
         requestLayout();
@@ -305,11 +300,6 @@
         if (mTileBoard != null) {
             float tileArea = (float) RectUtils.area(mBounds) / newBoard.numTiles();
             if (zoom > mBaseZoom && tileArea < 1) {
-                float currentTileArea = (float) RectUtils.area(mBounds) / mTileBoard.numTiles();
-                Log.d(getLogTag(), String.format(
-                        "Zoom at %.0f, tile base area would drop to %.2f px^2, "
-                                + "current tiling is probably good enough (%.2f).", zoom, tileArea,
-                        currentTileArea));
                 return;
             }
         }
@@ -336,9 +326,6 @@
                             count++;
                         }
                         log.append("]");
-                        Log.v(getLogTag(),
-                                String.format("Cancel %d tiles %s (%d)", count, log.toString(),
-                                        mTiles.size()));
                         mBitmapSource.cancelTiles(tileIds);
                     }
                 });
@@ -445,8 +432,7 @@
                         ? limitBitmapWidth(mRequestedWidth, mMaxBgPageSize)
                         : limitBitmapWidth(mRequestedWidth, mMaxBitmapSize);
         if (cappedWidth <= 0) {
-            ErrorLog.logAndThrow(TAG, "requestDrawAtWidth",
-                    String.format("Invalid width %s", cappedWidth));
+            throw new RuntimeException(String.format("Invalid width %s", cappedWidth));
         }
         return cappedWidth;
     }
@@ -486,7 +472,7 @@
             mRequestedWidth = (int) (zoom * mBounds.width());
             int cappedWidth = limitBitmapWidth(mRequestedWidth, mMaxBgPageSize);
             if (cappedWidth <= 0) {
-                ErrorLog.logAndThrow(TAG, "requestFastDrawAtWidth",
+                throw new RuntimeException(
                         String.format("Invalid width cap:%s z:%s", cappedWidth, zoom));
             } else {
                 Dimensions pageSize = getPageDimensionsAtWidth(cappedWidth);
@@ -587,8 +573,6 @@
                     }
                 }
                 sb.append("]");
-                Log.v(getLogTag(), String.format("Add %d tiles %s (%d) ", count, sb.toString(),
-                        mTiles.size()));
                 callback.requestNewTiles(newTiles);
             }
 
@@ -605,13 +589,9 @@
                         tv.reset();
                         removeView(tv);
                         mTiles.remove(tv.mTileInfo.getIndex());
-                    } else {
-                        ErrorLog.log(getLogTag(), "Dispose NULL Tile View @ " + k);
                     }
                 }
                 sb.append("]");
-                Log.v(getLogTag(), String.format("Remove %d tiles %s (%d) ", count, sb.toString(),
-                        mTiles.size()));
             }
         });
     }
@@ -623,8 +603,6 @@
             TileView tile = getTileByIndex(tileInfo.getIndex());
             if (tile != null) {
                 tile.setBitmap(tileInfo, tileBitmap);
-            } else {
-                ErrorLog.log(getLogTag(), "No tile for " + tileInfo);
             }
         } else {
             mBitmapRecycler.discardBitmap(tileBitmap);
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/SearchEditText.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/SearchEditText.java
index a8bf791..153fb10 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/SearchEditText.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/SearchEditText.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.inputmethod.InputMethodManager;
 
 import androidx.annotation.NonNull;
@@ -64,7 +63,6 @@
     protected void onFocusChanged(boolean focused, int direction,
             @NonNull Rect previouslyFocusedRect) {
         super.onFocusChanged(focused, direction, previouslyFocusedRect);
-        Log.w(TAG, "focused=" + focused + " direction=" + direction);
         if (focused) {
             post(mShowImeRunnable);
         } else {
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/TileView.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/TileView.java
index e7e0e65..acd2797 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/TileView.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/TileView.java
@@ -26,7 +26,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
-import androidx.pdf.util.ErrorLog;
 import androidx.pdf.util.Preconditions;
 import androidx.pdf.util.TileBoard.TileInfo;
 
@@ -52,9 +51,6 @@
     void setBitmap(TileInfo tileInfo, Bitmap bitmap) {
         Preconditions.checkArgument(Objects.equals(tileInfo, this.mTileInfo),
                 String.format("Got wrong tileId %s : %s", this.mTileInfo, tileInfo));
-        if (this.mBitmap != null) {
-            ErrorLog.log(getLogTag(), "Used tile receiving new bitmap " + tileInfo);
-        }
         this.mBitmap = bitmap;
         // This View is already properly laid out, but without this requestLayout, it doesn't draw.
         requestLayout();
diff --git a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/ZoomView.java b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/ZoomView.java
index 37becf2..faa86b3 100644
--- a/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/ZoomView.java
+++ b/pdf/pdf-viewer/src/main/java/androidx/pdf/widget/ZoomView.java
@@ -31,7 +31,6 @@
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
 import android.view.View;
@@ -420,10 +419,9 @@
     }
 
     /** Reports the current position to listeners. */
-    private void reportPosition(boolean stable, String logCause) {
+    private void reportPosition(boolean stable) {
         ZoomScroll newPos = new ZoomScroll(getZoom(), getScrollX(), getScrollY(), stable);
         if (!Objects.equals(mPosition.get(), newPos)) {
-            Log.v(TAG, String.format("Report position %s: %s", logCause, newPos));
             mPosition.set(newPos);
         }
     }
@@ -495,7 +493,6 @@
 
         // Need to flip this to true if we think onLayout changed the position of anything.
         boolean shouldConstrainPosition = false;
-        String reportPositionCause = null;
 
         // 1) Changes to the contents (e.g. init, new contents appended):
         // Update contentRawBounds in all cases (even when !changed) because contentView's layout
@@ -507,12 +504,6 @@
             int prevHeight = mContentRawBounds.height();
             mContentRawBounds.set(0, 0, mContentView.getWidth(), mContentView.getHeight());
 
-            Log.v(
-                    TAG,
-                    String.format(
-                            "Layout: Content changed Raw bounds = %s Scale = %s Scroll = %s %s",
-                            mContentRawBounds, getZoom(), getScrollX(), getScrollY()));
-
             if (!mViewport.isEmpty() && prevWidth > 0 && prevHeight > 0) {
                 // Might need to move the viewport depending on the ContentResizedMode
                 // configuration.
@@ -538,14 +529,6 @@
                 // No need to adjust v-scroll when height changes (ie more pages are added to the
                 // bottom).
                 shouldConstrainPosition = true;
-                reportPositionCause =
-                        String.format(
-                                Locale.US,
-                                "Content size changed from (%d x %d) to (%d x %d)",
-                                prevWidth,
-                                prevHeight,
-                                mContentRawBounds.width(),
-                                mContentRawBounds.height());
             }
         }
 
@@ -564,10 +547,6 @@
                         right - getPaddingRight() - getPaddingLeft() - left,
                         bottom - getPaddingBottom() - getPaddingTop() - top);
                 shouldConstrainPosition = true;
-                reportPositionCause =
-                        String.format(
-                                "Viewport init = %s Scale = %s Scroll = %s %s",
-                                mViewport, getZoom(), getScrollX(), getScrollY());
 
                 mViewportInitialized = true;
             } else { // Some other layout trigger - could be a configuration change (rotation)
@@ -598,10 +577,6 @@
 
                 centerAt(lookAtPoint.x, lookAtPoint.y);
                 shouldConstrainPosition = true;
-                reportPositionCause =
-                        String.format(
-                                "Viewport changed = %s Scale = %s Scroll = %s %s",
-                                mViewport, getZoom(), getScrollX(), getScrollY());
             }
         }
 
@@ -612,20 +587,17 @@
                 if (!mInitialZoomDone) {
                     setZoom(getInitialZoom(), 0, 0); // Stay at the top of the document.
                     shouldConstrainPosition = true;
-                    reportPositionCause = String.format("Initial zoom: %s", getZoom());
                 }
             } else if (restoreSavedPosition()) {
                 shouldConstrainPosition = true;
-                reportPositionCause = String.format("Restored");
             }
             mInitialZoomDone = true;
         }
 
         if (shouldConstrainPosition) {
             constrainPosition();
-            final String cause = reportPositionCause;
             // Report position needs to be posted because it may trigger requestLayout().
-            ThreadUtils.postOnUiThread(() -> reportPosition(STABLE, cause));
+            ThreadUtils.postOnUiThread(() -> reportPosition(STABLE));
         }
     }
 
@@ -717,12 +689,12 @@
         if (mScroller.computeScrollOffset()) {
             // Fling does not support overscroll. It will simply not scroll past an edge.
             mScroller.apply(this);
-            reportPosition(UNSTABLE, "computeScroll");
+            reportPosition(UNSTABLE);
 
             // Need to invalidate even when delta == 0 to let the scroller properly finish.
             invalidate();
         } else if (mIsFling) {
-            reportPosition(STABLE, "Finish Fling");
+            reportPosition(STABLE);
             mIsFling = false;
         }
     }
@@ -776,7 +748,7 @@
 
         scrollTo(left, top);
         constrainPosition();
-        reportPosition(STABLE, "centerAt");
+        reportPosition(STABLE);
     }
 
     /**
@@ -852,7 +824,7 @@
                     public void onAnimationEnd(Animator animation) {
                         mZoomScrollAnimation = null;
                         constrainPosition();
-                        reportPosition(STABLE, "zoomScrollAnimation end");
+                        reportPosition(STABLE);
                     }
                 });
         mZoomScrollAnimation = animatorSet;
@@ -863,7 +835,7 @@
     public void scrollTo(int left, int top, boolean stable) {
         scrollTo(left, top);
         constrainPosition();
-        reportPosition(stable, "scrollTo" + (stable ? "Stable" : "Transient"));
+        reportPosition(stable);
     }
 
     public float getZoom() {
@@ -887,7 +859,6 @@
         mContentView.setScaleX(zoom);
         mContentView.setScaleY(zoom);
         scrollBy(deltaX, deltaY);
-        Log.v(TAG, String.format("After zoom (%s): (%s)", zoom, mContentRawBounds));
     }
 
     /**
@@ -961,7 +932,6 @@
             lookAtY = 0; // Stick to the top of the document if the layout changes while there.
         }
 
-        Log.v(TAG, String.format("lookAtPoint (%s %s)", lookAtX, lookAtY));
         return new PointF(lookAtX, lookAtY);
     }
 
@@ -985,7 +955,6 @@
         bundle.putParcelable(KEY_SUPER, super.onSaveInstanceState());
         if (mSaveState) {
             bundle.putBundle(KEY_POSITION, mPosition.get().asBundle());
-            Log.v(TAG, String.format("Saving position %s", mPosition.get()));
         }
         return bundle;
     }
@@ -1016,7 +985,6 @@
         // availableHeight will keep increasing with successive calls of this method. If we can't
         // restore now, we wait for the next call.
         int availableHeight = (int) (mContentRawBounds.height() * mPositionToRestore.zoom);
-        Log.v(TAG, String.format("Try Restore %s in %s", mPositionToRestore, availableHeight));
         if (mRestorePositionRunnable != null) {
             mHandler.removeCallbacks(mRestorePositionRunnable);
             mRestorePositionRunnable = null;
@@ -1032,12 +1000,11 @@
             mRestorePositionRunnable =
                     () -> {
                         restorePosition();
-                        reportPosition(STABLE, "Finish delayed Restore");
+                        reportPosition(STABLE);
                     };
             mHandler.postDelayed(mRestorePositionRunnable, 200);
             return false;
         } else {
-            Log.v(TAG, String.format("Restore %s in %s", mPositionToRestore, availableHeight));
             // That's a perfect restore, do it.
             restorePosition();
             return true;
@@ -1046,7 +1013,6 @@
 
     /** Restores the given position and reports it. */
     private void restorePosition() {
-        Log.v(TAG, String.format("Restoring position %s", mPositionToRestore));
         ZoomScroll restore = mPositionToRestore;
         mPositionToRestore = null;
         mRestorePositionRunnable = null;
@@ -1328,7 +1294,6 @@
                 if (totalScrollLength() > mMinScrollToSwitch
                         && Math.abs(mTotalY / mTotalX) < SCROLL_CORRECTION_RATIO) {
                     mStraightenCurrentVerticalScroll = false;
-                    Log.v(TAG, "Scroll correction switch");
                 } else {
                     // Ignore the horizontal component of the scroll.
                     dx = 0;
@@ -1337,7 +1302,7 @@
 
             scrollBy(dx, dy);
             constrainPosition();
-            reportPosition(UNSTABLE, "onScroll");
+            reportPosition(UNSTABLE);
 
             // For a pure scroll gesture (no zoom), if it reaches somewhat past an edge, pass the
             // gesture on to the parents.
@@ -1348,8 +1313,6 @@
                 if (shareOverscroll(axis, mOverScrollX, mOverScrollY)) {
                     // Scrolling past the bounds, so let the parent handle further scrolling if
                     // they want to.
-                    Log.v(TAG, String.format("Scroll past edge by (%s %s): ", mOverScrollX,
-                            mOverScrollY));
                     releaseGesture();
                     return false;
                 }
@@ -1376,7 +1339,7 @@
             if (newZoom != zoom) {
                 setZoom(newZoom, detector.getFocusX(), detector.getFocusY());
                 constrainPosition();
-                reportPosition(UNSTABLE, "onScale");
+                reportPosition(UNSTABLE);
             }
             return true;
         }
@@ -1392,12 +1355,12 @@
             switch (gesture) {
                 case ZOOM:
                     constrainPosition();
-                    reportPosition(STABLE, "Finish Scale");
+                    reportPosition(STABLE);
                     break;
                 case DRAG:
                 case DRAG_Y:
                 case DRAG_X:
-                    reportPosition(STABLE, "Finish scroll");
+                    reportPosition(STABLE);
                     break;
                 default:
                     // Double-tap is reported at the end of the animation. Nothing else. Keeps
@@ -1456,10 +1419,6 @@
             Rect content = contentPosition();
             if (mViewport.contains(content)) {
                 // content fits into the viewport: pan/fling are disabled.
-                Log.v(
-                        TAG,
-                        String.format("Abort fling at (%s %s) with v (%s %s) ", x, y, -velocityX,
-                                -velocityY));
                 return true;
             }
 
@@ -1481,12 +1440,6 @@
                 maxY = Math.max(0, content.height() - mViewport.height());
             }
 
-            Log.v(
-                    TAG,
-                    String.format(
-                            "Start fling at (%s %s) with v (%s %s) min (%s, %s) max (%s, %s)",
-                            x, y, -velocityX, -velocityY, minX, minY, maxX, maxY));
-
             mIsFling = true;
             mScroller.fling(x, y, (int) -velocityX, (int) -velocityY, minX, maxX, minY, maxY);
             invalidate();
diff --git a/pdf/pdf-viewer/src/main/res/layout/file_viewer_pdf.xml b/pdf/pdf-viewer/src/main/res/layout/file_viewer_pdf.xml
index 9206c1f..d47b623 100644
--- a/pdf/pdf-viewer/src/main/res/layout/file_viewer_pdf.xml
+++ b/pdf/pdf-viewer/src/main/res/layout/file_viewer_pdf.xml
@@ -25,8 +25,6 @@
         android:layout_height="match_parent"
         android:clipToPadding="false"
         android:paddingBottom="@dimen/viewer_doc_padding_y"
-        android:paddingLeft="@dimen/viewer_doc_padding_x"
-        android:paddingRight="@dimen/viewer_doc_padding_x"
         android:paddingTop="@dimen/viewer_doc_padding_y">
 
         <FrameLayout
diff --git a/pdf/pdf-viewer/src/main/res/values-w840dp/dimens.xml b/pdf/pdf-viewer/src/main/res/values-w840dp/dimens.xml
new file mode 100644
index 0000000..077536c
--- /dev/null
+++ b/pdf/pdf-viewer/src/main/res/values-w840dp/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+  <dimen name="viewer_doc_padding_x">80dp</dimen>
+</resources>
diff --git a/pdf/pdf-viewer/src/main/res/values/dimensions.xml b/pdf/pdf-viewer/src/main/res/values/dimensions.xml
index 5d49a23..4869951 100644
--- a/pdf/pdf-viewer/src/main/res/values/dimensions.xml
+++ b/pdf/pdf-viewer/src/main/res/values/dimensions.xml
@@ -19,7 +19,7 @@
     <dimen name="viewer_fastscroll_edge_offset">15dp</dimen>
     <dimen name="viewer_fastscroll_rounded_corner_radius">2dp</dimen>
     <dimen name="viewer_doc_padding_y">4dp</dimen>
-    <dimen name="viewer_doc_padding_x">16dp</dimen>
+    <dimen name="viewer_doc_padding_x">0dp</dimen>
     <dimen name="mtrl_min_touch_target_size">48dp</dimen>
 
     <dimen name="viewer_progress_bar_height">4dp</dimen>
diff --git a/pdf/pdf-viewer/src/test/java/androidx/pdf/mocks/MockBitmapParcel.java b/pdf/pdf-viewer/src/test/java/androidx/pdf/mocks/MockBitmapParcel.java
index d1918c1..01442a8 100644
--- a/pdf/pdf-viewer/src/test/java/androidx/pdf/mocks/MockBitmapParcel.java
+++ b/pdf/pdf-viewer/src/test/java/androidx/pdf/mocks/MockBitmapParcel.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Bitmap;
 import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 import androidx.pdf.util.BitmapParcel;
 
@@ -45,13 +44,11 @@
             while (channel.read(buffer) != -1) {
                 buffer.rewind();
                 bitmap.copyPixelsFromBuffer(buffer);
-//                buffer.rewind();
             }
             buffer.rewind();
             channel.close();
             sourceFd.close();
-        } catch (IOException e) {
-            Log.e("MockBitmapParcel", "Failed to close the FD", e);
+        } catch (IOException ignored) {
         }
     }
 }
diff --git a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/BitmapParcelTest.java b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/BitmapParcelTest.java
index bbdc579..91db95d 100644
--- a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/BitmapParcelTest.java
+++ b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/BitmapParcelTest.java
@@ -23,7 +23,6 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 import androidx.pdf.mocks.MockBitmapParcel;
 import androidx.pdf.test.R;
@@ -74,11 +73,6 @@
 
     private boolean validateBitmap(Bitmap bitmap) {
         boolean same = bitmap.sameAs(mSourceBitmap);
-        Log.i(
-                TAG,
-                String.format(
-                        "Compare bitmaps  %s = %s : %s",
-                        mSourceBitmap.getByteCount(), bitmap.getByteCount(), same));
         return same;
     }
 
diff --git a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/FutureValuesTest.java b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/FutureValuesTest.java
index 4640b3e4..c62fa9e 100644
--- a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/FutureValuesTest.java
+++ b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/FutureValuesTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
+import androidx.annotation.NonNull;
 import androidx.pdf.data.FutureValue;
 import androidx.pdf.data.FutureValue.Callback;
 import androidx.pdf.data.FutureValues;
@@ -78,7 +79,7 @@
                     }
 
                     @Override
-                    public void failed(Throwable thrown) {
+                    public void failed(@NonNull Throwable thrown) {
                         fail("Not expected to fail for ImmediateValue");
                     }
 
@@ -144,7 +145,7 @@
         deferredFutureValue.get(
                 new BlockingCallback<Integer>() {
                     @Override
-                    public void failed(Throwable thrown) {
+                    public void failed(@NonNull Throwable thrown) {
                         super.failed(thrown);
                         failureDetected[0] = true;
                     }
@@ -186,7 +187,7 @@
         deferredFutureValue.get(
                 new SimpleCallback<Integer>() {
                     @Override
-                    public void failed(Throwable thrown) {
+                    public void failed(@NonNull Throwable thrown) {
                         super.failed(thrown);
                         failureDetected[0] = true;
                     }
diff --git a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/GestureTrackerTest.java b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/GestureTrackerTest.java
index 4ca6d44..bf3bfe3 100644
--- a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/GestureTrackerTest.java
+++ b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/GestureTrackerTest.java
@@ -25,7 +25,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
-import android.util.Log;
 import android.view.MotionEvent;
 
 import androidx.pdf.util.GestureTracker.Gesture;
@@ -73,7 +72,6 @@
 
     @Test
     public void testDrag() {
-        Log.d(TAG, "Start test drag");
         for (MotionEvent event : dragSequence(0)) {
             mGestureTracker.feed(event, true);
         }
@@ -85,12 +83,10 @@
         verifyNoMoreInteractions(mGestureHandler);
         assertThat(capturedGesture.getValue()).isEqualTo(Gesture.DRAG_X);
         assertThat(mGestureTracker.matches(Gesture.DRAG_X)).isTrue();
-        Log.d(TAG, "End test drag");
     }
 
     @Test
     public void testSingleTap() {
-        Log.d(TAG, "Start test single tap");
         for (MotionEvent event : singleTapSequence(0)) {
             mGestureTracker.feed(event, true);
         }
@@ -116,12 +112,10 @@
         verifyNoMoreInteractions(mGestureHandler);
         assertThat(mGestureTracker.matches(Gesture.SINGLE_TAP)).isTrue();
         assertThat(capturedGesture.getValue()).isEqualTo(Gesture.SINGLE_TAP);
-        Log.d(TAG, "End test single tap");
     }
 
     @Test
     public void testDoubleTap() {
-        Log.d(TAG, "Start test double tap");
         for (MotionEvent event : singleTapSequence(0)) {
             mGestureTracker.feed(event, true);
         }
@@ -139,12 +133,10 @@
         verify(mGestureHandler).onGestureEnd(capturedGesture.capture());
         verifyNoMoreInteractions(mGestureHandler);
         assertThat(capturedGesture.getValue()).isEqualTo(Gesture.DOUBLE_TAP);
-        Log.d(TAG, "End test double tap");
     }
 
     @Test
     public void testTapDrag() {
-        Log.d(TAG, "Start test tap-drag (should not count as double-tap)");
         for (MotionEvent event : singleTapSequence(0)) {
             mGestureTracker.feed(event, true);
         }
@@ -162,12 +154,10 @@
         verify(mGestureHandler).onGestureEnd(capturedGesture.capture());
         verifyNoMoreInteractions(mGestureHandler);
         assertThat(capturedGesture.getValue()).isEqualTo(Gesture.DRAG_X);
-        Log.d(TAG, "End test tap-drag");
     }
 
     @Test
     public void testDragTap() {
-        Log.d(TAG, "Start test drag-tap (should not count as double-tap)");
         for (MotionEvent event : dragSequence(50)) {
             mGestureTracker.feed(event, true);
         }
@@ -185,7 +175,6 @@
         verify(mGestureHandler).onGestureEnd(capturedGesture.capture());
         verifyNoMoreInteractions(mGestureHandler);
         assertThat(capturedGesture.getValue()).isEqualTo(Gesture.DRAG_X);
-        Log.d(TAG, "End test drag-tap");
     }
 
     private static List<MotionEvent> dragSequence(final long downTime) {
diff --git a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/SettableFutureValueTest.java b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/SettableFutureValueTest.java
index b612c99..c8a5dae 100644
--- a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/SettableFutureValueTest.java
+++ b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/SettableFutureValueTest.java
@@ -21,6 +21,7 @@
 
 import static org.junit.Assert.fail;
 
+import androidx.annotation.NonNull;
 import androidx.pdf.data.FutureValue.Callback;
 import androidx.pdf.data.FutureValues;
 import androidx.pdf.data.FutureValues.SettableFutureValue;
@@ -43,7 +44,7 @@
         private float mLastProgressDone = LAST_PROGRESS_DONE_DEFAULT;
 
         @Override
-        public void failed(Throwable thrown) {
+        public void failed(@NonNull Throwable thrown) {
             this.mThrown = thrown;
             this.mResultCount++;
         }
diff --git a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/Utils.java b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/Utils.java
index 5eaf2cd..221472e 100644
--- a/pdf/pdf-viewer/src/test/java/androidx/pdf/util/Utils.java
+++ b/pdf/pdf-viewer/src/test/java/androidx/pdf/util/Utils.java
@@ -16,8 +16,6 @@
 
 package androidx.pdf.util;
 
-import android.util.Log;
-
 import androidx.annotation.Nullable;
 
 import java.io.Closeable;
@@ -51,8 +49,7 @@
         if (closeable != null) {
             try {
                 closeable.close();
-            } catch (Exception ex) {
-                Log.e(TAG, "i/o error while closing", ex);
+            } catch (Exception ignored) {
             }
         }
     }
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index 9af5451..cc49619b9 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -26,5 +26,5 @@
 # Disable docs
 androidx.enableDocumentation=false
 androidx.playground.snapshotBuildId=11349412
-androidx.playground.metalavaBuildId=11810151
+androidx.playground.metalavaBuildId=11936116
 androidx.studio.type=playground
\ No newline at end of file
diff --git a/room/room-common/api/current.txt b/room/room-common/api/current.txt
index 8b38bec..a817853 100644
--- a/room/room-common/api/current.txt
+++ b/room/room-common/api/current.txt
@@ -3,10 +3,10 @@
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface AutoMigration {
     method public abstract int from();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> spec() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> spec() default java.lang.Object;
     method public abstract int to();
     property public abstract int from;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> spec;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> spec;
     property public abstract int to;
   }
 
@@ -79,15 +79,15 @@
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Database {
     method public abstract androidx.room.AutoMigration[] autoMigrations();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] entities();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] entities();
     method public abstract boolean exportSchema() default true;
     method public abstract int version();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] views();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] views();
     property public abstract androidx.room.AutoMigration[] autoMigrations;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] entities;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] entities;
     property public abstract boolean exportSchema;
     property public abstract int version;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] views;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] views;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface DatabaseView {
@@ -98,8 +98,8 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Delete {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
   }
 
   @java.lang.annotation.Repeatable(DeleteColumn.Entries::class) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface DeleteColumn {
@@ -147,13 +147,13 @@
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={}) public @interface ForeignKey {
     method public abstract String[] childColumns();
     method public abstract boolean deferred() default false;
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity();
     method @androidx.room.ForeignKey.Action public abstract int onDelete() default androidx.room.ForeignKey.NO_ACTION;
     method @androidx.room.ForeignKey.Action public abstract int onUpdate() default androidx.room.ForeignKey.NO_ACTION;
     method public abstract String[] parentColumns();
     property public abstract String[] childColumns;
     property public abstract boolean deferred;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property @androidx.room.ForeignKey.Action public abstract int onDelete;
     property @androidx.room.ForeignKey.Action public abstract int onUpdate;
     property public abstract String[] parentColumns;
@@ -184,7 +184,7 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Fts4 {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> contentEntity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> contentEntity() default java.lang.Object;
     method public abstract String languageId() default "";
     method public abstract androidx.room.FtsOptions.MatchInfo matchInfo() default androidx.room.FtsOptions.MatchInfo.FTS4;
     method public abstract String[] notIndexed();
@@ -192,7 +192,7 @@
     method public abstract int[] prefix();
     method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
     method public abstract String[] tokenizerArgs();
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> contentEntity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> contentEntity;
     property public abstract String languageId;
     property public abstract androidx.room.FtsOptions.MatchInfo matchInfo;
     property public abstract String[] notIndexed;
@@ -240,19 +240,19 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Insert {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
     method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property @androidx.room.OnConflictStrategy public abstract int onConflict;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={}) public @interface Junction {
     method public abstract String entityColumn() default "";
     method public abstract String parentColumn() default "";
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> value();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> value();
     property public abstract String entityColumn;
     property public abstract String parentColumn;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> value;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> value;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.TYPE) public @interface MapColumn {
@@ -313,18 +313,18 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface RawQuery {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] observedEntities();
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] observedEntities;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] observedEntities();
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] observedEntities;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface Relation {
     method public abstract androidx.room.Junction associateBy() default androidx.room.Junction(java.lang.Object);
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
     method public abstract String entityColumn();
     method public abstract String parentColumn();
     method public abstract String[] projection();
     property public abstract androidx.room.Junction associateBy;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property public abstract String entityColumn;
     property public abstract String parentColumn;
     property public abstract String[] projection;
@@ -397,21 +397,21 @@
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.CLASS}) public @interface TypeConverters {
     method public abstract androidx.room.BuiltInTypeConverters builtInTypeConverters() default androidx.room.BuiltInTypeConverters();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] value();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] value();
     property public abstract androidx.room.BuiltInTypeConverters builtInTypeConverters;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] value;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] value;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Update {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
     method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property @androidx.room.OnConflictStrategy public abstract int onConflict;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Upsert {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
   }
 
 }
diff --git a/room/room-common/api/restricted_current.txt b/room/room-common/api/restricted_current.txt
index a2133c9..6a61efc 100644
--- a/room/room-common/api/restricted_current.txt
+++ b/room/room-common/api/restricted_current.txt
@@ -9,10 +9,10 @@
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface AutoMigration {
     method public abstract int from();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> spec() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> spec() default java.lang.Object;
     method public abstract int to();
     property public abstract int from;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> spec;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> spec;
     property public abstract int to;
   }
 
@@ -85,15 +85,15 @@
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Database {
     method public abstract androidx.room.AutoMigration[] autoMigrations();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] entities();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] entities();
     method public abstract boolean exportSchema() default true;
     method public abstract int version();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] views();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] views();
     property public abstract androidx.room.AutoMigration[] autoMigrations;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] entities;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] entities;
     property public abstract boolean exportSchema;
     property public abstract int version;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] views;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] views;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface DatabaseView {
@@ -104,8 +104,8 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Delete {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
   }
 
   @java.lang.annotation.Repeatable(DeleteColumn.Entries::class) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface DeleteColumn {
@@ -153,13 +153,13 @@
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={}) public @interface ForeignKey {
     method public abstract String[] childColumns();
     method public abstract boolean deferred() default false;
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity();
     method @androidx.room.ForeignKey.Action public abstract int onDelete() default androidx.room.ForeignKey.NO_ACTION;
     method @androidx.room.ForeignKey.Action public abstract int onUpdate() default androidx.room.ForeignKey.NO_ACTION;
     method public abstract String[] parentColumns();
     property public abstract String[] childColumns;
     property public abstract boolean deferred;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property @androidx.room.ForeignKey.Action public abstract int onDelete;
     property @androidx.room.ForeignKey.Action public abstract int onUpdate;
     property public abstract String[] parentColumns;
@@ -190,7 +190,7 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Fts4 {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> contentEntity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> contentEntity() default java.lang.Object;
     method public abstract String languageId() default "";
     method public abstract androidx.room.FtsOptions.MatchInfo matchInfo() default androidx.room.FtsOptions.MatchInfo.FTS4;
     method public abstract String[] notIndexed();
@@ -198,7 +198,7 @@
     method public abstract int[] prefix();
     method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
     method public abstract String[] tokenizerArgs();
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> contentEntity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> contentEntity;
     property public abstract String languageId;
     property public abstract androidx.room.FtsOptions.MatchInfo matchInfo;
     property public abstract String[] notIndexed;
@@ -246,19 +246,19 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Insert {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
     method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property @androidx.room.OnConflictStrategy public abstract int onConflict;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={}) public @interface Junction {
     method public abstract String entityColumn() default "";
     method public abstract String parentColumn() default "";
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> value();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> value();
     property public abstract String entityColumn;
     property public abstract String parentColumn;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> value;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> value;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.TYPE) public @interface MapColumn {
@@ -319,18 +319,18 @@
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface RawQuery {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] observedEntities();
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] observedEntities;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] observedEntities();
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] observedEntities;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface Relation {
     method public abstract androidx.room.Junction associateBy() default androidx.room.Junction(java.lang.Object);
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
     method public abstract String entityColumn();
     method public abstract String parentColumn();
     method public abstract String[] projection();
     property public abstract androidx.room.Junction associateBy;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property public abstract String entityColumn;
     property public abstract String parentColumn;
     property public abstract String[] projection;
@@ -413,21 +413,21 @@
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.CLASS}) public @interface TypeConverters {
     method public abstract androidx.room.BuiltInTypeConverters builtInTypeConverters() default androidx.room.BuiltInTypeConverters();
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] value();
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] value();
     property public abstract androidx.room.BuiltInTypeConverters builtInTypeConverters;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!>[] value;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?>[] value;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Update {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
     method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
     property @androidx.room.OnConflictStrategy public abstract int onConflict;
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface Upsert {
-    method public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity() default java.lang.Object;
-    property public abstract kotlin.reflect.KClass<? extends java.lang.Object!> entity;
+    method public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity() default java.lang.Object;
+    property public abstract kotlin.reflect.KClass<? extends java.lang.Object?> entity;
   }
 
 }
diff --git a/room/room-runtime/api/current.txt b/room/room-runtime/api/current.txt
index 7f5e5a3..c055b76 100644
--- a/room/room-runtime/api/current.txt
+++ b/room/room-runtime/api/current.txt
@@ -180,7 +180,7 @@
   }
 
   public interface TransactionScope<T> extends androidx.room.PooledConnection {
-    method public suspend Object? rollback(T result, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? rollback(T result, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     method public suspend <R> Object? withNestedTransaction(kotlin.jvm.functions.Function2<? super androidx.room.TransactionScope<R>,? super kotlin.coroutines.Continuation<? super R>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? super R>);
   }
 
diff --git a/room/room-runtime/api/restricted_current.txt b/room/room-runtime/api/restricted_current.txt
index 4091505..a2f7235 100644
--- a/room/room-runtime/api/restricted_current.txt
+++ b/room/room-runtime/api/restricted_current.txt
@@ -371,7 +371,7 @@
   }
 
   public interface TransactionScope<T> extends androidx.room.PooledConnection {
-    method public suspend Object? rollback(T result, kotlin.coroutines.Continuation<? extends java.lang.Object!>);
+    method public suspend Object? rollback(T result, kotlin.coroutines.Continuation<? extends java.lang.Object?>);
     method public suspend <R> Object? withNestedTransaction(kotlin.jvm.functions.Function2<? super androidx.room.TransactionScope<R>,? super kotlin.coroutines.Continuation<? super R>,? extends java.lang.Object?> block, kotlin.coroutines.Continuation<? super R>);
   }
 
diff --git a/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
index 21cb480..6d2d169 100644
--- a/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
@@ -1515,6 +1515,15 @@
          * For example, an instance of [androidx.sqlite.driver.AndroidSQLiteDriver] or
          * [androidx.sqlite.driver.bundled.BundledSQLiteDriver].
          *
+         * Once a driver is configured using this function, various callbacks that receive a
+         * [SupportSQLiteDatabase] will not be invoked, such as [RoomDatabase.Callback.onCreate].
+         * Moreover, APIs that use SupportSQLite will also throw an exception, such as
+         * [RoomDatabase.openHelper].
+         *
+         * See the documentation on
+         * [Migrating to SQLite Driver](https://d.android.com/training/data-storage/room/room-kmp-migration#migrate_from_support_sqlite_to_sqlite_driver)
+         * for more information.
+         *
          * @param driver The driver
          * @return This builder instance.
          */
@@ -1785,6 +1794,10 @@
          * Called when the database is created for the first time. This is called after all the
          * tables are created.
          *
+         * This function is only called when Room is configured without a driver. If a driver is set
+         * using [androidx.room.RoomDatabase.Builder.setDriver], then only the version that receives
+         * a [SQLiteConnection] is called.
+         *
          * @param db The database.
          */
         open fun onCreate(db: SupportSQLiteDatabase) {}
@@ -1805,6 +1818,10 @@
         /**
          * Called after the database was destructively migrated
          *
+         * This function is only called when Room is configured without a driver. If a driver is set
+         * using [androidx.room.RoomDatabase.Builder.setDriver], then only the version that receives
+         * a [SQLiteConnection] is called.
+         *
          * @param db The database.
          */
         open fun onDestructiveMigration(db: SupportSQLiteDatabase) {}
@@ -1823,6 +1840,10 @@
         /**
          * Called when the database has been opened.
          *
+         * This function is only called when Room is configured without a driver. If a driver is set
+         * using [androidx.room.RoomDatabase.Builder.setDriver], then only the version that receives
+         * a [SQLiteConnection] is called.
+         *
          * @param db The database.
          */
         open fun onOpen(db: SupportSQLiteDatabase) {}
diff --git a/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/AutoMigrationSpec.android.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/AutoMigrationSpec.android.kt
index 72ff52b..9c06675ac 100644
--- a/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/AutoMigrationSpec.android.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/AutoMigrationSpec.android.kt
@@ -32,6 +32,10 @@
     /**
      * Invoked after the migration is completed.
      *
+     * This function is only called when Room is configured without a driver. If a driver is set
+     * using [androidx.room.RoomDatabase.Builder.setDriver], then only the version that receives a
+     * [SQLiteConnection] is called.
+     *
      * @param db The SQLite database.
      */
     fun onPostMigrate(db: SupportSQLiteDatabase) {}
diff --git a/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/Migration.android.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/Migration.android.kt
index cfb25d0..127b804 100644
--- a/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/Migration.android.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/Migration.android.kt
@@ -46,6 +46,10 @@
      * This method is already called inside a transaction and that transaction might actually be a
      * composite transaction of all necessary `Migration`s.
      *
+     * This function is only called when Room is configured without a driver. If a driver is set
+     * using [androidx.room.RoomDatabase.Builder.setDriver], then only the version that receives a
+     * [SQLiteConnection] is called.
+     *
      * @param db The database instance
      * @throws NotImplementedError if migrate(SQLiteConnection) is not overridden.
      */
diff --git a/test/ext/junit-gtest/api/current.txt b/test/ext/junit-gtest/api/current.txt
index 8db60c3..696d4b6 100644
--- a/test/ext/junit-gtest/api/current.txt
+++ b/test/ext/junit-gtest/api/current.txt
@@ -2,7 +2,7 @@
 package androidx.test.ext.junitgtest {
 
   public final class GtestRunner extends org.junit.runner.Runner implements org.junit.runner.manipulation.Filterable {
-    ctor public GtestRunner(Class<? extends java.lang.Object!> testClass);
+    ctor public GtestRunner(Class<? extends java.lang.Object?> testClass);
     method @kotlin.jvm.Throws(exceptionClasses=NoTestsRemainException::class) public void filter(org.junit.runner.manipulation.Filter filter) throws org.junit.runner.manipulation.NoTestsRemainException;
     method public org.junit.runner.Description getDescription();
     method public void run(org.junit.runner.notification.RunNotifier notifier);
diff --git a/test/ext/junit-gtest/api/restricted_current.txt b/test/ext/junit-gtest/api/restricted_current.txt
index 8db60c3..696d4b6 100644
--- a/test/ext/junit-gtest/api/restricted_current.txt
+++ b/test/ext/junit-gtest/api/restricted_current.txt
@@ -2,7 +2,7 @@
 package androidx.test.ext.junitgtest {
 
   public final class GtestRunner extends org.junit.runner.Runner implements org.junit.runner.manipulation.Filterable {
-    ctor public GtestRunner(Class<? extends java.lang.Object!> testClass);
+    ctor public GtestRunner(Class<? extends java.lang.Object?> testClass);
     method @kotlin.jvm.Throws(exceptionClasses=NoTestsRemainException::class) public void filter(org.junit.runner.manipulation.Filter filter) throws org.junit.runner.manipulation.NoTestsRemainException;
     method public org.junit.runner.Description getDescription();
     method public void run(org.junit.runner.notification.RunNotifier notifier);
diff --git a/test/uiautomator/integration-tests/testapp/build.gradle b/test/uiautomator/integration-tests/testapp/build.gradle
index 7aba758..0efa882 100644
--- a/test/uiautomator/integration-tests/testapp/build.gradle
+++ b/test/uiautomator/integration-tests/testapp/build.gradle
@@ -40,7 +40,7 @@
     androidTestImplementation(libs.testRunner)
 
     // Align dependencies in debugRuntimeClasspath and debugAndroidTestRuntimeClasspath.
-    androidTestImplementation("androidx.lifecycle:lifecycle-common:2.8.0")
+    androidTestImplementation("androidx.lifecycle:lifecycle-common:2.8.2")
     androidTestImplementation("androidx.annotation:annotation:1.8.0")
 }
 
diff --git a/tracing/tracing-perfetto/api/current.txt b/tracing/tracing-perfetto/api/current.txt
index 0a74331..a35e073 100644
--- a/tracing/tracing-perfetto/api/current.txt
+++ b/tracing/tracing-perfetto/api/current.txt
@@ -12,7 +12,7 @@
   public final class StartupTracingInitializer implements androidx.startup.Initializer<kotlin.Unit> {
     ctor public StartupTracingInitializer();
     method public void create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
 }
diff --git a/tracing/tracing-perfetto/api/restricted_current.txt b/tracing/tracing-perfetto/api/restricted_current.txt
index 0a74331..a35e073 100644
--- a/tracing/tracing-perfetto/api/restricted_current.txt
+++ b/tracing/tracing-perfetto/api/restricted_current.txt
@@ -12,7 +12,7 @@
   public final class StartupTracingInitializer implements androidx.startup.Initializer<kotlin.Unit> {
     ctor public StartupTracingInitializer();
     method public void create(android.content.Context context);
-    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object!>>> dependencies();
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<? extends java.lang.Object?>>> dependencies();
   }
 
 }
diff --git a/tv/tv-foundation/api/current.txt b/tv/tv-foundation/api/current.txt
index a392d37..7cfb9113 100644
--- a/tv/tv-foundation/api/current.txt
+++ b/tv/tv-foundation/api/current.txt
@@ -146,8 +146,8 @@
   }
 
   public static final class TvLazyGridState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object?> Saver;
   }
 
   public final class TvLazyGridStateKt {
@@ -245,8 +245,8 @@
   }
 
   public static final class TvLazyListState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object?> Saver;
   }
 
 }
diff --git a/tv/tv-foundation/api/restricted_current.txt b/tv/tv-foundation/api/restricted_current.txt
index a392d37..7cfb9113 100644
--- a/tv/tv-foundation/api/restricted_current.txt
+++ b/tv/tv-foundation/api/restricted_current.txt
@@ -146,8 +146,8 @@
   }
 
   public static final class TvLazyGridState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.grid.TvLazyGridState,? extends java.lang.Object?> Saver;
   }
 
   public final class TvLazyGridStateKt {
@@ -245,8 +245,8 @@
   }
 
   public static final class TvLazyListState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.foundation.lazy.list.TvLazyListState,? extends java.lang.Object?> Saver;
   }
 
 }
diff --git a/tv/tv-material/api/1.0.0-beta01.txt b/tv/tv-material/api/1.0.0-beta01.txt
index 93d2c08..baebe2c 100644
--- a/tv/tv-material/api/1.0.0-beta01.txt
+++ b/tv/tv-material/api/1.0.0-beta01.txt
@@ -154,8 +154,8 @@
   }
 
   public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class CheckboxColors {
diff --git a/tv/tv-material/api/current.txt b/tv/tv-material/api/current.txt
index 93d2c08..baebe2c 100644
--- a/tv/tv-material/api/current.txt
+++ b/tv/tv-material/api/current.txt
@@ -154,8 +154,8 @@
   }
 
   public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class CheckboxColors {
diff --git a/tv/tv-material/api/restricted_1.0.0-beta01.txt b/tv/tv-material/api/restricted_1.0.0-beta01.txt
index 93d2c08..baebe2c 100644
--- a/tv/tv-material/api/restricted_1.0.0-beta01.txt
+++ b/tv/tv-material/api/restricted_1.0.0-beta01.txt
@@ -154,8 +154,8 @@
   }
 
   public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class CheckboxColors {
diff --git a/tv/tv-material/api/restricted_current.txt b/tv/tv-material/api/restricted_current.txt
index 93d2c08..baebe2c 100644
--- a/tv/tv-material/api/restricted_current.txt
+++ b/tv/tv-material/api/restricted_current.txt
@@ -154,8 +154,8 @@
   }
 
   public static final class CarouselState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object!> Saver;
+    method public androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.tv.material3.CarouselState,? extends java.lang.Object?> Saver;
   }
 
   @androidx.compose.runtime.Immutable public final class CheckboxColors {
diff --git a/wear/compose/compose-material3/benchmark/src/androidTest/java/androidx/wear/compose/material3/benchmark/IconButtonBenchmark.kt b/wear/compose/compose-material3/benchmark/src/androidTest/java/androidx/wear/compose/material3/benchmark/IconButtonBenchmark.kt
new file mode 100644
index 0000000..ec8d8d8
--- /dev/null
+++ b/wear/compose/compose-material3/benchmark/src/androidTest/java/androidx/wear/compose/material3/benchmark/IconButtonBenchmark.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.compose.material3.benchmark
+
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkToFirstPixel
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+import androidx.test.filters.MediumTest
+import androidx.wear.compose.material3.FilledIconButton
+import androidx.wear.compose.material3.FilledTonalIconButton
+import androidx.wear.compose.material3.Icon
+import androidx.wear.compose.material3.IconButton
+import androidx.wear.compose.material3.MaterialTheme
+import androidx.wear.compose.material3.OutlinedIconButton
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@MediumTest
+@RunWith(Parameterized::class)
+class IconButtonBenchmark(private val iconButtonType: IconButtonType) {
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun parameters() = IconButtonType.values()
+    }
+
+    @get:Rule val benchmarkRule = ComposeBenchmarkRule()
+
+    private val testCaseFactory = { IconButtonTestCase(iconButtonType) }
+
+    @Test
+    fun first_pixel() {
+        benchmarkRule.benchmarkToFirstPixel(testCaseFactory)
+    }
+}
+
+internal class IconButtonTestCase(private val iconButtonType: IconButtonType) :
+    LayeredComposeTestCase() {
+    @Composable
+    override fun MeasuredContent() {
+        when (iconButtonType) {
+            IconButtonType.FilledIconButton -> FilledIconButton(onClick = {}) { StandardIcon() }
+            IconButtonType.FilledTonalIconButton ->
+                FilledTonalIconButton(onClick = {}) { StandardIcon() }
+            IconButtonType.OutlinedIconButton -> OutlinedIconButton(onClick = {}) { StandardIcon() }
+            IconButtonType.IconButton -> IconButton(onClick = {}) { StandardIcon() }
+        }
+    }
+
+    @Composable
+    override fun ContentWrappers(content: @Composable () -> Unit) {
+        MaterialTheme { content() }
+    }
+}
+
+enum class IconButtonType {
+    FilledIconButton,
+    FilledTonalIconButton,
+    OutlinedIconButton,
+    IconButton
+}
+
+@Composable
+internal fun StandardIcon() {
+    val size = 24f
+    val imageVector =
+        ImageVector.Builder(
+                defaultWidth = size.dp,
+                defaultHeight = size.dp,
+                viewportWidth = size,
+                viewportHeight = size
+            )
+            .build()
+
+    Icon(imageVector = imageVector, contentDescription = "vector")
+}
diff --git a/wear/compose/compose-material3/benchmark/src/androidTest/java/androidx/wear/compose/material3/benchmark/IconToggleButtonBenchmark.kt b/wear/compose/compose-material3/benchmark/src/androidTest/java/androidx/wear/compose/material3/benchmark/IconToggleButtonBenchmark.kt
new file mode 100644
index 0000000..4a9f841
--- /dev/null
+++ b/wear/compose/compose-material3/benchmark/src/androidTest/java/androidx/wear/compose/material3/benchmark/IconToggleButtonBenchmark.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.compose.material3.benchmark
+
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkToFirstPixel
+import androidx.test.filters.MediumTest
+import androidx.wear.compose.material3.IconToggleButton
+import androidx.wear.compose.material3.MaterialTheme
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@MediumTest
+@RunWith(Parameterized::class)
+class IconToggleButtonBenchmark(private val type: IconToggleButtonType) {
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun parameters() = IconToggleButtonType.values()
+    }
+
+    @get:Rule val benchmarkRule = ComposeBenchmarkRule()
+
+    private val testCaseFactory = { IconToggleButtonTestCase(type) }
+
+    @Test
+    fun first_pixel() {
+        benchmarkRule.benchmarkToFirstPixel(testCaseFactory)
+    }
+}
+
+internal class IconToggleButtonTestCase(
+    private val type: IconToggleButtonType,
+) : LayeredComposeTestCase() {
+
+    @Composable
+    override fun MeasuredContent() {
+        when (type) {
+            IconToggleButtonType.IconToggleButtonOn -> {
+                IconToggleButton(
+                    checked = true,
+                    onCheckedChange = {},
+                ) {
+                    StandardIcon()
+                }
+            }
+            IconToggleButtonType.IconToggleButtonOff -> {
+                IconToggleButton(
+                    checked = false,
+                    onCheckedChange = {},
+                ) {
+                    StandardIcon()
+                }
+            }
+        }
+    }
+
+    @Composable
+    override fun ContentWrappers(content: @Composable () -> Unit) {
+        MaterialTheme { content() }
+    }
+}
+
+enum class IconToggleButtonType {
+    IconToggleButtonOn,
+    IconToggleButtonOff
+}
diff --git a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ProgressIndicatorDemo.kt b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ProgressIndicatorDemo.kt
index f3bd26d..807a43e 100644
--- a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ProgressIndicatorDemo.kt
+++ b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ProgressIndicatorDemo.kt
@@ -27,7 +27,6 @@
 import androidx.compose.ui.unit.dp
 import androidx.wear.compose.integration.demos.common.Centralize
 import androidx.wear.compose.integration.demos.common.ComposableDemo
-import androidx.wear.compose.integration.demos.common.DemoCategory
 import androidx.wear.compose.material3.Button
 import androidx.wear.compose.material3.CircularProgressIndicator
 import androidx.wear.compose.material3.IconButtonDefaults
@@ -41,41 +40,29 @@
 
 val ProgressIndicatorDemos =
     listOf(
-        DemoCategory(
-            "Samples",
-            listOf(
-                ComposableDemo("Full screen") {
-                    Centralize { FullScreenProgressIndicatorSample() }
-                },
-                ComposableDemo("Media button wrapping") {
-                    Centralize { MediaButtonProgressIndicatorSample() }
-                },
-                ComposableDemo("Overflow progress (>100%)") {
-                    Centralize { OverflowProgressIndicatorSample() }
-                },
-                ComposableDemo("Small sized indicator") {
-                    Box(
-                        modifier =
-                            Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)
-                    ) {
-                        Button({ /* No op */ }, modifier = Modifier.align(Alignment.Center)) {
-                            Text(
-                                "Loading...",
-                                modifier = Modifier.align(Alignment.CenterVertically)
-                            )
-                            Spacer(modifier = Modifier.size(10.dp))
-                            CircularProgressIndicator(
-                                progress = { 0.75f },
-                                modifier = Modifier.size(IconButtonDefaults.DefaultButtonSize),
-                                startAngle = 120f,
-                                endAngle = 60f,
-                                strokeWidth = ButtonCircularIndicatorStrokeWidth,
-                                colors =
-                                    ProgressIndicatorDefaults.colors(indicatorColor = Color.Red)
-                            )
-                        }
-                    }
+        ComposableDemo("Full screen") { Centralize { FullScreenProgressIndicatorSample() } },
+        ComposableDemo("Media button wrapping") {
+            Centralize { MediaButtonProgressIndicatorSample() }
+        },
+        ComposableDemo("Overflow progress (>100%)") {
+            Centralize { OverflowProgressIndicatorSample() }
+        },
+        ComposableDemo("Small sized indicator") {
+            Box(
+                modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)
+            ) {
+                Button({ /* No op */ }, modifier = Modifier.align(Alignment.Center)) {
+                    Text("Loading...", modifier = Modifier.align(Alignment.CenterVertically))
+                    Spacer(modifier = Modifier.size(10.dp))
+                    CircularProgressIndicator(
+                        progress = { 0.75f },
+                        modifier = Modifier.size(IconButtonDefaults.DefaultButtonSize),
+                        startAngle = 120f,
+                        endAngle = 60f,
+                        strokeWidth = ButtonCircularIndicatorStrokeWidth,
+                        colors = ProgressIndicatorDefaults.colors(indicatorColor = Color.Red)
+                    )
                 }
-            )
-        )
+            }
+        }
     )
diff --git a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/SliderDemo.kt b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/SliderDemo.kt
index a3061c5..e849251 100644
--- a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/SliderDemo.kt
+++ b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/SliderDemo.kt
@@ -37,7 +37,6 @@
 import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
 import androidx.wear.compose.integration.demos.common.Centralize
 import androidx.wear.compose.integration.demos.common.ComposableDemo
-import androidx.wear.compose.integration.demos.common.DemoCategory
 import androidx.wear.compose.material3.ExperimentalWearMaterial3Api
 import androidx.wear.compose.material3.Icon
 import androidx.wear.compose.material3.InlineSlider
@@ -50,34 +49,20 @@
 
 val SliderDemos =
     listOf(
-        DemoCategory(
-            "Samples",
-            listOf(
-                ComposableDemo("Inline slider") {
-                    Centralize(Modifier.padding(horizontal = 10.dp)) { InlineSliderSample() }
-                },
-                ComposableDemo("Segmented inline slider") {
-                    Centralize(Modifier.padding(horizontal = 10.dp)) {
-                        InlineSliderSegmentedSample()
-                    }
-                },
-                ComposableDemo("Integer inline slider") {
-                    Centralize(Modifier.padding(horizontal = 10.dp)) {
-                        InlineSliderWithIntegerSample()
-                    }
-                },
-            )
-        ),
-        DemoCategory(
-            "Demos",
-            listOf(
-                ComposableDemo("Inline slider") { InlineSliderDemo() },
-                ComposableDemo("RTL Inline slider") { InlineSliderRTLDemo() },
-                ComposableDemo("Inline slider segmented") { InlineSliderDemo(segmented = true) },
-                ComposableDemo("With custom color") { InlineSliderCustomColorsDemo() },
-                ComposableDemo("Inline slider with integers") { InlineSliderWithIntegersDemo() },
-            )
-        )
+        ComposableDemo("Inline slider") {
+            Centralize(Modifier.padding(horizontal = 10.dp)) { InlineSliderSample() }
+        },
+        ComposableDemo("Segmented inline slider") {
+            Centralize(Modifier.padding(horizontal = 10.dp)) { InlineSliderSegmentedSample() }
+        },
+        ComposableDemo("Integer inline slider") {
+            Centralize(Modifier.padding(horizontal = 10.dp)) { InlineSliderWithIntegerSample() }
+        },
+        ComposableDemo("Inline slider Demo") { InlineSliderDemo() },
+        ComposableDemo("RTL Inline slider") { InlineSliderRTLDemo() },
+        ComposableDemo("Inline slider segmented") { InlineSliderDemo(segmented = true) },
+        ComposableDemo("With custom color") { InlineSliderCustomColorsDemo() },
+        ComposableDemo("Inline slider with integers") { InlineSliderWithIntegersDemo() },
     )
 
 @OptIn(ExperimentalWearMaterial3Api::class)
diff --git a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt
index c118e47..59baac4 100644
--- a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt
+++ b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt
@@ -20,7 +20,7 @@
 import android.widget.Toast
 import androidx.wear.compose.integration.demos.common.Centralize
 import androidx.wear.compose.integration.demos.common.ComposableDemo
-import androidx.wear.compose.integration.demos.common.DemoCategory
+import androidx.wear.compose.integration.demos.common.Material3DemoCategory
 import androidx.wear.compose.material3.samples.EdgeSwipeForSwipeToDismiss
 import androidx.wear.compose.material3.samples.FixedFontSize
 import androidx.wear.compose.material3.samples.HorizontalPageIndicatorSample
@@ -32,10 +32,10 @@
 import androidx.wear.compose.material3.samples.StepperWithRangeSemanticsSample
 
 val WearMaterial3Demos =
-    DemoCategory(
+    Material3DemoCategory(
         "Material 3",
         listOf(
-            DemoCategory(
+            Material3DemoCategory(
                 "Button",
                 listOf(
                     ComposableDemo("Button") { ButtonDemo() },
@@ -48,7 +48,7 @@
                 )
             ),
             ComposableDemo("List Header") { Centralize { ListHeaderDemo() } },
-            DemoCategory("Time Text", TimeTextDemos),
+            Material3DemoCategory("Time Text", TimeTextDemos),
             ComposableDemo("Card") { CardDemo() },
             ComposableDemo("Text Button") { TextButtonDemo() },
             ComposableDemo("Icon Button") { IconButtonDemo() },
@@ -60,10 +60,10 @@
             ComposableDemo("Split Radio Button") { SplitRadioButtonDemo() },
             ComposableDemo("Toggle Button") { ToggleButtonDemo() },
             ComposableDemo("Split Toggle Button") { SplitToggleButtonDemo() },
-            DemoCategory(
+            Material3DemoCategory(
                 "Stepper",
                 listOf(
-                    DemoCategory(
+                    Material3DemoCategory(
                         "Samples",
                         listOf(
                             ComposableDemo("Stepper") { Centralize { StepperSample() } },
@@ -77,11 +77,11 @@
                     )
                 )
             ),
-            DemoCategory("Slider", SliderDemos),
-            DemoCategory("Progress Indicator", ProgressIndicatorDemos),
-            DemoCategory("Scroll Indicator", ScrollIndicatorDemos),
+            Material3DemoCategory("Slider", SliderDemos),
+            Material3DemoCategory("Progress Indicator", ProgressIndicatorDemos),
+            Material3DemoCategory("Scroll Indicator", ScrollIndicatorDemos),
             ComposableDemo(title = "Fixed Font Size") { Centralize { FixedFontSize() } },
-            DemoCategory(
+            Material3DemoCategory(
                 title = "Swipe To Dismiss",
                 listOf(
                     ComposableDemo("Simple") { SimpleSwipeToDismissBox(it.navigateBack) },
@@ -89,7 +89,7 @@
                     ComposableDemo("Edge swipe") { EdgeSwipeForSwipeToDismiss(it.navigateBack) },
                 )
             ),
-            DemoCategory(
+            Material3DemoCategory(
                 title = "Horizontal Page Indicator",
                 listOf(
                     ComposableDemo("Simple HorizontalPageIndicator") {
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ScrollIndicator.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ScrollIndicator.kt
index 4322596..1e75ae5 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ScrollIndicator.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ScrollIndicator.kt
@@ -81,8 +81,9 @@
  * implementing [Modifier.verticalScroll] provides a [ScrollState].
  *
  * To comply with Wear Material Design guidelines, this composable should be aligned to the center
- * end of the screen using `Alignment.CenterEnd`. It will appear on the right in Ltr orientation and
- * on the left in Rtl orientation.
+ * end of the screen using `Alignment.CenterEnd`, such as by setting `modifier =
+ * Modifier.align(Alignment.CenterEnd)`. This way, the [ScrollIndicator] will appear on the right in
+ * Ltr orientation and on the left in Rtl orientation.
  *
  * It detects if the screen is round or square and draws itself as a curve or line.
  *
@@ -94,7 +95,8 @@
  * @sample androidx.wear.compose.material3.samples.ScrollIndicatorWithColumnSample
  *
  * @param state The scrollState to use as the basis for the ScrollIndicatorState.
- * @param modifier The modifier to be applied to the component
+ * @param modifier The modifier to be applied to the component - usually set to
+ *   `Modifier.align(Alignment.CenterEnd)`.
  * @param reverseDirection Reverses direction of ScrollIndicator if true
  * @param positionAnimationSpec [AnimationSpec] for position animation. The Position animation is
  *   used for animating changes between state.positionFraction and state.sizeFraction of
@@ -128,7 +130,7 @@
  * Creates an [ScrollIndicator] based on the values in a [ScalingLazyListState] object that a
  * [ScalingLazyColumn] uses.
  *
- * Typically used with the [Scaffold] but can be used to decorate any full screen situation.
+ * Typically used with the [ScreenScaffold] but can be used to decorate any full screen situation.
  *
  * To comply with Wear Material Design guidelines, this composable should be aligned to the center
  * end of the screen using `Alignment.CenterEnd`. It will appear on the right in Ltr orientation and
@@ -258,7 +260,7 @@
 /**
  * An indicator on one side of the screen to show the current [ScrollIndicatorState].
  *
- * Typically used with the [Scaffold] but can be used to decorate any full screen situation.
+ * Typically used with the [ScreenScaffold] but can be used to decorate any full screen situation.
  *
  * This composable should only be used to fill the whole screen as Wear Material Design language
  * requires the placement of the position indicator to be right center of the screen as the
diff --git a/wear/compose/integration-tests/demos/common/src/main/java/androidx/wear/compose/integration/demos/common/Demo.kt b/wear/compose/integration-tests/demos/common/src/main/java/androidx/wear/compose/integration/demos/common/Demo.kt
index d89ada5..d3e5a2f9 100644
--- a/wear/compose/integration-tests/demos/common/src/main/java/androidx/wear/compose/integration/demos/common/Demo.kt
+++ b/wear/compose/integration-tests/demos/common/src/main/java/androidx/wear/compose/integration/demos/common/Demo.kt
@@ -47,8 +47,9 @@
     Demo(title)
 
 /** A category of [Demo]s, that will display a list of [demos] when selected. */
-class DemoCategory(title: String, val demos: List<Demo>) : Demo(title) {
+open class DemoCategory(title: String, val demos: List<Demo>) : Demo(title) {
     private var scrollState: ScalingLazyListState? = null
+    open val materialVersion = 2
 
     @Composable
     fun getScrollStateOrInit(
@@ -58,6 +59,10 @@
     }
 }
 
+class Material3DemoCategory(title: String, demos: List<Demo>) : DemoCategory(title, demos) {
+    override val materialVersion = 3
+}
+
 /** Parameters which are used by [Demo] screens. */
 class DemoParameters(
     val navigateBack: () -> Unit,
diff --git a/wear/compose/integration-tests/navigation/build.gradle b/wear/compose/integration-tests/navigation/build.gradle
index b6957c2..64f02c2 100644
--- a/wear/compose/integration-tests/navigation/build.gradle
+++ b/wear/compose/integration-tests/navigation/build.gradle
@@ -54,6 +54,6 @@
     implementation(project(':wear:compose:compose-navigation'))
 
     // Align dependencies in debugRuntimeClasspath and debugAndroidTestRuntimeClasspath.
-    androidTestImplementation("androidx.lifecycle:lifecycle-common:2.8.0")
+    androidTestImplementation("androidx.lifecycle:lifecycle-common:2.8.2")
     androidTestImplementation("androidx.annotation:annotation:1.8.0")
 }
diff --git a/wear/protolayout/protolayout-material-core/build.gradle b/wear/protolayout/protolayout-material-core/build.gradle
index dcf081a..ca1740a 100644
--- a/wear/protolayout/protolayout-material-core/build.gradle
+++ b/wear/protolayout/protolayout-material-core/build.gradle
@@ -26,6 +26,7 @@
 plugins {
     id("AndroidXPlugin")
     id("com.android.library")
+    id("kotlin-android")
 }
 
 android {
@@ -55,6 +56,7 @@
     testImplementation(libs.testRunner)
     testImplementation(libs.testRules)
     testImplementation(libs.truth)
+    testImplementation("androidx.core:core-ktx:1.13.1")
 }
 
 androidx {
diff --git a/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverter.java b/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverter.java
new file mode 100644
index 0000000..98351ea
--- /dev/null
+++ b/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverter.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.materialcore.fontscaling;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+import java.util.Arrays;
+
+/**
+ * A lookup table for non-linear font scaling. Converts font sizes given in "sp" dimensions to a
+ * "dp" dimension according to a non-linear curve.
+ *
+ * <p>This is meant to improve readability at larger font scales: larger fonts will scale up more
+ * slowly than smaller fonts, so we don't get ridiculously huge fonts that don't fit on the screen.
+ *
+ * <p>The thinking here is that large fonts are already big enough to read, but we still want to
+ * scale them slightly to preserve the visual hierarchy when compared to smaller fonts.
+ */
+// This is copied from
+// https://cs.android.com/android/_/android/platform/frameworks/base/+/2a4e99a798cc69944f64d54b81aee987fbea45d6:core/java/android/content/res/FontScaleConverter.java
+// TODO: b/342359552 - Use Android Platform api instead when it becomes public.
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class FontScaleConverter {
+
+    final float[] mFromSpValues;
+    final float[] mToDpValues;
+
+    /**
+     * Creates a lookup table for the given conversions.
+     *
+     * <p>Any "sp" value not in the lookup table will be derived via linear interpolation.
+     *
+     * <p>The arrays must be sorted ascending and monotonically increasing.
+     *
+     * @param fromSp array of dimensions in SP
+     * @param toDp array of dimensions in DP that correspond to an SP value in fromSp
+     * @throws IllegalArgumentException if the array lengths don't match or are empty
+     */
+    FontScaleConverter(@NonNull float[] fromSp, @NonNull float[] toDp) {
+        if (fromSp.length != toDp.length || fromSp.length == 0) {
+            throw new IllegalArgumentException("Array lengths must match and be nonzero");
+        }
+
+        mFromSpValues = fromSp;
+        mToDpValues = toDp;
+    }
+
+    /** Convert a dimension in "dp" back to "sp" using the lookup table. */
+    public float convertDpToSp(float dp) {
+        return lookupAndInterpolate(dp, mToDpValues, mFromSpValues);
+    }
+
+    /** Convert a dimension in "sp" to "dp" using the lookup table. */
+    public float convertSpToDp(float sp) {
+        return lookupAndInterpolate(sp, mFromSpValues, mToDpValues);
+    }
+
+    private static float lookupAndInterpolate(
+            float sourceValue, float[] sourceValues, float[] targetValues) {
+        final float sourceValuePositive = Math.abs(sourceValue);
+        // TODO(b/247861374): find a match at a higher index?
+        final float sign = Math.signum(sourceValue);
+        // We search for exact matches only, even if it's just a little off. The interpolation will
+        // handle any non-exact matches.
+        final int index = Arrays.binarySearch(sourceValues, sourceValuePositive);
+        if (index >= 0) {
+            // exact match, return the matching dp
+            return sign * targetValues[index];
+        } else {
+            // must be a value in between index and index + 1: interpolate.
+            final int lowerIndex = -(index + 1) - 1;
+
+            final float startSp;
+            final float endSp;
+            final float startDp;
+            final float endDp;
+
+            if (lowerIndex >= sourceValues.length - 1) {
+                // It's past our lookup table. Determine the last elements' scaling factor and use.
+                startSp = sourceValues[sourceValues.length - 1];
+                startDp = targetValues[sourceValues.length - 1];
+
+                if (startSp == 0) {
+                    return 0;
+                }
+
+                final float scalingFactor = startDp / startSp;
+                return sourceValue * scalingFactor;
+            } else if (lowerIndex == -1) {
+                // It's smaller than the smallest value in our table. Interpolate from 0.
+                startSp = 0;
+                startDp = 0;
+                endSp = sourceValues[0];
+                endDp = targetValues[0];
+            } else {
+                startSp = sourceValues[lowerIndex];
+                endSp = sourceValues[lowerIndex + 1];
+                startDp = targetValues[lowerIndex];
+                endDp = targetValues[lowerIndex + 1];
+            }
+
+            return sign
+                    * MathUtils.constrainedMap(startDp, endDp, startSp, endSp, sourceValuePositive);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null) {
+            return false;
+        }
+        if (!(o instanceof FontScaleConverter)) {
+            return false;
+        }
+        FontScaleConverter that = (FontScaleConverter) o;
+        return Arrays.equals(mFromSpValues, that.mFromSpValues)
+                && Arrays.equals(mToDpValues, that.mToDpValues);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Arrays.hashCode(mFromSpValues);
+        result = 31 * result + Arrays.hashCode(mToDpValues);
+        return result;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "FontScaleConverter{"
+                + "fromSpValues="
+                + Arrays.toString(mFromSpValues)
+                + ", toDpValues="
+                + Arrays.toString(mToDpValues)
+                + '}';
+    }
+}
diff --git a/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterFactory.java b/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterFactory.java
new file mode 100644
index 0000000..5b8b3f7
--- /dev/null
+++ b/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterFactory.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.materialcore.fontscaling;
+
+import android.content.res.Configuration;
+import android.util.SparseArray;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
+
+/** Stores lookup tables for creating {@link FontScaleConverter}s at various scales. */
+// This is copied from
+// https://cs.android.com/android/_/android/platform/frameworks/base/+/2a4e99a798cc69944f64d54b81aee987fbea45d6:core/java/android/content/res/FontScaleConverterFactory.java
+// TODO: b/342359552 - Use Android Platform api instead when it becomes public.
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class FontScaleConverterFactory {
+    private static final float SCALE_KEY_MULTIPLIER = 100f;
+
+    @VisibleForTesting
+    static final SparseArray<FontScaleConverter> LOOKUP_TABLES = new SparseArray<>();
+
+    @SuppressWarnings("NonFinalStaticField")
+    private static float sMinScaleBeforeCurvesApplied = 1.05f;
+
+    static {
+        // These were generated by frameworks/base/tools/fonts/font-scaling-array-generator.js and
+        // manually tweaked for optimum readability.
+        put(
+                /* scaleKey= */ 1.15f,
+                new FontScaleConverter(
+                        /* fromSp= */ new float[] {8f, 10f, 12f, 14f, 18f, 20f, 24f, 30f, 100},
+                        /* toDp= */ new float[] {
+                            9.2f, 11.5f, 13.8f, 16.4f, 19.8f, 21.8f, 25.2f, 30f, 100
+                        }));
+
+        put(
+                /* scaleKey= */ 1.3f,
+                new FontScaleConverter(
+                        /* fromSp= */ new float[] {8f, 10f, 12f, 14f, 18f, 20f, 24f, 30f, 100},
+                        /* toDp= */ new float[] {
+                            10.4f, 13f, 15.6f, 18.8f, 21.6f, 23.6f, 26.4f, 30f, 100
+                        }));
+
+        put(
+                /* scaleKey= */ 1.5f,
+                new FontScaleConverter(
+                        /* fromSp= */ new float[] {8f, 10f, 12f, 14f, 18f, 20f, 24f, 30f, 100},
+                        /* toDp= */ new float[] {12f, 15f, 18f, 22f, 24f, 26f, 28f, 30f, 100}));
+
+        put(
+                /* scaleKey= */ 1.8f,
+                new FontScaleConverter(
+                        /* fromSp= */ new float[] {8f, 10f, 12f, 14f, 18f, 20f, 24f, 30f, 100},
+                        /* toDp= */ new float[] {
+                            14.4f, 18f, 21.6f, 24.4f, 27.6f, 30.8f, 32.8f, 34.8f, 100
+                        }));
+
+        put(
+                /* scaleKey= */ 2f,
+                new FontScaleConverter(
+                        /* fromSp= */ new float[] {8f, 10f, 12f, 14f, 18f, 20f, 24f, 30f, 100},
+                        /* toDp= */ new float[] {16f, 20f, 24f, 26f, 30f, 34f, 36f, 38f, 100}));
+
+        sMinScaleBeforeCurvesApplied = getScaleFromKey(LOOKUP_TABLES.keyAt(0)) - 0.02f;
+        if (sMinScaleBeforeCurvesApplied <= 1.0f) {
+            throw new IllegalStateException(
+                    "You should only apply non-linear scaling to font scales > 1");
+        }
+    }
+
+    private FontScaleConverterFactory() {}
+
+    /**
+     * Returns true if non-linear font scaling curves would be in effect for the given scale, false
+     * if the scaling would follow a linear curve or for no scaling.
+     *
+     * <p>Example usage: <code>
+     * isNonLinearFontScalingActive(getResources().getConfiguration().fontScale)</code>
+     */
+    public static boolean isNonLinearFontScalingActive(float fontScale) {
+        return fontScale >= sMinScaleBeforeCurvesApplied;
+    }
+
+    /**
+     * Finds a matching FontScaleConverter for the given fontScale factor.
+     *
+     * @param fontScale the scale factor, usually from {@link Configuration#fontScale}.
+     * @return a converter for the given scale, or null if non-linear scaling should not be used.
+     */
+    @Nullable
+    public static FontScaleConverter forScale(float fontScale) {
+        if (!isNonLinearFontScalingActive(fontScale)) {
+            return null;
+        }
+
+        FontScaleConverter lookupTable = get(fontScale);
+        if (lookupTable != null) {
+            return lookupTable;
+        }
+
+        // Didn't find an exact match: interpolate between two existing tables
+        final int index = LOOKUP_TABLES.indexOfKey(getKey(fontScale));
+        if (index >= 0) {
+            // This should never happen, should have been covered by get() above.
+            return LOOKUP_TABLES.valueAt(index);
+        }
+        // Didn't find an exact match: interpolate between two existing tables
+        final int lowerIndex = -(index + 1) - 1;
+        final int higherIndex = lowerIndex + 1;
+        if (lowerIndex < 0 || higherIndex >= LOOKUP_TABLES.size()) {
+            // We have gone beyond our bounds and have nothing to interpolate between. Just give
+            // them a straight linear table instead.
+            // This works because when FontScaleConverter encounters a size beyond its bounds, it
+            // calculates a linear fontScale factor using the ratio of the last element pair.
+            return new FontScaleConverter(new float[] {1f}, new float[] {fontScale});
+        } else {
+            float startScale = getScaleFromKey(LOOKUP_TABLES.keyAt(lowerIndex));
+            float endScale = getScaleFromKey(LOOKUP_TABLES.keyAt(higherIndex));
+            float interpolationPoint =
+                    MathUtils.constrainedMap(
+                            /* rangeMin= */ 0f,
+                            /* rangeMax= */ 1f,
+                            startScale,
+                            endScale,
+                            fontScale);
+            return createInterpolatedTableBetween(
+                    LOOKUP_TABLES.valueAt(lowerIndex),
+                    LOOKUP_TABLES.valueAt(higherIndex),
+                    interpolationPoint);
+        }
+    }
+
+    @NonNull
+    private static FontScaleConverter createInterpolatedTableBetween(
+            FontScaleConverter start, FontScaleConverter end, float interpolationPoint) {
+        float[] commonSpSizes = new float[] {8f, 10f, 12f, 14f, 18f, 20f, 24f, 30f, 100f};
+        float[] dpInterpolated = new float[commonSpSizes.length];
+
+        for (int i = 0; i < commonSpSizes.length; i++) {
+            float sp = commonSpSizes[i];
+            float startDp = start.convertSpToDp(sp);
+            float endDp = end.convertSpToDp(sp);
+            dpInterpolated[i] = MathUtils.lerp(startDp, endDp, interpolationPoint);
+        }
+
+        return new FontScaleConverter(commonSpSizes, dpInterpolated);
+    }
+
+    private static int getKey(float fontScale) {
+        return (int) (fontScale * SCALE_KEY_MULTIPLIER);
+    }
+
+    private static float getScaleFromKey(int key) {
+        return (float) key / SCALE_KEY_MULTIPLIER;
+    }
+
+    private static void put(float scaleKey, @NonNull FontScaleConverter fontScaleConverter) {
+        LOOKUP_TABLES.put(getKey(scaleKey), fontScaleConverter);
+    }
+
+    @Nullable
+    private static FontScaleConverter get(float scaleKey) {
+        return LOOKUP_TABLES.get(getKey(scaleKey));
+    }
+}
diff --git a/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/MathUtils.java b/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/MathUtils.java
new file mode 100644
index 0000000..5773d03
--- /dev/null
+++ b/wear/protolayout/protolayout-material-core/src/main/java/androidx/wear/protolayout/materialcore/fontscaling/MathUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.wear.protolayout.materialcore.fontscaling;
+
+import static java.lang.Math.min;
+
+/** A class that contains utility methods related to numbers. */
+final class MathUtils {
+    private MathUtils() {}
+
+    /**
+     * Returns the linear interpolation of {@code amount} between {@code start} and {@code stop}.
+     */
+    static float lerp(float start, float stop, float amount) {
+        return start + (stop - start) * amount;
+    }
+
+    /**
+     * Returns the interpolation scalar (s) that satisfies the equation: {@code value = }{@link
+     * #lerp}{@code (a, b, s)}
+     *
+     * <p>If {@code a == b}, then this function will return 0.
+     */
+    static float lerpInv(float a, float b, float value) {
+        return a != b ? ((value - a) / (b - a)) : 0.0f;
+    }
+
+    /** Returns the single argument constrained between [0.0, 1.0]. */
+    static float saturate(float value) {
+        return value < 0.0f ? 0.0f : min(1.0f, value);
+    }
+
+    /** Returns the saturated (constrained between [0, 1]) result of {@link #lerpInv}. */
+    static float lerpInvSat(float a, float b, float value) {
+        return saturate(lerpInv(a, b, value));
+    }
+
+    /**
+     * Calculates a value in [rangeMin, rangeMax] that maps value in [valueMin, valueMax] to
+     * returnVal in [rangeMin, rangeMax].
+     *
+     * <p>Always returns a constrained value in the range [rangeMin, rangeMax], even if value is
+     * outside [valueMin, valueMax].
+     *
+     * <p>Eg: constrainedMap(0f, 100f, 0f, 1f, 0.5f) = 50f constrainedMap(20f, 200f, 10f, 20f, 20f)
+     * = 200f constrainedMap(20f, 200f, 10f, 20f, 50f) = 200f constrainedMap(10f, 50f, 10f, 20f, 5f)
+     * = 10f
+     *
+     * @param rangeMin minimum of the range that should be returned.
+     * @param rangeMax maximum of the range that should be returned.
+     * @param valueMin minimum of range to map {@code value} to.
+     * @param valueMax maximum of range to map {@code value} to.
+     * @param value to map to the range [{@code valueMin}, {@code valueMax}]. Note, can be outside
+     *     this range, resulting in a clamped value.
+     * @return the mapped value, constrained to [{@code rangeMin}, {@code rangeMax}.
+     */
+    static float constrainedMap(
+            float rangeMin, float rangeMax, float valueMin, float valueMax, float value) {
+        return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value));
+    }
+}
diff --git a/wear/protolayout/protolayout-material-core/src/test/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterFactoryTest.kt b/wear/protolayout/protolayout-material-core/src/test/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterFactoryTest.kt
new file mode 100644
index 0000000..841825b
--- /dev/null
+++ b/wear/protolayout/protolayout-material-core/src/test/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterFactoryTest.kt
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.materialcore.fontscaling
+
+import androidx.core.util.forEach
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import kotlin.math.ceil
+import kotlin.math.floor
+import kotlin.random.Random.Default.nextFloat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class FontScaleConverterFactoryTest {
+
+    @Test
+    fun scale200IsTwiceAtSmallSizes() {
+        val table = FontScaleConverterFactory.forScale(2F)!!
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(2f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(16f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(20f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(10f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    @LargeTest
+    @Test
+    fun missingLookupTablePastEnd_returnsLinear() {
+        val table = FontScaleConverterFactory.forScale(3F)!!
+        generateSequenceOfFractions(-10000f..10000f, step = 0.01f).map {
+            assertThat(table.convertSpToDp(it)).isWithin(CONVERSION_TOLERANCE).of(it * 3f)
+        }
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(3f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(24f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(30f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(15f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+        assertThat(table.convertSpToDp(50F)).isWithin(CONVERSION_TOLERANCE).of(150f)
+        assertThat(table.convertSpToDp(100F)).isWithin(CONVERSION_TOLERANCE).of(300f)
+    }
+
+    @SmallTest
+    fun missingLookupTable110_returnsInterpolated() {
+        val table = FontScaleConverterFactory.forScale(1.1F)!!
+
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(1.1f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(8f * 1.1f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(11f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(5f * 1.1f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+        assertThat(table.convertSpToDp(50F)).isLessThan(50f * 1.1f)
+        assertThat(table.convertSpToDp(100F)).isLessThan(100f * 1.1f)
+    }
+
+    @Test
+    fun missingLookupTable199_returnsInterpolated() {
+        val table = FontScaleConverterFactory.forScale(1.9999F)!!
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(2f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(16f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(20f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(10f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    @Test
+    fun missingLookupTable160_returnsInterpolated() {
+        val table = FontScaleConverterFactory.forScale(1.6F)!!
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(1f * 1.6F)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(8f * 1.6F)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(10f * 1.6F)
+        assertThat(table.convertSpToDp(20F)).isLessThan(20f * 1.6F)
+        assertThat(table.convertSpToDp(100F)).isLessThan(100f * 1.6F)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(5f * 1.6F)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    @SmallTest
+    fun missingLookupTableNegativeReturnsNull() {
+        assertThat(FontScaleConverterFactory.forScale(-1F)).isNull()
+    }
+
+    @SmallTest
+    fun unnecessaryFontScalesReturnsNull() {
+        assertThat(FontScaleConverterFactory.forScale(0F)).isNull()
+        assertThat(FontScaleConverterFactory.forScale(1F)).isNull()
+        assertThat(FontScaleConverterFactory.forScale(0.85F)).isNull()
+    }
+
+    @SmallTest
+    fun tablesMatchAndAreMonotonicallyIncreasing() {
+        FontScaleConverterFactory.LOOKUP_TABLES.forEach { _, lookupTable ->
+            assertThat(lookupTable.mToDpValues).hasLength(lookupTable.mFromSpValues.size)
+            assertThat(lookupTable.mToDpValues).isNotEmpty()
+
+            assertThat(lookupTable.mFromSpValues.asList()).isInStrictOrder()
+            assertThat(lookupTable.mToDpValues.asList()).isInStrictOrder()
+
+            assertThat(lookupTable.mFromSpValues.asList()).containsNoDuplicates()
+            assertThat(lookupTable.mToDpValues.asList()).containsNoDuplicates()
+        }
+    }
+
+    @SmallTest
+    fun testIsNonLinearFontScalingActive() {
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1f)).isFalse()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(0f)).isFalse()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(-1f)).isFalse()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(0.85f)).isFalse()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.02f)).isFalse()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.10f)).isFalse()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.15f)).isTrue()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.1499999f)).isTrue()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.5f)).isTrue()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(2f)).isTrue()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(3f)).isTrue()
+    }
+
+    @LargeTest
+    @Test
+    fun allFeasibleScalesAndConversionsDoNotCrash() {
+        generateSequenceOfFractions(-10f..10f, step = 0.1f)
+            .fuzzFractions()
+            .mapNotNull { FontScaleConverterFactory.forScale(it) }
+            .flatMap { table ->
+                generateSequenceOfFractions(-2000f..2000f, step = 0.1f).fuzzFractions().map {
+                    Pair(table, it)
+                }
+            }
+            .forEach { (table, sp) ->
+                try {
+                    // Truth is slow because it creates a bunch of
+                    // objects. Don't use it unless we need to.
+                    if (!table.convertSpToDp(sp).isFinite()) {
+                        assertWithMessage("convertSpToDp(%s) on table: %s", sp, table)
+                            .that(table.convertSpToDp(sp))
+                            .isFinite()
+                    }
+                } catch (e: Exception) {
+                    throw AssertionError("Exception during convertSpToDp($sp) on table: $table", e)
+                }
+            }
+    }
+
+    @Test
+    fun testGenerateSequenceOfFractions() {
+        val fractions = generateSequenceOfFractions(-1000f..1000f, step = 0.1f).toList()
+        fractions.forEach {
+            assertThat(it).isAtLeast(-1000f)
+            assertThat(it).isAtMost(1000f)
+        }
+
+        assertThat(fractions).isInStrictOrder()
+        assertThat(fractions).hasSize(1000 * 2 * 10 + 1) // Don't forget the 0 in the middle!
+
+        assertThat(fractions).contains(100f)
+        assertThat(fractions).contains(500.1f)
+        assertThat(fractions).contains(500.2f)
+        assertThat(fractions).contains(0.2f)
+        assertThat(fractions).contains(0f)
+        assertThat(fractions).contains(-10f)
+        assertThat(fractions).contains(-10f)
+        assertThat(fractions).contains(-10.3f)
+
+        assertThat(fractions).doesNotContain(-10.31f)
+        assertThat(fractions).doesNotContain(0.35f)
+        assertThat(fractions).doesNotContain(0.31f)
+        assertThat(fractions).doesNotContain(-.35f)
+    }
+
+    @Test
+    fun testFuzzFractions() {
+        val numFuzzedFractions = 6
+        val fractions =
+            generateSequenceOfFractions(-1000f..1000f, step = 0.1f).fuzzFractions().toList()
+        fractions.forEach {
+            assertThat(it).isAtLeast(-1000f)
+            assertThat(it).isLessThan(1001f)
+        }
+
+        val numGeneratedFractions = 1000 * 2 * 10 + 1 // Don't forget the 0 in the middle!
+        assertThat(fractions).hasSize(numGeneratedFractions * numFuzzedFractions)
+
+        assertThat(fractions).contains(100f)
+        assertThat(fractions).contains(500.1f)
+        assertThat(fractions).contains(500.2f)
+        assertThat(fractions).contains(0.2f)
+        assertThat(fractions).contains(0f)
+        assertThat(fractions).contains(-10f)
+        assertThat(fractions).contains(-10f)
+        assertThat(fractions).contains(-10.3f)
+    }
+
+    companion object {
+        private const val CONVERSION_TOLERANCE = 0.05f
+    }
+}
+
+fun generateSequenceOfFractions(
+    range: ClosedFloatingPointRange<Float>,
+    step: Float
+): Sequence<Float> {
+    val multiplier = 1f / step
+    val start = floor(range.start * multiplier).toInt()
+    val endInclusive = ceil(range.endInclusive * multiplier).toInt()
+    return generateSequence(start) { it + 1 }
+        .takeWhile { it <= endInclusive }
+        .map { it.toFloat() / multiplier }
+}
+
+private fun Sequence<Float>.fuzzFractions(): Sequence<Float> {
+    return flatMap { i ->
+        listOf(i, i + 0.01f, i + 0.054f, i + 0.099f, i + nextFloat(), i + nextFloat())
+    }
+}
diff --git a/wear/protolayout/protolayout-material-core/src/test/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterTest.kt b/wear/protolayout/protolayout-material-core/src/test/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterTest.kt
new file mode 100644
index 0000000..7dc342a
--- /dev/null
+++ b/wear/protolayout/protolayout-material-core/src/test/java/androidx/wear/protolayout/materialcore/fontscaling/FontScaleConverterTest.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.materialcore.fontscaling
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class FontScaleConverterTest {
+
+    @Test
+    fun straightInterpolation() {
+        val table = createTable(8f to 8f, 10f to 10f, 20f to 20f)
+        verifyConversionBothWays(table, 1f, 1F)
+        verifyConversionBothWays(table, 8f, 8F)
+        verifyConversionBothWays(table, 10f, 10F)
+        verifyConversionBothWays(table, 30f, 30F)
+        verifyConversionBothWays(table, 20f, 20F)
+        verifyConversionBothWays(table, 5f, 5F)
+        verifyConversionBothWays(table, 0f, 0F)
+    }
+
+    @Test
+    fun interpolate200Percent() {
+        val table = createTable(8f to 16f, 10f to 20f, 30f to 60f)
+        verifyConversionBothWays(table, 2f, 1F)
+        verifyConversionBothWays(table, 16f, 8F)
+        verifyConversionBothWays(table, 20f, 10F)
+        verifyConversionBothWays(table, 60f, 30F)
+        verifyConversionBothWays(table, 40f, 20F)
+        verifyConversionBothWays(table, 10f, 5F)
+        verifyConversionBothWays(table, 0f, 0F)
+    }
+
+    @Test
+    fun interpolate150Percent() {
+        val table = createTable(2f to 3f, 10f to 15f, 20f to 30f, 100f to 150f)
+        verifyConversionBothWays(table, 3f, 2F)
+        verifyConversionBothWays(table, 1.5f, 1F)
+        verifyConversionBothWays(table, 12f, 8F)
+        verifyConversionBothWays(table, 15f, 10F)
+        verifyConversionBothWays(table, 30f, 20F)
+        verifyConversionBothWays(table, 75f, 50F)
+        verifyConversionBothWays(table, 7.5f, 5F)
+        verifyConversionBothWays(table, 0f, 0F)
+    }
+
+    @Test
+    fun pastEndsUsesLastScalingFactor() {
+        val table = createTable(8f to 16f, 10f to 20f, 30f to 60f)
+        verifyConversionBothWays(table, 200f, 100F)
+        verifyConversionBothWays(table, 62f, 31F)
+        verifyConversionBothWays(table, 2000f, 1000F)
+        verifyConversionBothWays(table, 4000f, 2000F)
+        verifyConversionBothWays(table, 20000f, 10000F)
+    }
+
+    @Test
+    fun negativeSpIsNegativeDp() {
+        val table = createTable(8f to 16f, 10f to 20f, 30f to 60f)
+        verifyConversionBothWays(table, -2f, -1F)
+        verifyConversionBothWays(table, -16f, -8F)
+        verifyConversionBothWays(table, -20f, -10F)
+        verifyConversionBothWays(table, -60f, -30F)
+        verifyConversionBothWays(table, -40f, -20F)
+        verifyConversionBothWays(table, -10f, -5F)
+        verifyConversionBothWays(table, 0f, -0F)
+    }
+
+    private fun createTable(vararg pairs: Pair<Float, Float>) =
+        FontScaleConverter(
+            pairs.map { it.first }.toFloatArray(),
+            pairs.map { it.second }.toFloatArray()
+        )
+
+    private fun verifyConversionBothWays(
+        table: FontScaleConverter,
+        expectedDp: Float,
+        spToConvert: Float
+    ) {
+        assertWithMessage("convertSpToDp")
+            .that(table.convertSpToDp(spToConvert))
+            .isWithin(CONVERSION_TOLERANCE)
+            .of(expectedDp)
+
+        assertWithMessage("inverse: convertDpToSp")
+            .that(table.convertDpToSp(expectedDp))
+            .isWithin(CONVERSION_TOLERANCE)
+            .of(spToConvert)
+    }
+
+    companion object {
+        private const val CONVERSION_TOLERANCE = 0.05f
+    }
+}
diff --git a/wear/protolayout/protolayout-material/build.gradle b/wear/protolayout/protolayout-material/build.gradle
index be951af..b1d7de5 100644
--- a/wear/protolayout/protolayout-material/build.gradle
+++ b/wear/protolayout/protolayout-material/build.gradle
@@ -49,6 +49,7 @@
     androidTestImplementation(libs.testRunner)
     androidTestImplementation("androidx.core:core:1.7.0")
     androidTestImplementation(project(":test:screenshot:screenshot"))
+    androidTestImplementation(libs.testUiautomator)
     androidTestImplementation(project(":wear:protolayout:protolayout-renderer"))
 
     testImplementation(libs.junit)
diff --git a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java
index 61734b9..c25e2f9 100644
--- a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java
+++ b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java
@@ -16,11 +16,13 @@
 
 package androidx.wear.protolayout.material;
 
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 import static androidx.wear.protolayout.material.RunnerUtils.SCREEN_HEIGHT;
 import static androidx.wear.protolayout.material.RunnerUtils.SCREEN_WIDTH;
 import static androidx.wear.protolayout.material.RunnerUtils.convertToTestParameters;
+import static androidx.wear.protolayout.material.RunnerUtils.getFontScale;
 import static androidx.wear.protolayout.material.RunnerUtils.runSingleScreenshotTest;
+import static androidx.wear.protolayout.material.RunnerUtils.setAndAssertFontScale;
+import static androidx.wear.protolayout.material.RunnerUtils.setFontScale;
 import static androidx.wear.protolayout.material.RunnerUtils.waitForNotificationToDisappears;
 import static androidx.wear.protolayout.material.TestCasesGenerator.XXXL_SCALE_SUFFIX;
 import static androidx.wear.protolayout.material.TestCasesGenerator.generateTestCases;
@@ -34,10 +36,13 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.screenshot.AndroidXScreenshotTestRule;
+import androidx.test.uiautomator.UiDevice;
 import androidx.wear.protolayout.DeviceParametersBuilders;
 import androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters;
 import androidx.wear.protolayout.material.RunnerUtils.TestCase;
 
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -50,15 +55,10 @@
 @RunWith(Parameterized.class)
 @LargeTest
 public class MaterialGoldenXLTest {
-    /* We set DisplayMetrics in the data() method for creating test cases. However, when running all
-    tests together, first all parametrization (data()) methods are called, and then individual
-    tests, causing that actual DisplayMetrics will be different. So we need to restore it before
-    each test. */
-    private static final DisplayMetrics DISPLAY_METRICS_FOR_TEST = new DisplayMetrics();
-    private static final DisplayMetrics OLD_DISPLAY_METRICS = new DisplayMetrics();
-
     private static final float FONT_SCALE_XXXL = 1.24f;
 
+    private static float originalFontScale;
+
     private final TestCase mTestCase;
     private final String mExpected;
 
@@ -66,6 +66,13 @@
     public AndroidXScreenshotTestRule mScreenshotRule =
             new AndroidXScreenshotTestRule("wear/wear-protolayout-material");
 
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        setAndAssertFontScale(
+                UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()),
+                FONT_SCALE_XXXL);
+    }
+
     public MaterialGoldenXLTest(String expected, TestCase testCase) {
         mTestCase = testCase;
         mExpected = expected;
@@ -76,27 +83,18 @@
         return (int) ((px - 0.5f) / scale);
     }
 
-    @SuppressWarnings("deprecation")
     @Parameterized.Parameters(name = "{0}")
-    public static Collection<Object[]> data() {
+    public static Collection<Object[]> data() throws Exception {
+        // These "parameters" methods are called before any parameterized test (from any class)
+        // executes. We set and later reset the font here to have the correct context during test
+        // generation. We later set and reset the font for the actual test in BeforeClass/AfterClass
+        // methods.
+        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        originalFontScale = getFontScale(device);
+        setAndAssertFontScale(device, FONT_SCALE_XXXL);
+
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        DisplayMetrics currentDisplayMetrics = new DisplayMetrics();
         DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
-        currentDisplayMetrics.setTo(displayMetrics);
-        displayMetrics.scaledDensity *= FONT_SCALE_XXXL;
-
-        InstrumentationRegistry.getInstrumentation()
-                .getContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(displayMetrics);
-        InstrumentationRegistry.getInstrumentation()
-                .getTargetContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(displayMetrics);
-
-        DISPLAY_METRICS_FOR_TEST.setTo(displayMetrics);
 
         float scale = displayMetrics.density;
         DeviceParameters deviceParameters =
@@ -104,6 +102,7 @@
                         .setScreenWidthDp(pxToDp(SCREEN_WIDTH, scale))
                         .setScreenHeightDp(pxToDp(SCREEN_HEIGHT, scale))
                         .setScreenDensity(displayMetrics.density)
+                        .setFontScale(context.getResources().getConfiguration().fontScale)
                         // Not important for components.
                         .setScreenShape(DeviceParametersBuilders.SCREEN_SHAPE_RECT)
                         .build();
@@ -126,31 +125,17 @@
                         /* isForLtr= */ true));
 
         // Restore state before this method, so other test have correct context.
-        InstrumentationRegistry.getInstrumentation()
-                .getContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(currentDisplayMetrics);
-        InstrumentationRegistry.getInstrumentation()
-                .getTargetContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(currentDisplayMetrics);
-
+        setAndAssertFontScale(device, originalFontScale);
         waitForNotificationToDisappears();
 
         return testCaseList;
     }
 
-    @Parameterized.BeforeParam
-    public static void restoreBefore() {
-        OLD_DISPLAY_METRICS.setTo(getApplicationContext().getResources().getDisplayMetrics());
-        getApplicationContext().getResources().getDisplayMetrics().setTo(DISPLAY_METRICS_FOR_TEST);
-    }
-
-    @Parameterized.AfterParam
-    public static void restoreAfter() {
-        getApplicationContext().getResources().getDisplayMetrics().setTo(OLD_DISPLAY_METRICS);
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        setFontScale(
+                UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()),
+                originalFontScale);
     }
 
     @Test
diff --git a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/RunnerUtils.java b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/RunnerUtils.java
index 0fe42d3..5ba7a7b 100644
--- a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/RunnerUtils.java
+++ b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/RunnerUtils.java
@@ -16,6 +16,8 @@
 
 package androidx.wear.protolayout.material;
 
+import static org.junit.Assert.assertEquals;
+
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Intent;
@@ -28,11 +30,13 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.screenshot.AndroidXScreenshotTestRule;
 import androidx.test.screenshot.matchers.MSSIMMatcher;
+import androidx.test.uiautomator.UiDevice;
 import androidx.wear.protolayout.LayoutElementBuilders.Layout;
 import androidx.wear.protolayout.material.test.GoldenTestActivity;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 public class RunnerUtils {
@@ -153,4 +157,23 @@
             this.isForLtr = isForLtr;
         }
     }
+
+    public static float getFontScale(UiDevice device) throws Exception {
+        String result = device.executeShellCommand("settings get system font_scale");
+        try {
+            return Float.parseFloat(result);
+        } catch (NumberFormatException e) {
+            return 1.0f;
+        }
+    }
+
+    public static void setFontScale(UiDevice device, float fontScale) throws Exception {
+        device.executeShellCommand("settings put system font_scale " + fontScale);
+    }
+
+    public static void setAndAssertFontScale(UiDevice device, float fontScale) throws Exception {
+        setFontScale(device, fontScale);
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        assertEquals(getFontScale(device), fontScale, 0.0001f);
+    }
 }
diff --git a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java
index 3c49e92..af368f2 100644
--- a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java
+++ b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java
@@ -16,11 +16,13 @@
 
 package androidx.wear.protolayout.material.layouts;
 
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 import static androidx.wear.protolayout.material.RunnerUtils.SCREEN_HEIGHT;
 import static androidx.wear.protolayout.material.RunnerUtils.SCREEN_WIDTH;
 import static androidx.wear.protolayout.material.RunnerUtils.convertToTestParameters;
+import static androidx.wear.protolayout.material.RunnerUtils.getFontScale;
 import static androidx.wear.protolayout.material.RunnerUtils.runSingleScreenshotTest;
+import static androidx.wear.protolayout.material.RunnerUtils.setAndAssertFontScale;
+import static androidx.wear.protolayout.material.RunnerUtils.setFontScale;
 import static androidx.wear.protolayout.material.RunnerUtils.waitForNotificationToDisappears;
 import static androidx.wear.protolayout.material.layouts.TestCasesGenerator.XXXL_SCALE_SUFFIX;
 import static androidx.wear.protolayout.material.layouts.TestCasesGenerator.generateTestCases;
@@ -32,10 +34,13 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.screenshot.AndroidXScreenshotTestRule;
+import androidx.test.uiautomator.UiDevice;
 import androidx.wear.protolayout.DeviceParametersBuilders;
 import androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters;
 import androidx.wear.protolayout.material.RunnerUtils.TestCase;
 
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -47,15 +52,10 @@
 @RunWith(Parameterized.class)
 @LargeTest
 public class LayoutsGoldenXLTest {
-    /* We set DisplayMetrics in the data() method for creating test cases. However, when running all
-    tests together, first all parametrization (data()) methods are called, and then individual
-    tests, causing that actual DisplayMetrics will be different. So we need to restore it before
-    each test. */
-    private static final DisplayMetrics DISPLAY_METRICS_FOR_TEST = new DisplayMetrics();
-    private static final DisplayMetrics OLD_DISPLAY_METRICS = new DisplayMetrics();
-
     private static final float FONT_SCALE_XXXL = 1.24f;
 
+    private static float originalFontScale;
+
     private final TestCase mTestCase;
     private final String mExpected;
 
@@ -63,6 +63,13 @@
     public AndroidXScreenshotTestRule mScreenshotRule =
             new AndroidXScreenshotTestRule("wear/wear-protolayout-material");
 
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        setAndAssertFontScale(
+                UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()),
+                FONT_SCALE_XXXL);
+    }
+
     public LayoutsGoldenXLTest(String expected, TestCase testCase) {
         mTestCase = testCase;
         mExpected = expected;
@@ -73,27 +80,18 @@
         return (int) ((px - 0.5f) / scale);
     }
 
-    @SuppressWarnings("deprecation")
     @Parameterized.Parameters(name = "{0}")
-    public static Collection<Object[]> data() {
+    public static Collection<Object[]> data() throws Exception {
+        // These "parameters" methods are called before any parameterized test (from any class)
+        // executes. We set and later reset the font here to have the correct context during test
+        // generation. We later set and reset the font for the actual test in BeforeClass/AfterClass
+        // methods.
+        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        originalFontScale = getFontScale(device);
+        setAndAssertFontScale(device, FONT_SCALE_XXXL);
+
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        DisplayMetrics currentDisplayMetrics = new DisplayMetrics();
         DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
-        currentDisplayMetrics.setTo(displayMetrics);
-        displayMetrics.scaledDensity *= FONT_SCALE_XXXL;
-
-        InstrumentationRegistry.getInstrumentation()
-                .getContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(displayMetrics);
-        InstrumentationRegistry.getInstrumentation()
-                .getTargetContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(displayMetrics);
-
-        DISPLAY_METRICS_FOR_TEST.setTo(displayMetrics);
 
         float scale = displayMetrics.density;
         DeviceParameters deviceParameters =
@@ -101,6 +99,7 @@
                         .setScreenWidthDp(pxToDp(SCREEN_WIDTH, scale))
                         .setScreenHeightDp(pxToDp(SCREEN_HEIGHT, scale))
                         .setScreenDensity(displayMetrics.density)
+                        .setFontScale(context.getResources().getConfiguration().fontScale)
                         // TODO(b/231543947): Add test cases for round screen.
                         .setScreenShape(DeviceParametersBuilders.SCREEN_SHAPE_RECT)
                         .build();
@@ -111,40 +110,18 @@
                         /* isForRtl= */ true,
                         /* isForLtr= */ true);
 
-        // Restore state before this method, so other test have correct context. This is needed here
-        // too, besides in restoreBefore and restoreAfter as the test cases builder uses the context
-        // to apply font scaling, so we need that display metrics passed in. However, after
-        // generating cases we need to restore the state as other data() methods in this package can
-        // work correctly with the default state, as when the tests are run, first all data() static
-        // methods are called, and then parameterized test cases.
-        InstrumentationRegistry.getInstrumentation()
-                .getContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(currentDisplayMetrics);
-        InstrumentationRegistry.getInstrumentation()
-                .getTargetContext()
-                .getResources()
-                .getDisplayMetrics()
-                .setTo(currentDisplayMetrics);
+        // Restore state before this method, so other test have correct context.
+        setAndAssertFontScale(device, originalFontScale);
         waitForNotificationToDisappears();
 
         return testCaseList;
     }
 
-    @Parameterized.BeforeParam
-    public static void restoreBefore() {
-        // Set the state as it was in data() method when we generated test cases. This was
-        // overridden by other static data() methods, so we need to restore it.
-        OLD_DISPLAY_METRICS.setTo(getApplicationContext().getResources().getDisplayMetrics());
-        getApplicationContext().getResources().getDisplayMetrics().setTo(DISPLAY_METRICS_FOR_TEST);
-    }
-
-    @Parameterized.AfterParam
-    public static void restoreAfter() {
-        // Restore the state to default, so the other tests and emulator have the correct starter
-        // state.
-        getApplicationContext().getResources().getDisplayMetrics().setTo(OLD_DISPLAY_METRICS);
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        setFontScale(
+                UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()),
+                originalFontScale);
     }
 
     @Test
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Typography.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Typography.java
index 9e1613e..da9219f 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Typography.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Typography.java
@@ -16,6 +16,9 @@
 
 package androidx.wear.protolayout.material;
 
+import static android.os.Build.VERSION.SDK_INT;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+
 import static androidx.annotation.Dimension.DP;
 import static androidx.annotation.Dimension.SP;
 import static androidx.wear.protolayout.DimensionBuilders.sp;
@@ -28,7 +31,6 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
-import android.util.DisplayMetrics;
 
 import androidx.annotation.Dimension;
 import androidx.annotation.IntDef;
@@ -40,6 +42,8 @@
 import androidx.wear.protolayout.LayoutElementBuilders.FontStyle;
 import androidx.wear.protolayout.LayoutElementBuilders.FontVariant;
 import androidx.wear.protolayout.LayoutElementBuilders.FontWeight;
+import androidx.wear.protolayout.materialcore.fontscaling.FontScaleConverter;
+import androidx.wear.protolayout.materialcore.fontscaling.FontScaleConverterFactory;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -120,6 +124,9 @@
         TYPOGRAPHY_TO_LINE_HEIGHT_SP.put(TYPOGRAPHY_CAPTION2, 16f);
         TYPOGRAPHY_TO_LINE_HEIGHT_SP.put(TYPOGRAPHY_CAPTION3, 14f);
     }
+
+    private Typography() {}
+
     /**
      * Returns the {@link FontStyle.Builder} for the given FontStyle code with the recommended size,
      * weight and letter spacing. Font will be scalable.
@@ -130,8 +137,6 @@
         return getFontStyleBuilder(fontStyleCode, context, true);
     }
 
-    private Typography() {}
-
     /**
      * Returns the {@link FontStyle.Builder} for the given Typography code with the recommended
      * size, weight and letter spacing, with the option to make this font not scalable.
@@ -183,17 +188,29 @@
         return sp(checkNotNull(TYPOGRAPHY_TO_LINE_HEIGHT_SP.get(typography)).intValue());
     }
 
-    @NonNull
-    @SuppressLint("ResourceType")
-    @SuppressWarnings("deprecation") // scaledDensity, b/335215227
-    // This is a helper function to make the font not scalable. It should interpret in value as DP
-    // and convert it to SP which is needed to be passed in as a font size. However, we will pass an
-    // SP object to it, because the default style is defined in it, but for the case when the font
-    // size on device in 1, so the DP is equal to SP.
-    private static SpProp dpToSp(@NonNull Context context, @Dimension(unit = DP) float valueDp) {
-        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
-        float scaledSp = (valueDp / metrics.scaledDensity) * metrics.density;
-        return sp(scaledSp);
+    /**
+     * This is a helper function to make the font not scalable. It should interpret in value as DP
+     * and convert it to SP which is needed to be passed in as a font size. However, we will pass an
+     * SP object to it, because the default style is defined in it, but for the case when the font
+     * size on device is 1, so the DP is equal to SP.
+     */
+    @Dimension(unit = SP)
+    private static float dpToSp(float fontScale, @Dimension(unit = DP) float valueDp) {
+        FontScaleConverter converter =
+                (SDK_INT >= UPSIDE_DOWN_CAKE)
+                        ? FontScaleConverterFactory.forScale(fontScale)
+                        : null;
+
+        if (converter == null) {
+            return dpToSpLinear(fontScale, valueDp);
+        }
+
+        return converter.convertDpToSp(valueDp);
+    }
+
+    @Dimension(unit = SP)
+    private static float dpToSpLinear(float fontScale, @Dimension(unit = DP) float valueDp) {
+        return valueDp / fontScale;
     }
 
     // The @Dimension(unit = SP) on sp() is seemingly being ignored, so lint complains that we're
@@ -206,8 +223,9 @@
             float letterSpacing,
             boolean isScalable,
             @NonNull Context context) {
+        float fontScale = context.getResources().getConfiguration().fontScale;
         return new FontStyle.Builder()
-                .setSize(isScalable ? DimensionBuilders.sp(size) : dpToSp(context, size))
+                .setSize(DimensionBuilders.sp(isScalable ? size : dpToSp(fontScale, size)))
                 .setLetterSpacing(DimensionBuilders.em(letterSpacing))
                 .setVariant(variant)
                 .setWeight(weight);
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
index 1f636f3..540382b 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
@@ -143,28 +143,31 @@
   // The collection of font settings to be applied.
   //
   // Supported settings depend on the font used and renderer version.
-  // If this is used with the variable fonts on renderers supporting 1.4, weight and width setting
-  // will be always available.
+  // <setter>If this is used with the variable fonts on renderers
+  // supporting 1.4, weight and width setting will always be available.</setter>
   repeated FontSetting settings = 8;
 
-  // The prioritized collection of font family names describing which font should be used for this
-  // FontStyle and its fallback values if not available. For example, preferring default system
-  // variable font with default non variable system font as a fallback. If not set, defaults to
-  // system font.
+  // The prioritized collection of font family names describing which font
+  // should be used for this FontStyle and its fallback values if not available.
+  // For example, preferring default system variable font with default non
+  // variable system font as a fallback. <setter>If not set, defaults to system
+  // font.</setter>
   repeated string preferred_font_families = 9;
 }
 
 // A single point of customization in a font.
 message FontSetting {
   oneof inner {
-    // A single point of customization in a font variation, with axis tag and a value for it.
+    // A single point of customization in a font variation, with axis tag and a
+    // value for it.
     FontVariationSetting variation = 1;
     // A single point of customization in a font feature, with specified tag.
     FontFeatureSetting feature = 2;
   }
 }
 
-// A single point of customization in a font variation, with axis tag and a value for it.
+// A single point of customization in a font variation, with axis tag and a
+// value for it.
 message FontVariationSetting {
   // The axis tag for this setting. This represents a 4 ASCII characters tag.
   fixed32 axis_tag = 1;
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
index a02182a..df8091a 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
@@ -19,6 +19,8 @@
 import static androidx.wear.protolayout.DimensionBuilders.sp;
 import static androidx.wear.protolayout.expression.Preconditions.checkNotNull;
 
+import static java.nio.charset.StandardCharsets.US_ASCII;
+
 import android.annotation.SuppressLint;
 import android.graphics.Color;
 import android.util.Log;
@@ -86,13 +88,12 @@
  * layouts.
  */
 public final class LayoutElementBuilders {
+    private LayoutElementBuilders() {}
 
     @VisibleForTesting static final String WEIGHT_AXIS_TAG = "wght";
     @VisibleForTesting static final String WIDTH_AXIS_TAG = "wdth";
     @VisibleForTesting static final String TABULAR_OPTION_TAG = "tnum";
 
-    private LayoutElementBuilders() {}
-
     /** The weight to be applied to the font. */
     @RequiresSchemaVersion(major = 1, minor = 0)
     @RestrictTo(RestrictTo.Scope.LIBRARY)
@@ -217,8 +218,8 @@
      *
      * @deprecated Use {@link #TEXT_OVERFLOW_ELLIPSIZE} instead.
      */
-    @Deprecated
     @RequiresSchemaVersion(major = 1, minor = 0)
+    @Deprecated
     public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2;
 
     /**
@@ -670,9 +671,7 @@
         /**
          * Gets the collection of font settings to be applied.
          *
-         * <p>Supported settings depend on the font used and renderer version. If this is used with
-         * the variable fonts on renderers supporting 1.4, {@link FontSetting#weight} and
-         * {@link FontSetting#width} setting will be always available.
+         * <p>Supported settings depend on the font used and renderer version.
          */
         @NonNull
         public List<FontSetting> getSettings() {
@@ -684,9 +683,10 @@
         }
 
         /**
-         * Gets the original font family name and its fallback values describing which font should
-         * be used for this {@link FontStyle}. For example, default font ProtoLayout, variable
-         * version of default font.
+         * Gets the prioritized collection of font family names describing which font should be used
+         * for this {@link FontStyle} and its fallback values if not available. For example,
+         * preferring default system variable font with default non variable system font as a
+         * fallback.
          */
         @NonNull
         public List<String> getPreferredFontFamilies() {
@@ -762,15 +762,13 @@
                     + getVariant()
                     + ", settings="
                     + getSettings()
-                    + ", fontFamily="
+                    + ", preferredFontFamilies="
                     + getPreferredFontFamilies()
                     + "}";
         }
 
         /** Builder for {@link FontStyle} */
         public static final class Builder {
-            @VisibleForTesting static final int TEXT_SIZES_LIMIT = 10;
-
             private final LayoutElementProto.FontStyle.Builder mImpl =
                     LayoutElementProto.FontStyle.newBuilder();
             private final Fingerprint mFingerprint = new Fingerprint(-374492482);
@@ -924,8 +922,8 @@
              * Adds one item to the collection of font settings to be applied.
              *
              * <p>Supported settings depend on the font used and renderer version. If this is used
-             * with the variable fonts on renderers supporting 1.4, {@link FontSetting#weight} and
-             * {@link FontSetting#width} setting will be always available.
+             * with the variable fonts on renderers supporting 1.4, weight and width setting will be
+             * always available.
              */
             @RequiresSchemaVersion(major = 1, minor = 400)
             @NonNull
@@ -937,6 +935,22 @@
             }
 
             /**
+             * Adds one item to the prioritized collection of font family names describing which
+             * font should be used for this {@link FontStyle} and its fallback values if not
+             * available. For example, preferring default system variable font with default non
+             * variable system font as a fallback. If not set, defaults to system font.
+             */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            @NonNull
+            private Builder addPreferredFontFamily(@NonNull String preferredFontFamily) {
+                mImpl.addPreferredFontFamilies(preferredFontFamily);
+                mFingerprint.recordPropertyUpdate(9, preferredFontFamily.hashCode());
+                return this;
+            }
+
+            @VisibleForTesting static final int TEXT_SIZES_LIMIT = 10;
+
+            /**
              * Sets the available sizes of the font, in scaled pixels (sp). If not specified,
              * defaults to the size of the system's "body" font.
              *
@@ -964,16 +978,16 @@
              * the last size among multiple values.
              *
              * @throws IllegalArgumentException if the number of available sizes is larger than 10
-             * or one of the sizes is not a positive value.
+             *     or one of the sizes is not a positive value.
              */
-            @RequiresSchemaVersion(major = 1, minor = 300)
             @NonNull
+            @RequiresSchemaVersion(major = 1, minor = 300)
             @ProtoLayoutExperimental
             public Builder setSizes(
                     @NonNull @IntRange(from = 1) @Dimension(unit = Dimension.SP) int... sizes) {
                 if (sizes.length > TEXT_SIZES_LIMIT) {
                     throw new IllegalArgumentException(
-                            "Number of available sizes of the font style can't be larger than 10.");
+                            "Number of available sizes can't be larger than 10.");
                 }
 
                 mImpl.clearSize();
@@ -1009,6 +1023,58 @@
                 return this;
             }
 
+            /** The recommended font family names to be used within {@link FontStyle}. */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            @RestrictTo(RestrictTo.Scope.LIBRARY)
+            @Retention(RetentionPolicy.SOURCE)
+            @StringDef(
+                    value = {DEFAULT_SYSTEM_FONT, ROBOTO_FONT, ROBOTO_FLEX_FONT},
+                    open = true)
+            public @interface FontFamilyNames {}
+
+            /**
+             * Font family name that uses default system font. Supported in any renderer version.
+             */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            public static final String DEFAULT_SYSTEM_FONT = "default";
+
+            /** Font family name that uses Roboto font. Supported in renderers supporting 1.4. */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            public static final String ROBOTO_FONT = "roboto";
+
+            /**
+             * Font family name that uses Roboto Flex variable font. Supported in renderers
+             * supporting 1.4.
+             */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            public static final String ROBOTO_FLEX_FONT = "roboto-flex";
+
+            /**
+             * Sets the preferred font families for this {@link FontStyle}.
+             *
+             * <p>For example, preferring default system variable font with default non variable
+             * system font as a fallback.
+             *
+             * <p>If the given font family is not available on a device, the fallback values will be
+             * attempted to use, in order in which they are given.
+             *
+             * <p>Renderer support for values outside of the given constants ( {@link
+             * #DEFAULT_SYSTEM_FONT}, {@link #ROBOTO_FONT} or {@link #ROBOTO_FLEX_FONT}) is not
+             * guaranteed for all devices.
+             *
+             * <p>If not set, default system font will be used.
+             */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            @NonNull
+            public Builder setPreferredFontFamilies(
+                    @NonNull @FontFamilyNames String fontFamily, @NonNull String... fallbacks) {
+                addPreferredFontFamily(fontFamily);
+                for (String fallback : fallbacks) {
+                    addPreferredFontFamily(fallback);
+                }
+                return this;
+            }
+
             @VisibleForTesting static final int SETTINGS_LIMIT = 10;
 
             /**
@@ -1019,7 +1085,7 @@
              *
              * <p>Supported settings depend on the font used and renderer version. If this is used
              * with the variable fonts on renderers supporting 1.4, {@link FontSetting#weight} and
-             * {@link FontSetting#width} setting will be always available.
+             * {@link FontSetting#width} setting will always be available.
              *
              * @throws IllegalArgumentException if the number of the given Setting is larger than
              *  10.
@@ -1065,72 +1131,6 @@
                 return this;
             }
 
-            /**
-             * Adds one item to the font family describing which font should be used for this {@link
-             * FontStyle}. For example, using default font in ProtoLayout or its variable version.
-             * If not set, default font will be used.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @NonNull
-            private Builder addPreferredFontFamily(@NonNull String fontFamily) {
-                mImpl.addPreferredFontFamilies(fontFamily);
-                mFingerprint.recordPropertyUpdate(9, fontFamily.hashCode());
-                return this;
-            }
-
-            /** The recommended font family names to be used within {@link FontStyle}. */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @RestrictTo(RestrictTo.Scope.LIBRARY)
-            @Retention(RetentionPolicy.SOURCE)
-            @StringDef(
-                    value = {DEFAULT_SYSTEM_FONT, ROBOTO_FONT, ROBOTO_FLEX_FONT},
-                    open = true)
-            public @interface FontFamilyNames {}
-
-            /**
-             * Font family name that uses default system font. Supported in any renderer version.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            public static final String DEFAULT_SYSTEM_FONT = "default";
-
-            /** Font family name that uses Roboto font. Supported in renderers supporting 1.4. */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            public static final String ROBOTO_FONT = "roboto";
-
-            /**
-             * Font family name that uses Roboto Flex variable font. Supported in renderers
-             * supporting 1.4.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            public static final String ROBOTO_FLEX_FONT = "roboto-flex";
-
-            /**
-             * Sets the preferred font families for this {@link FontStyle}.
-             *
-             * <p>For example, preferring default system variable font with default non variable
-             * system font as a fallback.
-             *
-             * <p>If the given font family is not available on a device, the fallback values will
-             * be attempted to use, in order in which they are given.
-             *
-             * <p>Renderer support for values outside of the given constants (
-             * {@link #DEFAULT_SYSTEM_FONT}, {@link #ROBOTO_FONT} or {@link #ROBOTO_FLEX_FONT}) is
-             * not guaranteed for all devices.
-             *
-             * <p>If not set, default system font will be used.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @NonNull
-            public Builder setPreferredFontFamilies(
-                    @NonNull @FontFamilyNames String fontFamily,
-                    @NonNull String... fallbacks) {
-                addPreferredFontFamily(fontFamily);
-                for (String fallback : fallbacks) {
-                    addPreferredFontFamily(fallback);
-                }
-                return this;
-            }
-
             /** Builds an instance from accumulated values. */
             @NonNull
             public FontStyle build() {
@@ -1147,24 +1147,10 @@
         @NonNull
         LayoutElementProto.FontSetting toFontSettingProto();
 
-        /** Get the fingerprint for this object or null if unknown. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @Nullable
-        Fingerprint getFingerprint();
-
-        /** Builder to create {@link FontSetting} objects. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        interface Builder {
-
-            /** Builds an instance with values accumulated in this Builder. */
-            @NonNull
-            FontSetting build();
-        }
-
         /**
-         * {@link FontSetting} option for custom weight for font. Similar to the {@link FontWeightProp} but
-         * it accepts any value. For more information, see
-         * <a href="https://fonts.google.com/knowledge/glossary/weight_axis">here</a>.
+         * {@link FontSetting} option for custom weight for font. Similar to the {@link
+         * FontWeightProp} but it accepts any value. For more information, see <a
+         * href="https://fonts.google.com/knowledge/glossary/weight_axis">here</a>.
          *
          * <p>Note that using this {@link FontSetting} will override {@link
          * FontStyle.Builder#setWeight}.
@@ -1178,8 +1164,8 @@
         }
 
         /**
-         * {@link FontSetting} option for custom width for font. For more information, see
-         * <a href="https://fonts.google.com/knowledge/glossary/width_axis">here</a>.
+         * {@link FontSetting} option for custom width for font. For more information, see <a
+         * href="https://fonts.google.com/knowledge/glossary/width_axis">here</a>.
          *
          * @param value width, usually in 25..200, but actual range can depend on the font used
          */
@@ -1190,9 +1176,9 @@
         }
 
         /**
-         * {@link FontSetting} option for enabling displaying tabular figures. In other words,
-         * all numeral characters will have the same width. This corresponds to
-         * {@code tnum} OpenType feature.
+         * {@link FontSetting} option for enabling displaying tabular numerals. In other words, all
+         * numeral characters will have the same width. This corresponds to {@code tnum} OpenType
+         * feature.
          *
          * <p>This setting's availability is font dependent and may not have effect on all font
          * families, some of them like Roboto automatically space out numeral characters to have the
@@ -1203,6 +1189,20 @@
         static FontSetting tabularNum() {
             return new FontFeatureSetting.Builder(TABULAR_OPTION_TAG).build();
         }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link FontSetting} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            FontSetting build();
+        }
     }
 
     /** Creates a new wrapper instance from the proto. */
@@ -1213,6 +1213,9 @@
         if (proto.hasVariation()) {
             return FontVariationSetting.fromProto(proto.getVariation(), fingerprint);
         }
+        if (proto.hasFeature()) {
+            return FontFeatureSetting.fromProto(proto.getFeature(), fingerprint);
+        }
         throw new IllegalStateException("Proto was not a recognised instance of FontSetting");
     }
 
@@ -1221,6 +1224,257 @@
         return fontSettingFromProto(proto, null);
     }
 
+    /** A single point of customization in a font variation, with axis tag and a value for it. */
+    @RequiresSchemaVersion(major = 1, minor = 400)
+    static final class FontVariationSetting implements FontSetting {
+        private final LayoutElementProto.FontVariationSetting mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        FontVariationSetting(
+                LayoutElementProto.FontVariationSetting impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /** Gets the value for this setting. */
+        float getValue() {
+            return mImpl.getValue();
+        }
+
+        /** Gets the axis tag for this font setting. This represents a 4 ASCII characters tag. */
+        @NonNull
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        public String getAxisTag() {
+            return new String(ByteBuffer.allocate(4).putInt(mImpl.getAxisTag()).array(), US_ASCII);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            FontVariationSetting that = (FontVariationSetting) o;
+            return Objects.equals(getAxisTag(), that.getAxisTag())
+                    && Float.compare(getValue(), that.getValue()) == 0;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(getAxisTag(), getValue());
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        /** Creates a new wrapper instance from the proto. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public static FontVariationSetting fromProto(
+                @NonNull LayoutElementProto.FontVariationSetting proto,
+                @Nullable Fingerprint fingerprint) {
+            return new FontVariationSetting(proto, fingerprint);
+        }
+
+        @NonNull
+        static FontVariationSetting fromProto(
+                @NonNull LayoutElementProto.FontVariationSetting proto) {
+            return fromProto(proto, null);
+        }
+
+        /** Returns the internal proto instance. */
+        @NonNull
+        LayoutElementProto.FontVariationSetting toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public LayoutElementProto.FontSetting toFontSettingProto() {
+            return LayoutElementProto.FontSetting.newBuilder().setVariation(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "FontVariationSetting{" + "value=" + getValue() + "}";
+        }
+
+        /** Builder for {@link FontVariationSetting}. */
+        @SuppressWarnings("HiddenSuperclass")
+        public static final class Builder implements FontSetting.Builder {
+            private final LayoutElementProto.FontVariationSetting.Builder mImpl =
+                    LayoutElementProto.FontVariationSetting.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(361361700);
+
+            /** Sets the value for this setting. */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            @NonNull
+            Builder setValue(float value) {
+                mImpl.setValue(value);
+                mFingerprint.recordPropertyUpdate(2, Float.floatToIntBits(value));
+                return this;
+            }
+
+            /**
+             * Creates an instance of {@link Builder}.
+             *
+             * @param axisTag the axis tag for this font setting. This represents a 4 ASCII
+             *     characters tag.
+             * @param value the value for this font setting.
+             */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            public Builder(@NonNull String axisTag, float value) {
+                setAxisTag(axisTag);
+                setValue(value);
+            }
+
+            /**
+             * Sets the axis tag for this font setting. This represents a 4 ASCII characters tag.
+             */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            @NonNull
+            Builder setAxisTag(@NonNull String axisTag) {
+                int axisTagInt = ByteBuffer.wrap(axisTag.getBytes()).getInt();
+                mImpl.setAxisTag(axisTagInt);
+                mFingerprint.recordPropertyUpdate(1, axisTagInt);
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @Override
+            @NonNull
+            public FontVariationSetting build() {
+                return new FontVariationSetting(mImpl.build(), mFingerprint);
+            }
+        }
+    }
+
+    /** A single point of customization in a font feature, with specified tag. */
+    @RequiresSchemaVersion(major = 1, minor = 400)
+    static final class FontFeatureSetting implements FontSetting {
+        private final LayoutElementProto.FontFeatureSetting mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        FontFeatureSetting(
+                LayoutElementProto.FontFeatureSetting impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /** Gets the feature tag. This represents a 4 ASCII characters tag. */
+        @NonNull
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        public String getTag() {
+            return new String(
+                    ByteBuffer.allocate(4).putInt(mImpl.getTag()).array(),
+                    StandardCharsets.US_ASCII);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            FontFeatureSetting that = (FontFeatureSetting) o;
+            return Objects.equals(getTag(), that.getTag());
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(getTag());
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        /** Creates a new wrapper instance from the proto. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public static FontFeatureSetting fromProto(
+                @NonNull LayoutElementProto.FontFeatureSetting proto,
+                @Nullable Fingerprint fingerprint) {
+            return new FontFeatureSetting(proto, fingerprint);
+        }
+
+        @NonNull
+        static FontFeatureSetting fromProto(@NonNull LayoutElementProto.FontFeatureSetting proto) {
+            return fromProto(proto, null);
+        }
+
+        /** Returns the internal proto instance. */
+        @NonNull
+        LayoutElementProto.FontFeatureSetting toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public LayoutElementProto.FontSetting toFontSettingProto() {
+            return LayoutElementProto.FontSetting.newBuilder().setFeature(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "FontFeatureSetting";
+        }
+
+        /** Builder for {@link FontFeatureSetting}. */
+        @SuppressWarnings("HiddenSuperclass")
+        public static final class Builder implements FontSetting.Builder {
+            private final LayoutElementProto.FontFeatureSetting.Builder mImpl =
+                    LayoutElementProto.FontFeatureSetting.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-2557130);
+
+            /**
+             * Creates an instance of {@link Builder}.
+             *
+             * @param tag the tag for this font feature. This represents a 4 ASCII characters tag.
+             */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            public Builder(@NonNull String tag) {
+                setTag(tag);
+            }
+
+            /** Sets the feature tag. This represents a 4 ASCII characters tag. */
+            @RequiresSchemaVersion(major = 1, minor = 400)
+            @NonNull
+            Builder setTag(@NonNull String tag) {
+                int tagInt = ByteBuffer.wrap(tag.getBytes()).getInt();
+                mImpl.setTag(tagInt);
+                mFingerprint.recordPropertyUpdate(1, tagInt);
+                return this;
+            }
+
+            /** Builds an instance from accumulated values. */
+            @Override
+            @NonNull
+            public FontFeatureSetting build() {
+                return new FontFeatureSetting(mImpl.build(), mFingerprint);
+            }
+        }
+    }
+
     /** An extensible {@code TextOverflow} property. */
     @RequiresSchemaVersion(major = 1, minor = 0)
     public static final class TextOverflowProp {
@@ -6391,277 +6645,4 @@
     }
     return false;
   }
-
-    /** A single point of customization in a font, with axis tag and a value for it. */
-    @RequiresSchemaVersion(major = 1, minor = 400)
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    public static final class FontVariationSetting implements FontSetting {
-        private final LayoutElementProto.FontVariationSetting mImpl;
-        @Nullable private final Fingerprint mFingerprint;
-
-        FontVariationSetting(
-                LayoutElementProto.FontVariationSetting impl, @Nullable Fingerprint fingerprint) {
-            this.mImpl = impl;
-            this.mFingerprint = fingerprint;
-        }
-
-        /** Gets the value for this font setting. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public float getValue() {
-            return mImpl.getValue();
-        }
-
-        /** Gets the axis tag for this font setting. This represents a 4 ASCII characters tag. */
-        @NonNull
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public String getAxisTag() {
-            return new String(
-                    ByteBuffer.allocate(4).putInt(mImpl.getAxisTag()).array(),
-                    StandardCharsets.US_ASCII);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-
-            FontVariationSetting that = (FontVariationSetting) o;
-            return Objects.equals(getAxisTag(), that.getAxisTag())
-                    && Objects.equals(getValue(), that.getValue());
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(getAxisTag(), getValue());
-        }
-
-        /** Get the fingerprint for this object, or null if unknown. */
-        @Override
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @Nullable
-        public Fingerprint getFingerprint() {
-            return mFingerprint;
-        }
-
-        /** Creates a new wrapper instance from the proto. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public static FontVariationSetting fromProto(
-                @NonNull LayoutElementProto.FontVariationSetting proto,
-                @Nullable Fingerprint fingerprint) {
-            return new FontVariationSetting(proto, fingerprint);
-        }
-
-        @NonNull
-        static FontVariationSetting fromProto(
-                @NonNull LayoutElementProto.FontVariationSetting proto) {
-            return fromProto(proto, null);
-        }
-
-        /** Returns the internal proto instance. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public LayoutElementProto.FontVariationSetting toProto() {
-            return mImpl;
-        }
-
-        @Override
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public LayoutElementProto.FontSetting toFontSettingProto() {
-            return LayoutElementProto.FontSetting.newBuilder().setVariation(mImpl).build();
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return "FontVariationSetting{"
-                    + "axisTag="
-                    + getAxisTag()
-                    + ", value="
-                    + getValue()
-                    + "}";
-        }
-
-        /** Builder for {@link FontSetting} */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public static final class Builder implements FontSetting.Builder {
-            private final LayoutElementProto.FontVariationSetting.Builder mImpl =
-                    LayoutElementProto.FontVariationSetting.newBuilder();
-            private final Fingerprint mFingerprint = new Fingerprint(843808384);
-
-            /** Sets the value for this font setting. */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @NonNull
-            Builder setValue(float value) {
-                mImpl.setValue(value);
-                mFingerprint.recordPropertyUpdate(2, Float.floatToIntBits(value));
-                return this;
-            }
-
-            /**
-             * Creates an instance of {@link Builder}.
-             *
-             * @param axisTag the axis tag for this font setting. This represents a 4 ASCII
-             *                 characters tag.
-             * @param value the value for this font setting.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @SuppressLint("CheckResult") // (b/247804720)
-            public Builder(@NonNull String axisTag, float value) {
-                setAxisTag(axisTag);
-                setValue(value);
-            }
-
-            /**
-             * Sets the axis tag for this font setting. This represents a 4 ASCII characters tag.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @NonNull
-            Builder setAxisTag(@NonNull String axisTag) {
-                int axisTagInt = ByteBuffer.wrap(axisTag.getBytes()).getInt();
-                mImpl.setAxisTag(axisTagInt);
-                mFingerprint.recordPropertyUpdate(1, axisTagInt);
-                return this;
-            }
-
-            /** Builds an instance from accumulated values. */
-            @Override
-            @NonNull
-            public FontVariationSetting build() {
-                return new FontVariationSetting(mImpl.build(), mFingerprint);
-            }
-        }
-    }
-
-    /** A single point of customization in a font feature, with specified tag. */
-    @RequiresSchemaVersion(major = 1, minor = 400)
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    public static final class FontFeatureSetting implements FontSetting {
-        private final LayoutElementProto.FontFeatureSetting mImpl;
-        @Nullable private final Fingerprint mFingerprint;
-
-        FontFeatureSetting(
-                LayoutElementProto.FontFeatureSetting impl, @Nullable Fingerprint fingerprint) {
-            this.mImpl = impl;
-            this.mFingerprint = fingerprint;
-        }
-
-        /** Gets the feature tag. This represents a 4 ASCII characters tag. */
-        @NonNull
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public String getTag() {
-            return new String(
-                    ByteBuffer.allocate(4).putInt(mImpl.getTag()).array(),
-                    StandardCharsets.US_ASCII);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-
-            FontFeatureSetting that = (FontFeatureSetting) o;
-            return Objects.equals(getTag(), that.getTag());
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(getTag());
-        }
-
-        /** Get the fingerprint for this object, or null if unknown. */
-        @Override
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @Nullable
-        public Fingerprint getFingerprint() {
-            return mFingerprint;
-        }
-
-        /** Creates a new wrapper instance from the proto. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public static FontFeatureSetting fromProto(
-                @NonNull LayoutElementProto.FontFeatureSetting proto,
-                @Nullable Fingerprint fingerprint) {
-            return new FontFeatureSetting(proto, fingerprint);
-        }
-
-        @NonNull
-        static FontFeatureSetting fromProto(
-                @NonNull LayoutElementProto.FontFeatureSetting proto) {
-            return fromProto(proto, null);
-        }
-
-        /** Returns the internal proto instance. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public LayoutElementProto.FontFeatureSetting toProto() {
-            return mImpl;
-        }
-
-        @Override
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public LayoutElementProto.FontSetting toFontSettingProto() {
-            return LayoutElementProto.FontSetting.newBuilder().setFeature(mImpl).build();
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return "FontFeatureSetting{"
-                    + "tag="
-                    + getTag()
-                    + "}";
-        }
-
-        /** Builder for {@link FontFeatureSetting} */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public static final class Builder implements FontSetting.Builder {
-            private final LayoutElementProto.FontFeatureSetting.Builder mImpl =
-                    LayoutElementProto.FontFeatureSetting.newBuilder();
-            private final Fingerprint mFingerprint = new Fingerprint(843808384);
-
-            /**
-             * Creates an instance of {@link Builder}.
-             *
-             * @param tag the tag for this font feature. This represents a 4 ASCII characters tag.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @SuppressLint("CheckResult") // (b/247804720)
-            public Builder(@NonNull String tag) {
-                setTag(tag);
-            }
-
-            /**
-             * Sets the feature tag. This represents a 4 ASCII characters tag.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 400)
-            @NonNull
-            Builder setTag(@NonNull String tag) {
-                int tagInt = ByteBuffer.wrap(tag.getBytes()).getInt();
-                mImpl.setTag(tagInt);
-                mFingerprint.recordPropertyUpdate(1, tagInt);
-                return this;
-            }
-
-            /** Builds an instance from accumulated values. */
-            @Override
-            @NonNull
-            public FontFeatureSetting build() {
-                return new FontFeatureSetting(mImpl.build(), mFingerprint);
-            }
-        }
-    }
 }
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
index d82ced2..8620e76 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
@@ -520,16 +520,18 @@
                 new LayoutElementBuilders.FontVariationSetting.Builder(repeatedAxis, expectedValue)
                         .build();
         LayoutElementBuilders.FontSetting setting1Repeated =
-                new LayoutElementBuilders.FontVariationSetting
-                        .Builder(repeatedAxis, expectedValue + 5)
+                new LayoutElementBuilders.FontVariationSetting.Builder(
+                                repeatedAxis, expectedValue + 5)
                         .build();
         LayoutElementBuilders.FontVariationSetting setting2 =
                 new LayoutElementBuilders.FontVariationSetting.Builder(
-                        /* axisTag= */ "tst2", /* value= */ 200).build();
+                                /* axisTag= */ "tst2", /* value= */ 200)
+                        .build();
 
         LayoutElementBuilders.FontStyle fontStyle =
                 new LayoutElementBuilders.FontStyle.Builder()
-                        .setSettings(setting1, setting2, setting1Repeated).build();
+                        .setSettings(setting1, setting2, setting1Repeated)
+                        .build();
         LayoutElementProto.FontStyle fontStyleProto = fontStyle.toProto();
 
         List<LayoutElementProto.FontSetting> settingsList = fontStyleProto.getSettingsList();
@@ -547,15 +549,18 @@
                 new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 300).build();
         LayoutElementBuilders.FontSetting setting2 =
                 new LayoutElementBuilders.FontVariationSetting.Builder(
-                        /* axisTag= */ "axs2", /* value= */ 200).build();
+                                /* axisTag= */ "axs2", /* value= */ 200)
+                        .build();
         LayoutElementBuilders.FontSetting setting3 =
                 new LayoutElementBuilders.FontVariationSetting.Builder(
-                        /* axisTag= */ expectedAxis, expectedValue).build();
+                                /* axisTag= */ expectedAxis, expectedValue)
+                        .build();
 
         LayoutElementBuilders.FontStyle fontStyle =
                 new LayoutElementBuilders.FontStyle.Builder()
                         .setSettings(setting1, setting2)
-                        .setSettings(setting3).build();
+                        .setSettings(setting3)
+                        .build();
         LayoutElementProto.FontStyle fontStyleProto = fontStyle.toProto();
 
         List<LayoutElementProto.FontSetting> settingsList = fontStyleProto.getSettingsList();
@@ -586,13 +591,11 @@
 
         String actualAxis1Tag =
                 new String(
-                        ByteBuffer.allocate(4)
-                                .putInt(settingsList.get(0).getAxisTag()).array(),
+                        ByteBuffer.allocate(4).putInt(settingsList.get(0).getAxisTag()).array(),
                         StandardCharsets.US_ASCII);
         String actualAxis2Tag =
                 new String(
-                        ByteBuffer.allocate(4)
-                                .putInt(settingsList.get(1).getAxisTag()).array(),
+                        ByteBuffer.allocate(4).putInt(settingsList.get(1).getAxisTag()).array(),
                         StandardCharsets.US_ASCII);
 
         assertThat(actualAxis1Tag).isEqualTo(WEIGHT_AXIS_TAG);
@@ -606,8 +609,7 @@
     public void testFontSettings_setTnum() {
         LayoutElementBuilders.FontStyle fontStyle =
                 new LayoutElementBuilders.FontStyle.Builder()
-                        .setSettings(
-                                LayoutElementBuilders.FontSetting.tabularNum())
+                        .setSettings(LayoutElementBuilders.FontSetting.tabularNum())
                         .build();
         LayoutElementProto.FontStyle fontStyleProto = fontStyle.toProto();
 
@@ -620,8 +622,7 @@
 
         String actualAxis1Tag =
                 new String(
-                        ByteBuffer.allocate(4)
-                                .putInt(settingsList.get(0).getTag()).array(),
+                        ByteBuffer.allocate(4).putInt(settingsList.get(0).getTag()).array(),
                         StandardCharsets.US_ASCII);
 
         assertThat(actualAxis1Tag).isEqualTo(TABULAR_OPTION_TAG);
@@ -643,11 +644,9 @@
     @Test
     public void testSetting_equal() {
         LayoutElementBuilders.FontSetting setting1 =
-                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100)
-                        .build();
+                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100).build();
         LayoutElementBuilders.FontSetting setting2 =
-                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100)
-                        .build();
+                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100).build();
 
         assertThat(setting1).isEqualTo(setting2);
         assertThat(setting1.hashCode()).isEqualTo(setting2.hashCode());
@@ -656,11 +655,9 @@
     @Test
     public void testSetting_notEqualTag() {
         LayoutElementBuilders.FontSetting setting1 =
-                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100)
-                        .build();
+                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100).build();
         LayoutElementBuilders.FontSetting setting2 =
-                new LayoutElementBuilders.FontVariationSetting.Builder("axs2", 100)
-                        .build();
+                new LayoutElementBuilders.FontVariationSetting.Builder("axs2", 100).build();
 
         assertThat(setting1).isNotEqualTo(setting2);
         assertThat(setting1.hashCode()).isNotEqualTo(setting2.hashCode());
@@ -669,11 +666,9 @@
     @Test
     public void testSetting_notEqualValue() {
         LayoutElementBuilders.FontSetting setting1 =
-                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100)
-                        .build();
+                new LayoutElementBuilders.FontVariationSetting.Builder("axs1", 100).build();
         LayoutElementBuilders.FontSetting setting2 =
-                new LayoutElementBuilders.FontVariationSetting.Builder("axs21", 200)
-                        .build();
+                new LayoutElementBuilders.FontVariationSetting.Builder("axs21", 200).build();
 
         assertThat(setting1).isNotEqualTo(setting2);
         assertThat(setting1.hashCode()).isNotEqualTo(setting2.hashCode());
@@ -682,13 +677,11 @@
     @Test
     public void testFontSettings_tooManySettings_throws() {
         LayoutElementBuilders.FontSetting[] sizes =
-                new LayoutElementBuilders.FontSetting[
-                        LayoutElementBuilders.FontStyle.Builder.SETTINGS_LIMIT + 1];
+                new LayoutElementBuilders.FontSetting
+                        [LayoutElementBuilders.FontStyle.Builder.SETTINGS_LIMIT + 1];
         assertThrows(
                 IllegalArgumentException.class,
-                () -> new LayoutElementBuilders.FontStyle.Builder()
-                        .setSettings(sizes)
-                        .build());
+                () -> new LayoutElementBuilders.FontStyle.Builder().setSettings(sizes).build());
     }
 
     @Test