Merge changes Ie7275ac8,I69790219,I22106869 into androidx-main

* changes:
  Avoid using UAST implementation class
  Use Analysis API to find type argument of a call
  Switch to depend on androidLintApi to use Analysis API
diff --git a/appcompat/appcompat/src/androidTest/AndroidManifest.xml b/appcompat/appcompat/src/androidTest/AndroidManifest.xml
index fb17a4b..aa16fad 100644
--- a/appcompat/appcompat/src/androidTest/AndroidManifest.xml
+++ b/appcompat/appcompat/src/androidTest/AndroidManifest.xml
@@ -131,6 +131,11 @@
             android:theme="@style/Theme.TextColors"/>
 
         <activity
+            android:name="androidx.appcompat.widget.AppCompatTextViewFontScalingTest$TextViewFontScalingActivity"
+            android:label="@string/app_compat_text_view_activity"
+            android:theme="@style/Theme.TextColors" />
+
+        <activity
             android:name="androidx.appcompat.widget.AppCompatTextViewAutoSizeActivity"
             android:label="@string/app_compat_text_view_auto_size_activity"
             android:theme="@style/Theme.AppCompat.Light"/>
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewFontScalingTest.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewFontScalingTest.kt
new file mode 100644
index 0000000..a87d598
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewFontScalingTest.kt
@@ -0,0 +1,197 @@
+/*
+ * 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.appcompat.widget
+
+import android.app.Activity
+import android.os.Build
+import android.os.Bundle
+import android.util.TypedValue
+import android.widget.TextView
+import androidx.appcompat.test.R
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.testutils.AndroidFontScaleHelper.resetSystemFontScale
+import androidx.testutils.AndroidFontScaleHelper.setSystemFontScale
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test {@link AppCompatTextView} under non-linear font scaling.
+ */
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class AppCompatTextViewFontScalingTest {
+    @get:Rule
+    val scenarioRule = ActivityScenarioRule(TextViewFontScalingActivity::class.java)
+
+    @After
+    fun teardown() {
+        // Have to manually check the version here because if we try to rely on the assumeTrue() in
+        // resetSystemFontScale(), it is called twice (again in setSystemFontScale()) and the test
+        // fails with a "TestCouldNotBeSkippedException: Test could not be skipped due to other
+        // failures" because it thinks the second assumeTrue() was a separate error.
+        // tl;dr avoids a bug in jUnit when multiple assumeTrue()s happen in @Test and @After
+        if (Build.VERSION.SDK_INT >= 29) {
+            resetSystemFontScale(scenarioRule.scenario)
+        }
+    }
+
+    @Test
+    @Throws(Throwable::class)
+    fun testNonLinearFontScaling_testSetLineHeightSpAndSetTextSizeSp() {
+        setSystemFontScale(2f, scenarioRule.scenario)
+        scenarioRule.scenario.onActivity { activity ->
+            assertThat(activity.resources.configuration.fontScale).isWithin(0.02f).of(2f)
+
+            val textView = AppCompatTextView(activity)
+            val textSizeSp = 20f
+            val lineHeightSp = 40f
+
+            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSp)
+            textView.setLineHeight(TypedValue.COMPLEX_UNIT_SP, lineHeightSp)
+
+            verifyLineHeightIsIntendedProportions(lineHeightSp, textSizeSp, activity, textView)
+        }
+    }
+
+    @Test
+    @Throws(Throwable::class)
+    fun testNonLinearFontScaling_overwriteXml_testSetLineHeightSpAndSetTextSizeSp() {
+        setSystemFontScale(2f, scenarioRule.scenario)
+        scenarioRule.scenario.onActivity { activity ->
+            assertThat(activity.resources.configuration.fontScale).isWithin(0.02f).of(2f)
+
+            val textView = findTextView(activity, R.id.textview_lineheight2x)
+            val textSizeSp = 20f
+            val lineHeightSp = 40f
+
+            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSp)
+            textView.setLineHeight(TypedValue.COMPLEX_UNIT_SP, lineHeightSp)
+
+            verifyLineHeightIsIntendedProportions(lineHeightSp, textSizeSp, activity, textView)
+        }
+    }
+
+    @Test
+    @Throws(Throwable::class)
+    fun testNonLinearFontScaling_xml_testLineHeightAttrSpAndTextSizeAttrSp() {
+        setSystemFontScale(2f, scenarioRule.scenario)
+        scenarioRule.scenario.onActivity { activity ->
+            assertThat(activity.resources.configuration.fontScale).isWithin(0.02f).of(2f)
+
+            val textView = findTextView(activity, R.id.textview_lineheight2x)
+            val textSizeSp = 20f
+            val lineHeightSp = 40f
+
+            verifyLineHeightIsIntendedProportions(lineHeightSp, textSizeSp, activity, textView)
+        }
+    }
+
+    @Test
+    @Throws(Throwable::class)
+    fun testNonLinearFontScaling_dimenXml_testLineHeightAttrSpAndTextSizeAttrSp() {
+        setSystemFontScale(2f, scenarioRule.scenario)
+        scenarioRule.scenario.onActivity { activity ->
+            assertThat(activity.resources.configuration.fontScale).isWithin(0.02f).of(2f)
+
+            val textView = findTextView(activity, R.id.textview_lineheight_dimen3x)
+            val textSizeSp = 20f
+            val lineHeightSp = 60f
+
+            verifyLineHeightIsIntendedProportions(lineHeightSp, textSizeSp, activity, textView)
+        }
+    }
+
+    @Test
+    @Throws(Throwable::class)
+    fun testNonLinearFontScaling_styleXml_testLineHeightAttrSpAndTextSizeAttrSp() {
+        setSystemFontScale(2f, scenarioRule.scenario)
+        scenarioRule.scenario.onActivity { activity ->
+            assertThat(activity.resources.configuration.fontScale).isWithin(0.02f).of(2f)
+
+            val textView = findTextView(activity, R.id.textview_lineheight_style3x)
+            val textSizeSp = 20f
+            val lineHeightSp = 60f
+
+            verifyLineHeightIsIntendedProportions(lineHeightSp, textSizeSp, activity, textView)
+        }
+    }
+
+    @Test
+    @Throws(Throwable::class)
+    fun testNonLinearFontScaling_dimenXml_testSetLineHeightSpAndTextSizeAttrSp() {
+        setSystemFontScale(2f, scenarioRule.scenario)
+        scenarioRule.scenario.onActivity { activity ->
+            assertThat(activity.resources.configuration.fontScale).isWithin(0.02f).of(2f)
+
+            val textView = findTextView(activity, R.id.textview_lineheight_dimen3x)
+            val textSizeSp = 20f
+            val lineHeightSp = 30f
+
+            textView.setLineHeight(TypedValue.COMPLEX_UNIT_SP, lineHeightSp)
+
+            verifyLineHeightIsIntendedProportions(lineHeightSp, textSizeSp, activity, textView)
+        }
+    }
+
+    private fun findTextView(activity: Activity, id: Int): AppCompatTextView {
+        return activity.findViewById(id)!!
+    }
+
+    class TextViewFontScalingActivity : Activity() {
+        override fun onCreate(savedInstanceState: Bundle?) {
+            super.onCreate(savedInstanceState)
+            setContentView(R.layout.appcompat_textview_fontscaling_activity)
+        }
+    }
+
+    companion object {
+        /**
+         * Tolerance for comparing expected float lineHeight to the integer one returned by
+         * getLineHeight(). It is pretty lenient to account for integer rounding when text size is
+         * loaded from an attribute. (When loading an SP resource from an attribute for textSize,
+         * it is rounded to the nearest pixel, which can throw off calculations quite a lot. Not
+         * enough to make much of a difference to the user, but enough to need a wide tolerance in
+         * tests. See b/279456702 for more details.)
+         */
+        private const val TOLERANCE = 5f
+
+        private fun verifyLineHeightIsIntendedProportions(
+            lineHeightSp: Float,
+            textSizeSp: Float,
+            activity: Activity,
+            textView: TextView
+        ) {
+            val lineHeightMultiplier = lineHeightSp / textSizeSp
+            // Calculate what line height would be without non-linear font scaling compressing it.
+            // The trick is multiplying afterwards (by the pixel value) instead of before (by the SP
+            // value)
+            val expectedLineHeightPx = lineHeightMultiplier * TypedValue.applyDimension(
+                TypedValue.COMPLEX_UNIT_SP,
+                textSizeSp,
+                activity.resources.displayMetrics
+            )
+            assertThat(textView.lineHeight.toFloat())
+                .isWithin(TOLERANCE)
+                .of(expectedLineHeightPx)
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/res/layout/appcompat_textview_fontscaling_activity.xml b/appcompat/appcompat/src/androidTest/res/layout/appcompat_textview_fontscaling_activity.xml
new file mode 100644
index 0000000..fadabf4
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/res/layout/appcompat_textview_fontscaling_activity.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:id="@+id/layout_textviewtest"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <!-- Tests line height 2x the text size -->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/textview_lineheight2x"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/sample_text_long"
+            android:textSize="20sp"
+            android:lineHeight="40sp" />
+
+        <!-- Tests line height 3x the text size -->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/textview_lineheight_dimen3x"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/sample_text_long"
+            android:textSize="@dimen/textview_fontScaling_textSize"
+            android:lineHeight="@dimen/textview_fontScaling_lineHeight" />
+
+        <!-- Tests line height 3x the text size -->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/textview_lineheight_style3x"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/sample_text_long"
+            style="@style/TextAppearance.FontScaling" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/appcompat/appcompat/src/androidTest/res/values/dimens.xml b/appcompat/appcompat/src/androidTest/res/values/dimens.xml
index d4a8a0e..aed0b5d 100644
--- a/appcompat/appcompat/src/androidTest/res/values/dimens.xml
+++ b/appcompat/appcompat/src/androidTest/res/values/dimens.xml
@@ -27,4 +27,7 @@
     <dimen name="textview_firstBaselineToTopHeight">100dp</dimen>
     <dimen name="textview_lastBaselineToBottomHeight">30dp</dimen>
     <dimen name="textview_lineHeight">60dp</dimen>
+
+    <dimen name="textview_fontScaling_textSize">20sp</dimen>
+    <dimen name="textview_fontScaling_lineHeight">60sp</dimen>
 </resources>
\ No newline at end of file
diff --git a/appcompat/appcompat/src/androidTest/res/values/donottranslate-strings.xml b/appcompat/appcompat/src/androidTest/res/values/donottranslate-strings.xml
index 151400a..7a07538 100644
--- a/appcompat/appcompat/src/androidTest/res/values/donottranslate-strings.xml
+++ b/appcompat/appcompat/src/androidTest/res/values/donottranslate-strings.xml
@@ -71,6 +71,16 @@
     <string name="app_compat_button_auto_size_activity">AppCompat button auto-size</string>
     <string name="sample_text1">Sample text 1</string>
     <string name="sample_text2">Sample text 2</string>
+    <string name="sample_text_long">This is a really long string which exceeds the width of the
+view. New devices have a much larger screen which actually enables long strings to be displayed
+with no fading. I have made this string longer to fix this case. If you are correcting this
+text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer
+string! I think so, so how about double this string, like copy and paste!
+This is a really long string which exceeds the width of the view.
+New devices have a much larger screen which actually enables long strings to be displayed
+with no fading. I have made this string longer to fix this case. If you are correcting this
+text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer
+string! I think so, so how about double this string, like copy and paste!</string>
     <string name="app_compat_image_button_activity">AppCompat image button</string>
     <string name="app_compat_image_view_activity">AppCompat image view</string>
     <string name="app_compat_button_activity">AppCompat button</string>
diff --git a/appcompat/appcompat/src/androidTest/res/values/styles.xml b/appcompat/appcompat/src/androidTest/res/values/styles.xml
index 0b540bf..a076019 100644
--- a/appcompat/appcompat/src/androidTest/res/values/styles.xml
+++ b/appcompat/appcompat/src/androidTest/res/values/styles.xml
@@ -146,4 +146,9 @@
         <item name="android:colorForeground">@color/color_state_list_lilac</item>
     </style>
 
+    <!-- Tests line height 3x the text size -->
+    <style name="TextAppearance.FontScaling">
+        <item name="android:textSize">@dimen/textview_fontScaling_textSize</item>
+        <item name="android:lineHeight">@dimen/textview_fontScaling_lineHeight</item>
+    </style>
 </resources>
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java
index fda4335..4eb3371 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java
@@ -42,6 +42,7 @@
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.R;
 import androidx.core.content.res.ResourcesCompat;
+import androidx.core.util.TypedValueCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.inputmethod.EditorInfoCompat;
 import androidx.core.widget.TextViewCompat;
@@ -326,8 +327,20 @@
                 R.styleable.AppCompatTextView_firstBaselineToTopHeight, -1);
         final int lastBaselineToBottomHeight = a.getDimensionPixelSize(
                 R.styleable.AppCompatTextView_lastBaselineToBottomHeight, -1);
-        final int lineHeight = a.getDimensionPixelSize(
-                R.styleable.AppCompatTextView_lineHeight, -1);
+        float lineHeight = -1;
+        int lineHeightUnit = -1;
+        if (a.hasValue(R.styleable.AppCompatTextView_lineHeight)) {
+            TypedValue peekValue = a.peekValue(R.styleable.AppCompatTextView_lineHeight);
+            if (peekValue != null && peekValue.type == TypedValue.TYPE_DIMENSION) {
+                lineHeightUnit = TypedValueCompat.getUnitFromComplexDimension(peekValue.data);
+                lineHeight = TypedValue.complexToFloat(peekValue.data);
+            } else {
+                lineHeight = a.getDimensionPixelSize(
+                        R.styleable.AppCompatTextView_lineHeight,
+                        -1
+                );
+            }
+        }
 
         a.recycle();
         if (firstBaselineToTopHeight != -1) {
@@ -337,7 +350,11 @@
             TextViewCompat.setLastBaselineToBottomHeight(mView, lastBaselineToBottomHeight);
         }
         if (lineHeight != -1) {
-            TextViewCompat.setLineHeight(mView, lineHeight);
+            if (lineHeightUnit == -1) {
+                TextViewCompat.setLineHeight(mView, (int) lineHeight);
+            } else {
+                TextViewCompat.setLineHeight(mView, lineHeightUnit, lineHeight);
+            }
         }
     }
 
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java
index 1e92e4a..1f0e15a 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextView.java
@@ -37,6 +37,7 @@
 import android.widget.TextView;
 
 import androidx.annotation.DrawableRes;
+import androidx.annotation.FloatRange;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -477,6 +478,15 @@
         TextViewCompat.setLineHeight(this, lineHeight);
     }
 
+    @Override
+    public void setLineHeight(int unit, @FloatRange(from = 0) float lineHeight) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            getSuperCaller().setLineHeight(unit, lineHeight);
+        } else {
+            TextViewCompat.setLineHeight(this, unit, lineHeight);
+        }
+    }
+
     /**
      * See
      * {@link TextViewCompat#setCustomSelectionActionModeCallback(TextView, ActionMode.Callback)}
@@ -789,7 +799,9 @@
     @RequiresApi(api = 26)
     SuperCaller getSuperCaller() {
         if (mSuperCaller == null) {
-            if (Build.VERSION.SDK_INT >= 28) {
+            if (Build.VERSION.SDK_INT >= 34) {
+                mSuperCaller = new SuperCallerApi34();
+            } else if (Build.VERSION.SDK_INT >= 28) {
                 mSuperCaller = new SuperCallerApi28();
             } else if (Build.VERSION.SDK_INT >= 26) {
                 mSuperCaller = new SuperCallerApi26();
@@ -817,6 +829,9 @@
         // api 28
         void setFirstBaselineToTopHeight(@Px int firstBaselineToTopHeight);
         void setLastBaselineToBottomHeight(@Px int lastBaselineToBottomHeight);
+
+        // api 34
+        void setLineHeight(int unit, @FloatRange(from = 0) float lineHeight);
     }
 
     @RequiresApi(api = 26)
@@ -878,6 +893,9 @@
 
         @Override
         public void setLastBaselineToBottomHeight(int lastBaselineToBottomHeight) {}
+
+        @Override
+        public void setLineHeight(int unit, float lineHeight) {}
     }
 
     @RequiresApi(api = 28)
@@ -893,4 +911,12 @@
             AppCompatTextView.super.setLastBaselineToBottomHeight(lastBaselineToBottomHeight);
         }
     }
+
+    @RequiresApi(api = 34)
+    class SuperCallerApi34 extends SuperCallerApi28 {
+        @Override
+        public void setLineHeight(int unit, float lineHeight) {
+            AppCompatTextView.super.setLineHeight(unit, lineHeight);
+        }
+    }
 }
diff --git a/buildSrc-tests/src/test/java/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt b/buildSrc-tests/src/test/java/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt
index f53eb4f..e4d7736 100644
--- a/buildSrc-tests/src/test/java/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt
+++ b/buildSrc-tests/src/test/java/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt
@@ -39,7 +39,7 @@
     fun init() {
         builder = ConfigBuilder()
         builder.configName("placeHolderAndroidTest.xml")
-            .isBenchmark(false)
+            .isMicrobenchmark(false)
             .applicationId("com.androidx.placeholder.Placeholder")
             .isPostsubmit(true)
             .minSdk("15")
@@ -59,7 +59,7 @@
 
     @Test
     fun testXmlAgainstGoldenDefaultBenchmark() {
-        builder.isBenchmark(true)
+        builder.isMicrobenchmark(true)
         MatcherAssert.assertThat(
             builder.buildXml(),
             CoreMatchers.`is`(goldenDefaultConfigBenchmark)
@@ -123,7 +123,7 @@
 
     @Test
     fun testJsonAgainstGoldenPresubmitBenchmark() {
-        builder.isBenchmark(true)
+        builder.isMicrobenchmark(true)
             .isPostsubmit(false)
         MatcherAssert.assertThat(
             builder.buildJson(),
@@ -241,7 +241,7 @@
 
     @Test
     fun testValidTestConfigXml_benchmarkTrue() {
-        builder.isBenchmark(true)
+        builder.isMicrobenchmark(true)
         validate(builder.buildXml())
     }
 
@@ -279,7 +279,7 @@
     @Test
     fun testValidTestConfigXml_presubmitBenchmark() {
         builder.isPostsubmit(false)
-            .isBenchmark(true)
+            .isMicrobenchmark(true)
         validate(builder.buildXml())
     }
 
@@ -349,7 +349,6 @@
     <option name="config-descriptor:metadata" key="applicationId" value="com.androidx.placeholder.Placeholder" />
     <option name="wifi:disable" value="true" />
     <option name="instrumentation-arg" key="notAnnotation" value="androidx.test.filters.FlakyTest" />
-    <option name="instrumentation-arg" key="androidx.benchmark.output.enable" value="true" />
     <option name="instrumentation-arg" key="listener" value="androidx.benchmark.junit4.InstrumentationResultsRunListener" />
     <include name="google/unbundled/common/setup" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index 5ba35b8..2c51b04 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -162,6 +162,7 @@
                 project.validatePublishedMultiplatformHasDefault()
             }
         }
+        project.disallowAccidentalAndroidDependenciesInKmpProject(kmpExtension)
     }
 
     private fun Project.registerProjectOrArtifact() {
@@ -1214,6 +1215,31 @@
     }
 }
 
+/**
+ * Verifies we don't accidentially write "implementation" instead of "commonMainImplementation"
+ */
+fun Project.disallowAccidentalAndroidDependenciesInKmpProject(
+    kmpExtension: AndroidXMultiplatformExtension
+) {
+    project.afterEvaluate {
+        if (kmpExtension.supportedPlatforms.isNotEmpty()) {
+            val androidConfiguration = project.configurations.findByName("implementation")
+            if (androidConfiguration != null) {
+               if (
+                   androidConfiguration.dependencies.isNotEmpty() ||
+                   androidConfiguration.dependencyConstraints.isNotEmpty()
+               ) {
+                   throw GradleException(
+                       "The 'implementation' Configuration should not be used in a " +
+                       "multiplatform project: this Configuration is declared by the " +
+                       "Android plugin rather than the kmp plugin. Did you mean " +
+                       "'commonMainImplementation'?")
+                }
+            }
+        }
+    }
+}
+
 /** Verifies that ProjectParser computes the correct values for this project */
 fun Project.validateProjectParser(extension: AndroidXExtension) {
     // If configuration fails, we don't want to validate the ProjectParser
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
index 86d3217..a3fd34e 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
@@ -50,16 +50,14 @@
     private val kotlinExtension: KotlinMultiplatformExtension by kotlinExtensionDelegate
 
     /**
-     * The list of platforms that have been requested in the build configuration.
+     * The list of platforms that have been declared as supported in the build configuration.
      *
-     * The list of enabled platforms in [targetPlatforms] will vary based on the build environment.
-     * For example, a project's build configuration may have requested `mac()` but this is not
-     * available when building on Linux.
+     * This may be a superset of the currently enabled platforms in [targetPlatforms].
      */
-    val requestedPlatforms: MutableSet<PlatformIdentifier> = mutableSetOf()
+    val supportedPlatforms: MutableSet<PlatformIdentifier> = mutableSetOf()
 
     /**
-     * The list of platforms that are enabled.
+     * The list of platforms that are currently enabled.
      *
      * This will vary across build environments. For example, a project's build configuration may
      * have requested `mac()` but this is not available when building on Linux.
@@ -91,14 +89,14 @@
      * identifier for that platform.
      */
     var defaultPlatform: String? = null
-        get() = field ?: requestedPlatforms.singleOrNull()?.id
+        get() = field ?: supportedPlatforms.singleOrNull()?.id
         set(value) {
             if (value != null) {
-                if (requestedPlatforms.none { it.id == value }) {
+                if (supportedPlatforms.none { it.id == value }) {
                     throw GradleException(
                         "Platform $value has not been requested as a target. " +
                             "Available platforms are: " +
-                            requestedPlatforms.joinToString(", ") { it.id }
+                            supportedPlatforms.joinToString(", ") { it.id }
                     )
                 }
                 if (targetPlatforms.none { it == value }) {
@@ -145,7 +143,7 @@
 
     @JvmOverloads
     fun jvm(block: Action<KotlinJvmTarget>? = null): KotlinJvmTarget? {
-        requestedPlatforms.add(PlatformIdentifier.JVM)
+        supportedPlatforms.add(PlatformIdentifier.JVM)
         return if (project.enableJvm()) {
             kotlinExtension.jvm {
                 block?.execute(this)
@@ -163,7 +161,7 @@
 
     @JvmOverloads
     fun android(block: Action<KotlinAndroidTarget>? = null): KotlinAndroidTarget? {
-        requestedPlatforms.add(PlatformIdentifier.ANDROID)
+        supportedPlatforms.add(PlatformIdentifier.ANDROID)
         return if (project.enableJvm()) {
             kotlinExtension.androidTarget { block?.execute(this) }
         } else {
@@ -173,7 +171,7 @@
 
     @JvmOverloads
     fun desktop(block: Action<KotlinJvmTarget>? = null): KotlinJvmTarget? {
-        requestedPlatforms.add(PlatformIdentifier.DESKTOP)
+        supportedPlatforms.add(PlatformIdentifier.DESKTOP)
         return if (project.enableDesktop()) {
             kotlinExtension.jvm("desktop") { block?.execute(this) }
         } else {
@@ -189,7 +187,7 @@
 
     @JvmOverloads
     fun macosX64(block: Action<KotlinNativeTarget>? = null): KotlinNativeTargetWithHostTests? {
-        requestedPlatforms.add(PlatformIdentifier.MAC_OSX_64)
+        supportedPlatforms.add(PlatformIdentifier.MAC_OSX_64)
         return if (project.enableMac()) {
             kotlinExtension.macosX64().also { block?.execute(it) }
         } else {
@@ -199,7 +197,7 @@
 
     @JvmOverloads
     fun macosArm64(block: Action<KotlinNativeTarget>? = null): KotlinNativeTargetWithHostTests? {
-        requestedPlatforms.add(PlatformIdentifier.MAC_ARM_64)
+        supportedPlatforms.add(PlatformIdentifier.MAC_ARM_64)
         return if (project.enableMac()) {
             kotlinExtension.macosArm64().also { block?.execute(it) }
         } else {
@@ -209,7 +207,7 @@
 
     @JvmOverloads
     fun iosArm64(block: Action<KotlinNativeTarget>? = null): KotlinNativeTarget? {
-        requestedPlatforms.add(PlatformIdentifier.IOS_ARM_64)
+        supportedPlatforms.add(PlatformIdentifier.IOS_ARM_64)
         return if (project.enableMac()) {
             kotlinExtension.iosArm64().also { block?.execute(it) }
         } else {
@@ -225,7 +223,7 @@
 
     @JvmOverloads
     fun iosX64(block: Action<KotlinNativeTarget>? = null): KotlinNativeTarget? {
-        requestedPlatforms.add(PlatformIdentifier.IOS_X_64)
+        supportedPlatforms.add(PlatformIdentifier.IOS_X_64)
         return if (project.enableMac()) {
             kotlinExtension.iosX64().also { block?.execute(it) }
         } else {
@@ -235,7 +233,7 @@
 
     @JvmOverloads
     fun iosSimulatorArm64(block: Action<KotlinNativeTarget>? = null): KotlinNativeTarget? {
-        requestedPlatforms.add(PlatformIdentifier.IOS_SIMULATOR_ARM_64)
+        supportedPlatforms.add(PlatformIdentifier.IOS_SIMULATOR_ARM_64)
         return if (project.enableMac()) {
             kotlinExtension.iosSimulatorArm64().also { block?.execute(it) }
         } else {
@@ -252,7 +250,7 @@
 
     @JvmOverloads
     fun linuxX64(block: Action<KotlinNativeTarget>? = null): KotlinNativeTargetWithHostTests? {
-        requestedPlatforms.add(PlatformIdentifier.LINUX_64)
+        supportedPlatforms.add(PlatformIdentifier.LINUX_64)
         return if (project.enableLinux()) {
             kotlinExtension.linuxX64().also { block?.execute(it) }
         } else {
@@ -262,7 +260,7 @@
 
     @JvmOverloads
     fun js(block: Action<KotlinJsTargetDsl>? = null): KotlinJsTargetDsl? {
-        requestedPlatforms.add(PlatformIdentifier.JS)
+        supportedPlatforms.add(PlatformIdentifier.JS)
         return if (project.enableJs()) {
             kotlinExtension.js().also { block?.execute(it) }
         } else {
@@ -286,7 +284,7 @@
 
 fun Project.validatePublishedMultiplatformHasDefault() {
     val extension = project.extensions.getByType(AndroidXMultiplatformExtension::class.java)
-    if (extension.defaultPlatform == null && extension.requestedPlatforms.isNotEmpty()) {
+    if (extension.defaultPlatform == null && extension.supportedPlatforms.isNotEmpty()) {
         throw GradleException(
             "Project is published and multiple platforms are requested. You " +
                 "must explicitly specify androidXMultiplatform.defaultPlatform as one of: " +
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
index 9265e5c..724504f 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
@@ -566,10 +566,6 @@
                     ":media2:media2-session:version-compat-tests:service",
                     ":media2:media2-session:version-compat-tests:client-previous",
                     ":media2:media2-session:version-compat-tests:service-previous"
-                ), // Link graphics and material to always run @Large in presubmit per b/160624022
-                setOf(
-                    ":compose:ui:ui-graphics",
-                    ":compose:material:material"
                 ), // Link material and material-ripple
                 setOf(":compose:material:material-ripple", ":compose:material:material"),
                 setOf(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/AndroidTestConfigBuilder.kt b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/AndroidTestConfigBuilder.kt
index a3c6691..657f702 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/AndroidTestConfigBuilder.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/AndroidTestConfigBuilder.kt
@@ -23,7 +23,7 @@
     var appApkName: String? = null
     var appApkSha256: String? = null
     lateinit var applicationId: String
-    var isBenchmark: Boolean = false
+    var isMicrobenchmark: Boolean = false
     var isPostsubmit: Boolean = true
     lateinit var minSdk: String
     val tags = mutableListOf<String>()
@@ -40,7 +40,8 @@
 
     fun applicationId(applicationId: String) = apply { this.applicationId = applicationId }
 
-    fun isBenchmark(isBenchmark: Boolean) = apply { this.isBenchmark = isBenchmark }
+    fun isMicrobenchmark(isMicrobenchmark: Boolean) =
+        apply { this.isMicrobenchmark = isMicrobenchmark }
 
     fun isPostsubmit(isPostsubmit: Boolean) = apply { this.isPostsubmit = isPostsubmit }
 
@@ -59,7 +60,7 @@
     fun buildJson(): String {
         val gson = GsonBuilder().setPrettyPrinting().create()
         val instrumentationArgs =
-            if (isBenchmark && !isPostsubmit) {
+            if (isMicrobenchmark && !isPostsubmit) {
                 listOf(
                     InstrumentationArg("notAnnotation", "androidx.test.filters.FlakyTest"),
                     InstrumentationArg("androidx.benchmark.dryRunMode.enable", "true"),
@@ -91,11 +92,11 @@
         sb.append(MODULE_METADATA_TAG_OPTION.replace("APPLICATION_ID", applicationId))
             .append(WIFI_DISABLE_OPTION)
             .append(FLAKY_TEST_OPTION)
-        if (isBenchmark) {
+        if (isMicrobenchmark) {
             if (isPostsubmit) {
-                sb.append(BENCHMARK_POSTSUBMIT_OPTIONS)
+                sb.append(MICROBENCHMARK_POSTSUBMIT_OPTIONS)
             } else {
-                sb.append(BENCHMARK_PRESUBMIT_OPTION)
+                sb.append(MICROBENCHMARK_PRESUBMIT_OPTION)
             }
         }
         sb.append(SETUP_INCLUDE)
@@ -105,7 +106,7 @@
             sb.append(APK_INSTALL_OPTION.replace("APK_NAME", appApkName!!))
         sb.append(TARGET_PREPARER_CLOSE)
         // Post install commands after SuiteApkInstaller is declared
-        if (isBenchmark) {
+        if (isMicrobenchmark) {
             sb.append(benchmarkPostInstallCommandOption(applicationId))
         }
         sb.append(TEST_BLOCK_OPEN)
@@ -312,16 +313,15 @@
 """
         .trimIndent()
 
-private val BENCHMARK_PRESUBMIT_OPTION =
+private val MICROBENCHMARK_PRESUBMIT_OPTION =
     """
     <option name="instrumentation-arg" key="androidx.benchmark.dryRunMode.enable" value="true" />
 
 """
         .trimIndent()
 
-private val BENCHMARK_POSTSUBMIT_OPTIONS =
+private val MICROBENCHMARK_POSTSUBMIT_OPTIONS =
     """
-    <option name="instrumentation-arg" key="androidx.benchmark.output.enable" value="true" />
     <option name="instrumentation-arg" key="listener" value="androidx.benchmark.junit4.InstrumentationResultsRunListener" />
 
 """
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt
index 87b7114..d428c0f 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt
@@ -134,10 +134,14 @@
         configBuilder.isPostsubmit(!isPresubmit)
         // This section adds metadata tags that will help filter runners to specific modules.
         if (hasBenchmarkPlugin.get()) {
-            configBuilder.isBenchmark(true)
-            if (configBuilder.isPostsubmit) {
-                configBuilder.tag("microbenchmarks")
-            } else {
+            configBuilder.isMicrobenchmark(true)
+
+            // tag microbenchmarks as "microbenchmarks" in either build config, so that benchmark
+            // test configs will always have something to run, regardless of build (though presubmit
+            // builds will still set dry run, and not output metrics)
+            configBuilder.tag("microbenchmarks")
+
+            if (isPresubmit) {
                 // in presubmit, we treat micro benchmarks as regular correctness tests as
                 // they run with dryRunMode to check crashes don't happen, without measurement
                 configBuilder.tag("androidx_unit_tests")
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapter.kt
index 273d30d..c8276d6 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapter.kt
@@ -17,6 +17,7 @@
 package androidx.camera.camera2.pipe.integration.adapter
 
 import androidx.annotation.RequiresApi
+import androidx.annotation.VisibleForTesting
 import androidx.camera.camera2.pipe.CameraDevices
 import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.integration.internal.CameraGraphCreator
@@ -25,6 +26,7 @@
 import androidx.camera.core.CameraInfo
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.concurrent.CameraCoordinator
+import androidx.camera.core.concurrent.CameraCoordinator.CAMERA_OPERATING_MODE_UNSPECIFIED
 import androidx.camera.core.concurrent.CameraCoordinator.CameraOperatingMode
 import androidx.camera.core.impl.CameraInternal
 
@@ -33,17 +35,15 @@
     cameraDevices: CameraDevices,
     private val cameraGraphCreator: CameraGraphCreator
 ) : CameraCoordinator {
-    private val cameraInternalMap = mutableMapOf<CameraId, CameraInternalAdapter>()
-
-    private var concurrentCameraIdsSet: Set<Set<CameraId>> = mutableSetOf()
-    private var concurrentCameraIdMap: MutableMap<String, MutableList<String>> = mutableMapOf()
-    private var activeConcurrentCameraInfosList: MutableList<CameraInfo> = mutableListOf()
-
-    private var concurrentMode: Int = CameraCoordinator.CAMERA_OPERATING_MODE_UNSPECIFIED
-    private var concurrentModeOn = false
+    @VisibleForTesting val cameraInternalMap = mutableMapOf<CameraId, CameraInternalAdapter>()
+    @VisibleForTesting var concurrentCameraIdsSet = mutableSetOf<Set<CameraId>>()
+    @VisibleForTesting var concurrentCameraIdMap = mutableMapOf<String, MutableList<String>>()
+    @VisibleForTesting var activeConcurrentCameraInfosList = mutableListOf<CameraInfo>()
+    @VisibleForTesting var concurrentMode: Int = CAMERA_OPERATING_MODE_UNSPECIFIED
+    @VisibleForTesting var concurrentModeOn = false
 
     init {
-        concurrentCameraIdsSet = cameraDevices.awaitConcurrentCameraIds()!!
+        concurrentCameraIdsSet = cameraDevices.awaitConcurrentCameraIds()!!.toMutableSet()
         for (cameraIdSet in concurrentCameraIdsSet) {
             val cameraIdsList = cameraIdSet.toList()
             if (cameraIdsList.size >= 2) {
@@ -129,4 +129,13 @@
 
     override fun removeListener(listener: CameraCoordinator.ConcurrentCameraModeListener) {
     }
+
+    override fun shutdown() {
+        cameraInternalMap.clear()
+        concurrentCameraIdsSet.clear()
+        concurrentCameraIdMap.clear()
+        activeConcurrentCameraInfosList.clear()
+        concurrentMode = CAMERA_OPERATING_MODE_UNSPECIFIED
+        concurrentModeOn = false
+    }
 }
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapterTest.kt
index 1222685..12c69f8 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapterTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraCoordinatorAdapterTest.kt
@@ -25,6 +25,7 @@
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
 import androidx.camera.core.concurrent.CameraCoordinator.CAMERA_OPERATING_MODE_CONCURRENT
 import androidx.camera.core.concurrent.CameraCoordinator.CAMERA_OPERATING_MODE_SINGLE
+import androidx.camera.core.concurrent.CameraCoordinator.CAMERA_OPERATING_MODE_UNSPECIFIED
 import androidx.camera.core.impl.CameraInfoInternal
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
@@ -123,4 +124,22 @@
         assertThat(cameraCoordinatorAdapter.cameraOperatingMode)
             .isEqualTo(CAMERA_OPERATING_MODE_SINGLE)
     }
+
+    @Test
+    fun shutdown() {
+        cameraCoordinatorAdapter.cameraOperatingMode = CAMERA_OPERATING_MODE_CONCURRENT
+        cameraCoordinatorAdapter.activeConcurrentCameraInfos = mutableListOf(
+            FakeCameraInfoAdapterCreator.createCameraInfoAdapter(cameraId = CameraId("0")),
+            FakeCameraInfoAdapterCreator.createCameraInfoAdapter(cameraId = CameraId("1")))
+
+        cameraCoordinatorAdapter.shutdown()
+
+        assertThat(cameraCoordinatorAdapter.cameraInternalMap).isEmpty()
+        assertThat(cameraCoordinatorAdapter.activeConcurrentCameraInfos).isEmpty()
+        assertThat(cameraCoordinatorAdapter.concurrentCameraIdMap).isEmpty()
+        assertThat(cameraCoordinatorAdapter.concurrentCameraIdsSet).isEmpty()
+        assertThat(cameraCoordinatorAdapter.cameraOperatingMode).isEqualTo(
+            CAMERA_OPERATING_MODE_UNSPECIFIED)
+        assertThat(cameraCoordinatorAdapter.concurrentModeOn).isFalse()
+    }
 }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinator.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinator.java
index 93e24c7..e6680bf 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinator.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinator.java
@@ -140,6 +140,15 @@
         mConcurrentCameraModeListeners.remove(listener);
     }
 
+    @Override
+    public void shutdown() {
+        mConcurrentCameraModeListeners.clear();
+        mConcurrentCameraIdMap.clear();
+        mActiveConcurrentCameraInfos.clear();
+        mConcurrentCameraIds.clear();
+        mCameraOperatingMode = CAMERA_OPERATING_MODE_UNSPECIFIED;
+    }
+
     private void retrieveConcurrentCameraIds() {
         try {
             mConcurrentCameraIds = mCameraManager.getConcurrentCameraIds();
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
index 6b7de32..fa3f220 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
@@ -57,8 +57,6 @@
 )
 class Camera2CameraCoordinatorTest {
 
-    private val mContext = ApplicationProvider.getApplicationContext<Context>()
-
     private lateinit var cameraCoordinator: CameraCoordinator
 
     @Before
@@ -109,26 +107,7 @@
 
     @Test
     fun getPairedCameraId() {
-        val characteristics0 = ShadowCameraCharacteristics.newCameraCharacteristics()
-        (Shadow.extract<Any>(
-            ApplicationProvider.getApplicationContext<Context>()
-                .getSystemService(Context.CAMERA_SERVICE)
-        ) as ShadowCameraManager)
-            .addCamera("0", characteristics0)
-        val characteristics1 = ShadowCameraCharacteristics.newCameraCharacteristics()
-        (Shadow.extract<Any>(
-            ApplicationProvider.getApplicationContext<Context>()
-                .getSystemService(Context.CAMERA_SERVICE)
-        ) as ShadowCameraManager)
-            .addCamera("1", characteristics1)
-
-        val mCameraManagerCompat =
-            CameraManagerCompat.from((ApplicationProvider.getApplicationContext() as Context))
-
-        cameraCoordinator.activeConcurrentCameraInfos = listOf(
-            Camera2CameraInfoImpl("0", mCameraManagerCompat),
-            Camera2CameraInfoImpl("1", mCameraManagerCompat)
-        )
+        cameraCoordinator.activeConcurrentCameraInfos = createConcurrentCameraInfos()
 
         assertThat(cameraCoordinator.getPairedConcurrentCameraId("0")).isEqualTo("1")
         assertThat(cameraCoordinator.getPairedConcurrentCameraId("1")).isEqualTo("0")
@@ -164,6 +143,41 @@
             anyInt(), anyInt())
     }
 
+    @Test
+    fun shutdown() {
+        cameraCoordinator.cameraOperatingMode = CAMERA_OPERATING_MODE_CONCURRENT
+        cameraCoordinator.activeConcurrentCameraInfos = createConcurrentCameraInfos()
+
+        cameraCoordinator.shutdown()
+
+        assertThat(cameraCoordinator.concurrentCameraSelectors).isEmpty()
+        assertThat(cameraCoordinator.activeConcurrentCameraInfos).isEmpty()
+        assertThat(cameraCoordinator.cameraOperatingMode).isEqualTo(
+            CAMERA_OPERATING_MODE_UNSPECIFIED)
+    }
+
+    private fun createConcurrentCameraInfos(): List<Camera2CameraInfoImpl> {
+        val characteristics0 = ShadowCameraCharacteristics.newCameraCharacteristics()
+        (Shadow.extract<Any>(
+            ApplicationProvider.getApplicationContext<Context>()
+                .getSystemService(Context.CAMERA_SERVICE)
+        ) as ShadowCameraManager)
+            .addCamera("0", characteristics0)
+        val characteristics1 = ShadowCameraCharacteristics.newCameraCharacteristics()
+        (Shadow.extract<Any>(
+            ApplicationProvider.getApplicationContext<Context>()
+                .getSystemService(Context.CAMERA_SERVICE)
+        ) as ShadowCameraManager)
+            .addCamera("1", characteristics1)
+        val cameraManagerCompat =
+            CameraManagerCompat.from((ApplicationProvider.getApplicationContext() as Context))
+
+        return listOf(
+            Camera2CameraInfoImpl("0", cameraManagerCompat),
+            Camera2CameraInfoImpl("1", cameraManagerCompat)
+        )
+    }
+
     private class FakeCameraManagerImpl : CameraManagerCompat.CameraManagerCompatImpl {
 
         private val mCameraManagerImpl = CameraManagerCompat.CameraManagerCompatImpl.from(
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/concurrent/CameraCoordinator.java b/camera/camera-core/src/main/java/androidx/camera/core/concurrent/CameraCoordinator.java
index 60d6be3..b98d11e 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/concurrent/CameraCoordinator.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/concurrent/CameraCoordinator.java
@@ -130,6 +130,11 @@
     void removeListener(@NonNull ConcurrentCameraModeListener listener);
 
     /**
+     * Clean up all the resources when CameraX shutdown.
+     */
+    void shutdown();
+
+    /**
      * Interface for concurrent camera mode update.
      *
      * <p>Everytime user changes {@link CameraOperatingMode}, the observer will be notified and
diff --git a/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt b/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
index f585001..7dbc5c3 100644
--- a/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
+++ b/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
@@ -30,6 +30,7 @@
 import androidx.camera.core.ConcurrentCamera.SingleCameraConfig
 import androidx.camera.core.Preview
 import androidx.camera.core.UseCaseGroup
+import androidx.camera.core.concurrent.CameraCoordinator.CAMERA_OPERATING_MODE_UNSPECIFIED
 import androidx.camera.core.impl.CameraFactory
 import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
 import androidx.camera.testing.fakes.FakeAppConfig
@@ -63,6 +64,7 @@
     private val context = ApplicationProvider.getApplicationContext() as Context
     private val lifecycleOwner0 = FakeLifecycleOwner()
     private val lifecycleOwner1 = FakeLifecycleOwner()
+    private val cameraCoordinator = FakeCameraCoordinator()
 
     private lateinit var provider: ProcessCameraProvider
 
@@ -665,6 +667,10 @@
 
         // Should not throw exception
         ProcessCameraProvider.configureInstance(FakeAppConfig.create())
+        assertThat(cameraCoordinator.cameraOperatingMode).isEqualTo(
+            CAMERA_OPERATING_MODE_UNSPECIFIED)
+        assertThat(cameraCoordinator.concurrentCameraSelectors).isEmpty()
+        assertThat(cameraCoordinator.activeConcurrentCameraInfos).isEmpty()
     }
 
     @Test
@@ -841,7 +847,6 @@
     }
 
     private fun createConcurrentCameraAppConfig(): CameraXConfig {
-        val cameraCoordinator = FakeCameraCoordinator()
         val combination0 = mapOf(
             "0" to CameraSelector.Builder().requireLensFacing(LENS_FACING_BACK).build(),
             "1" to CameraSelector.Builder().requireLensFacing(LENS_FACING_FRONT).build())
diff --git a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
index d675fb8..f6e56cd 100644
--- a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
+++ b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
@@ -291,6 +291,10 @@
             mLifecycleCameraRepository.clear();
         });
 
+        if (mCameraX != null) {
+            mCameraX.getCameraFactory().getCameraCoordinator().shutdown();
+        }
+
         ListenableFuture<Void> shutdownFuture = mCameraX != null ? mCameraX.shutdown() :
                 Futures.immediateFuture(null);
 
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraCoordinator.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraCoordinator.java
index 3281ec1..1dc5b00 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraCoordinator.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraCoordinator.java
@@ -125,4 +125,13 @@
     public void removeListener(@NonNull ConcurrentCameraModeListener listener) {
         mConcurrentCameraModeListeners.remove(listener);
     }
+
+    @Override
+    public void shutdown() {
+        mConcurrentCameraIdMap.clear();
+        mConcurrentCameraIds.clear();
+        mConcurrentCameraSelectors.clear();
+        mActiveConcurrentCameraInfos.clear();
+        mConcurrentCameraModeListeners.clear();
+    }
 }
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index 5c2d5cb..67d58c8e 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -900,6 +900,7 @@
   }
 
   @SuppressCompatibility @androidx.car.app.annotations.CarProtocol @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(7) public class ConversationItem implements androidx.car.app.model.Item {
+    method public java.util.List<androidx.car.app.model.Action!> getActions();
     method public androidx.car.app.messaging.model.ConversationCallbackDelegate getConversationCallbackDelegate();
     method public androidx.car.app.model.CarIcon? getIcon();
     method public String getId();
@@ -912,6 +913,7 @@
   public static final class ConversationItem.Builder {
     ctor public ConversationItem.Builder();
     ctor public ConversationItem.Builder(androidx.car.app.messaging.model.ConversationItem);
+    method public androidx.car.app.messaging.model.ConversationItem.Builder addAction(androidx.car.app.model.Action);
     method public androidx.car.app.messaging.model.ConversationItem build();
     method public androidx.car.app.messaging.model.ConversationItem.Builder setConversationCallback(androidx.car.app.messaging.model.ConversationCallback);
     method public androidx.car.app.messaging.model.ConversationItem.Builder setGroupConversation(boolean);
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index 5c2d5cb..67d58c8e 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -900,6 +900,7 @@
   }
 
   @SuppressCompatibility @androidx.car.app.annotations.CarProtocol @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(7) public class ConversationItem implements androidx.car.app.model.Item {
+    method public java.util.List<androidx.car.app.model.Action!> getActions();
     method public androidx.car.app.messaging.model.ConversationCallbackDelegate getConversationCallbackDelegate();
     method public androidx.car.app.model.CarIcon? getIcon();
     method public String getId();
@@ -912,6 +913,7 @@
   public static final class ConversationItem.Builder {
     ctor public ConversationItem.Builder();
     ctor public ConversationItem.Builder(androidx.car.app.messaging.model.ConversationItem);
+    method public androidx.car.app.messaging.model.ConversationItem.Builder addAction(androidx.car.app.model.Action);
     method public androidx.car.app.messaging.model.ConversationItem build();
     method public androidx.car.app.messaging.model.ConversationItem.Builder setConversationCallback(androidx.car.app.messaging.model.ConversationCallback);
     method public androidx.car.app.messaging.model.ConversationItem.Builder setGroupConversation(boolean);
diff --git a/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java b/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
index d83d5b0..1acc0f4 100644
--- a/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
+++ b/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
@@ -29,13 +29,16 @@
 import androidx.car.app.annotations.ExperimentalCarApi;
 import androidx.car.app.annotations.KeepFields;
 import androidx.car.app.annotations.RequiresCarApi;
+import androidx.car.app.model.Action;
 import androidx.car.app.model.CarIcon;
 import androidx.car.app.model.CarText;
 import androidx.car.app.model.Item;
+import androidx.car.app.model.constraints.ActionsConstraints;
 import androidx.car.app.utils.CollectionUtils;
 import androidx.core.app.Person;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
@@ -58,6 +61,8 @@
     private final List<CarMessage> mMessages;
     @NonNull
     private final ConversationCallbackDelegate mConversationCallbackDelegate;
+    @NonNull
+    private final List<Action> mActions;
 
     @Override
     public int hashCode() {
@@ -67,7 +72,8 @@
                 mTitle,
                 mIcon,
                 mIsGroupConversation,
-                mMessages
+                mMessages,
+                mActions
         );
     }
 
@@ -89,6 +95,7 @@
                         .arePersonsEqual(getSelf(), otherConversationItem.getSelf())
                         && mIsGroupConversation == otherConversationItem.mIsGroupConversation
                         && Objects.equals(mMessages, otherConversationItem.mMessages)
+                        && Objects.equals(mActions, otherConversationItem.mActions)
                 ;
     }
 
@@ -101,6 +108,7 @@
         this.mMessages = requireNonNull(CollectionUtils.unmodifiableCopy(builder.mMessages));
         checkState(!mMessages.isEmpty(), "Message list cannot be empty.");
         this.mConversationCallbackDelegate = requireNonNull(builder.mConversationCallbackDelegate);
+        this.mActions = CollectionUtils.unmodifiableCopy(builder.mActions);
     }
 
     /** Default constructor for serialization. */
@@ -123,6 +131,7 @@
                         // Do nothing
                     }
                 });
+        mActions = Collections.emptyList();
     }
 
     /**
@@ -175,6 +184,16 @@
     }
 
     /**
+     * Returns the list of additional actions.
+     *
+     * @see ConversationItem.Builder#addAction(Action)
+     */
+    @NonNull
+    public List<Action> getActions() {
+        return mActions;
+    }
+
+    /**
      * Verifies that a given {@link Person} has the required fields to be a message sender. Returns
      * the input {@link Person} if valid, or throws an exception if invalid.
      *
@@ -202,6 +221,7 @@
         List<CarMessage> mMessages;
         @Nullable
         ConversationCallbackDelegate mConversationCallbackDelegate;
+        final List<Action> mActions;
 
         /**
          * Specifies a unique identifier for the conversation
@@ -278,6 +298,23 @@
             return this;
         }
 
+        /**
+         * Adds an additional action for the conversation.
+         *
+         * @throws NullPointerException     if {@code action} is {@code null}
+         * @throws IllegalArgumentException if {@code action} contains unsupported Action types,
+         *                                  exceeds the maximum number of allowed actions (1) or
+         *                                  does not contain a valid {@link CarIcon}.
+         */
+        @NonNull
+        public Builder addAction(@NonNull Action action) {
+            List<Action> mActionsCopy = new ArrayList<>(mActions);
+            mActionsCopy.add(requireNonNull(action));
+            ActionsConstraints.ACTIONS_CONSTRAINTS_CONVERSATION_ITEM.validateOrThrow(mActionsCopy);
+            mActions.add(action);
+            return this;
+        }
+
         /** Returns a new {@link ConversationItem} instance defined by this builder */
         @NonNull
         public ConversationItem build() {
@@ -286,6 +323,7 @@
 
         /** Returns an empty {@link Builder} instance. */
         public Builder() {
+            mActions = new ArrayList<>();
         }
 
         /** Returns a builder from the given {@link ConversationItem}. */
@@ -297,6 +335,7 @@
             this.mIsGroupConversation = other.isGroupConversation();
             this.mConversationCallbackDelegate = other.getConversationCallbackDelegate();
             this.mMessages = other.getMessages();
+            this.mActions = new ArrayList<>(other.getActions());
         }
     }
 }
diff --git a/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java b/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java
index b91efc0f..e61e54b 100644
--- a/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java
+++ b/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java
@@ -145,6 +145,19 @@
                     .build();
 
     /**
+     * Constraints for additional ConversationItem actions. Only allows custom actions.
+     */
+    @NonNull
+    public static final ActionsConstraints ACTIONS_CONSTRAINTS_CONVERSATION_ITEM =
+            new ActionsConstraints.Builder()
+                    .setMaxActions(1)
+                    .setMaxCustomTitles(1)
+                    .addAllowedActionType(Action.TYPE_CUSTOM)
+                    .setRequireActionIcons(true)
+                    .setOnClickListenerAllowed(true)
+                    .build();
+
+    /**
      * Constraints for floating action buttons.
      *
      * <p>Only buttons with icons and background color are allowed.
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
index ef2956c..e6b6e49 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
@@ -21,8 +21,11 @@
 import static org.junit.Assert.assertThrows;
 
 import androidx.annotation.NonNull;
+import androidx.car.app.TestUtils;
+import androidx.car.app.model.Action;
 import androidx.car.app.model.CarIcon;
 import androidx.car.app.model.CarText;
+import androidx.test.core.app.ApplicationProvider;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -191,6 +194,77 @@
         assertEqual(fullyPopulatedItem, modifiedConversationCallback);
     }
 
+    @Test
+    public void addAction() {
+        CarIcon icon = TestUtils.getTestCarIcon(ApplicationProvider.getApplicationContext(),
+                "ic_test_1");
+        Action customAction = new Action.Builder().setIcon(icon).build();
+        ConversationItem item =
+                TestConversationFactory
+                        .createFullyPopulatedConversationItemBuilder()
+                        .addAction(customAction)
+                        .build();
+
+        assertThat(item.getActions()).containsExactly(customAction);
+    }
+
+    @Test
+    public void addAction_appIconInvalid_throws() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> TestConversationFactory
+                        .createFullyPopulatedConversationItemBuilder()
+                        .addAction(Action.APP_ICON)
+                        .build());
+    }
+
+    @Test
+    public void addAction_backInvalid_throws() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> TestConversationFactory
+                        .createFullyPopulatedConversationItemBuilder()
+                        .addAction(Action.BACK)
+                        .build());
+    }
+
+    @Test
+    public void addAction_panInvalid_throws() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> TestConversationFactory
+                        .createFullyPopulatedConversationItemBuilder()
+                        .addAction(Action.PAN)
+                        .build());
+    }
+
+    @Test
+    public void addAction_manyActions_throws() {
+        CarIcon icon = TestUtils.getTestCarIcon(ApplicationProvider.getApplicationContext(),
+                "ic_test_1");
+        Action customAction = new Action.Builder().setIcon(icon).build();
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> TestConversationFactory
+                        .createFullyPopulatedConversationItemBuilder()
+                        .addAction(customAction)
+                        .addAction(customAction)
+                        .build());
+    }
+
+    @Test
+    public void addAction_invalidActionNullIcon_throws() {
+        Action customAction = TestUtils.createAction("Title", /* icon= */ null);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> TestConversationFactory
+                        .createFullyPopulatedConversationItemBuilder()
+                        .addAction(customAction)
+                        .build());
+    }
+
     private void assertEqual(ConversationItem item1, ConversationItem item2) {
         assertThat(item1).isEqualTo(item2);
         assertThat(item1.hashCode()).isEqualTo(item2.hashCode());
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithBoxWithConstraints.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithBoxWithConstraints.kt
index 148eb8b..bfcd637 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithBoxWithConstraints.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithBoxWithConstraints.kt
@@ -18,6 +18,7 @@
 
 package androidx.compose.animation.demos.lookahead
 
+import android.annotation.SuppressLint
 import androidx.compose.animation.demos.gesture.pastelColors
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
@@ -49,6 +50,7 @@
 import androidx.compose.ui.layout.LookaheadScope
 import androidx.compose.ui.unit.dp
 
+@SuppressLint("UnusedBoxWithConstraintsScope")
 @Composable
 fun LookaheadWithBoxWithConstraints() {
     Box(Modifier.fillMaxSize()) {
diff --git a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/BoxWithConstraintsDetector.kt b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/BoxWithConstraintsDetector.kt
new file mode 100644
index 0000000..9667018
--- /dev/null
+++ b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/BoxWithConstraintsDetector.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.lint
+
+import androidx.compose.lint.isInPackageName
+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.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.android.tools.lint.detector.api.computeKotlinArgumentMapping
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.ULambdaExpression
+import org.jetbrains.uast.USimpleNameReferenceExpression
+import org.jetbrains.uast.tryResolve
+import org.jetbrains.uast.visitor.AbstractUastVisitor
+
+class BoxWithConstraintsDetector : Detector(), SourceCodeScanner {
+    override fun getApplicableMethodNames(): List<String> = listOf(
+        FoundationNames.Layout.BoxWithConstraints.shortName
+    )
+
+    override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+        if (method.isInPackageName(FoundationNames.Layout.PackageName)) {
+            val contentArgument = computeKotlinArgumentMapping(node, method)
+                .orEmpty()
+                .filter { (_, parameter) ->
+                    parameter.name == "content"
+                }
+                .keys
+                .filterIsInstance<ULambdaExpression>()
+                .firstOrNull() ?: return
+
+            var foundValidReference = false
+            contentArgument.accept(object : AbstractUastVisitor() {
+                override fun visitSimpleNameReferenceExpression(
+                    node: USimpleNameReferenceExpression
+                ): Boolean {
+                    val reference = (node.tryResolve() as? PsiMethod)
+                        ?: return foundValidReference // No need to continue if we have already found one
+                    if (reference.isInPackageName(FoundationNames.Layout.PackageName) &&
+                        reference.containingClass?.name == "BoxWithConstraintsScope"
+                    ) {
+                        foundValidReference = true
+                    }
+                    return foundValidReference
+                }
+            })
+            if (!foundValidReference) {
+                context.report(
+                    UnusedConstraintsParameter,
+                    node,
+                    context.getLocation(contentArgument),
+                    "BoxWithConstraints scope is not used"
+                )
+            }
+        }
+    }
+
+    companion object {
+        val UnusedConstraintsParameter = Issue.create(
+            "UnusedBoxWithConstraintsScope",
+            "BoxWithConstraints content should use the constraints provided " +
+                "as via BoxWithConstraintsScope",
+            "The `content` lambda in BoxWithConstraints has a scope " +
+                "which will include the incoming constraints. If this " +
+                "scope is ignored, then the cost of subcomposition is being wasted and " +
+                "this BoxWithConstraints should be replaced with a Box.",
+            Category.CORRECTNESS, 3, Severity.ERROR,
+            Implementation(
+                BoxWithConstraintsDetector::class.java,
+                EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+            )
+        )
+    }
+}
diff --git a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt
index 2a936c1..d3de50b 100644
--- a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt
+++ b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationIssueRegistry.kt
@@ -32,7 +32,8 @@
     override val issues get() = listOf(
         LazyLayoutStateReadInCompositionDetector.FrequentlyChangedStateReadInComposition,
         UnrememberedMutableInteractionSourceDetector.UnrememberedMutableInteractionSource,
-        NonLambdaOffsetModifierDetector.UseOfNonLambdaOverload
+        NonLambdaOffsetModifierDetector.UseOfNonLambdaOverload,
+        BoxWithConstraintsDetector.UnusedConstraintsParameter
     )
     override val vendor = Vendor(
         vendorName = "Jetpack Compose",
diff --git a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationNames.kt b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationNames.kt
index b6a07ab..99d313a 100644
--- a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationNames.kt
+++ b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/FoundationNames.kt
@@ -41,5 +41,6 @@
         val PackageName = Package(FoundationNames.PackageName, "layout")
         val Offset = Name(PackageName, "offset")
         val AbsoluteOffset = Name(PackageName, "absoluteOffset")
+        val BoxWithConstraints = Name(PackageName, "BoxWithConstraints")
     }
 }
diff --git a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/BoxWithConstraintsDetectorTest.kt b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/BoxWithConstraintsDetectorTest.kt
new file mode 100644
index 0000000..947f2b6
--- /dev/null
+++ b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/BoxWithConstraintsDetectorTest.kt
@@ -0,0 +1,216 @@
+/*
+ * 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.lint
+
+import androidx.compose.lint.test.Stubs
+import androidx.compose.lint.test.bytecodeStub
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class BoxWithConstraintsDetectorTest : LintDetectorTest() {
+    override fun getDetector(): Detector = BoxWithConstraintsDetector()
+
+    override fun getIssues(): MutableList<Issue> =
+        mutableListOf(BoxWithConstraintsDetector.UnusedConstraintsParameter)
+
+    private val BoxWithConstraintsStub = bytecodeStub(
+        filename = "BoxWithConstraints.kt",
+        filepath = "androidx/compose/foundation/layout",
+        checksum = 0xddc1f733,
+        source =
+        """
+            package androidx.compose.foundation.layout
+
+            import androidx.compose.runtime.Composable
+
+            interface Constraints {
+                val minWidth: Int
+            }
+            interface Dp {}
+            interface BoxWithConstraintsScope {
+                val constraints: Constraints
+                val minWidth: Dp
+                val maxWidth: Dp
+                val minHeight: Dp
+                val maxHeight: Dp
+            }
+
+            @Composable
+            fun BoxWithConstraints(
+                propagateMinConstraints: Boolean = false,
+                content: @Composable BoxWithConstraintsScope.() -> Unit
+            ) {}
+        """.trimIndent(),
+        """
+                META-INF/main.kotlin_module:
+                H4sIAAAAAAAA/2NgYGBmYGBgBGJ2KM3AZcWllJiXUpSfmVKhl5yfW5BfnKqX
+                ll+al5JYkpmfp5eTWJlfWiIk4pRfEZ5ZkuGcn1dcUpSYmVdS7F3CxcvFnJaf
+                L8QWklpc4l2ixKDFAAD5174zYwAAAA==
+                """,
+        """
+                androidx/compose/foundation/layout/BoxWithConstraintsKt.class:
+                H4sIAAAAAAAA/6VTXU8TQRQ9sy394qsU+SqIKCAgwhZiwkOJiRKJjQWNRYzw
+                NGyHsrSdaXZnCbwY/oav/gPfiA+G+OiPMt7ZtlrsA4lusnfunTl77p17z/74
+                +fUbgCdYZ9jgsuwpt3xuO6reUL6wj1Ugy1y7Sto1fqECbT9X5+9dfbKlpK89
+                7krtv9JxMIb0KT/jhJIV+/XRqXBoN8KQ6cYzzC0eFKtK11xpn57V7eNAOiaF
+                b2+3vLX80j5D41bY5krxn0ouOaoh8m3yd9LV+adhyvluPi+Q2q0LeyuM+VFN
+                5Blmi8qr2KdCHxlC3+ZSKs2b1e0qvRvUaoSKO0pqIXUCKYbpjqtQDcKTvGYX
+                pPboe9fx4+hjGHFOhFNtEbzhHq8LAjIsLBb/7m6+Y6dkSCp0gT4MYDCFfqQZ
+                xhqeavAK12LHlTfazw4YZm4bAEO2u29zZXHMg5omqdw+wkJ3zabCHsRSsDDG
+                MNRm2BGa08g4JbXqZxGSIzMmTqVWjWPR/rlrvBx55TWGD9eX06nry5SVtppL
+                b7iMW51vNpe+vsxaObaeSBCQvMj6VDqaHc9EM1YuFlqW6/n+OWYl4qFNvIyb
+                BPQrgKTbLq+zKZv/IzgSQZvzxTkJw6dv2uR7FyFgpPvb1Sr1O7qlyoJhsOhK
+                sRvUj4S3Z6RoqlQOr+1zzzVxazNZciuS68Ajf/JtU8AFeeb6Lh0/+6NV+hX/
+                Pv2tuhuw/pLmTnWHN1oJUiUVeI7Ydk0w0eLY7+LHGk06CvNYmDCjp2iJojzF
+                lhnxcqb3CkNfQsAjsjFqfAwjWCZ/tAlBBsMhRRwp3KHzxyE6jpUWPkHrKr1J
+                A6fLA+kkUYySb3JttGoYmIp+/ISeSD67fIXxZkqbbAQsEeYegJFYhjiHiTND
+                x7kQtEjXALaJzlwhe4hIAZMFTJHF3QKmca+AGdw/BPPxALOHSPro8THnIxPa
+                lI95Hw99JHws/AJecgBzcAUAAA==
+                """,
+        """
+                androidx/compose/foundation/layout/BoxWithConstraintsScope.class:
+                H4sIAAAAAAAA/5WSzW7aQBDH/2vA2IYQJ21aQvqdSm0uNUU9tb30Q1WRSCol
+                UhOJkzEOLNi7iF0QvfEUfYAe+hA9VCjHPlTVMSUBQSpRazWz89N/dtYz++v3
+                j58AXuAxw0tfNPuSN0deIOOeVKF3Lgei6WsuhRf5X+RAe2/l6JTr9jsplO77
+                XGh1EshemAVjcDv+0CehaHmfGp0w0FmkGAqtUC/IGSpPD2prVFrIecWwX5P9
+                ltcJdSNByvOFkHqqV96R1EeDKCJVjmodcnHKm7rNcLBeofe9y0x/NMvM/z3n
+                Y8hbbT0L/dFluFXrSh1x4R2G2qezfMo34mGK+sgSk2VgXUIjnkRl2jWfM3yd
+                jEuOUTQcw52MHVrTvZWaecs6L07GFaPMjrddo2SUU2cX39MX30yzlLbSboao
+                STS7QC3XJuos0dyU5pfoxpQWluimaye3qzC8XqdT/xg+/T6og8HikMv/P2I7
+                nrf4ydqDs+KrqdnxfGRWfPUMdlav/axLkr3jgdA8DqtiyBVvROGb+ZticE7k
+                oB+EH3gUMuzOpJ9XhCb1D2kkXybNkIFJrXhIUeKzADEL9gpzrmG5a1h+mVG1
+                R1P7APvk60Q3qGqhjlQVm1W4ZLGVmO0qbuAmCRR2cKsOV+G2QlFhV6GkkFEw
+                FfYU7ijkFWyFuwqOwj2FnMJ9BesPb1xrKxsEAAA=
+                """,
+        """
+                androidx/compose/foundation/layout/Constraints.class:
+                H4sIAAAAAAAA/5WPz07CQBDGv9mWUot/CooiT6AXWonxYjyoiQkJxAQTMeFU
+                aIEVumvYheCNZ/HgQ3gwhKMPZdxyMF7dbH47szO73zdf3x+fAM5xRKhFIp5K
+                Hi+CvkxfpEqCgZyJONJcimASvcqZDm6lUHoacaFVHkTwn6N5ZIpiGNz3npO+
+                zsMiFIaJbnHR4bEeEayT0wah2BxLPeEiaCU6Mp9GlwSWzi2jThnyBBqbqwXP
+                stBE8RnhYrUseazCPOavlp7ZzHc95jJ3UFkt6yykdslnVRZaT+t3e/3mOFXb
+                tf1c9rpOCJv/G8lYAsFNf62Xb+Siw/XoT09trAneg5xN+8kdnySE4/ZMaJ4m
+                j1zx3iS5FkLqjYJyjA/YyBbZhBwcEzGUNzzAoTmvjGDeVNwurAa2GvAMUciw
+                3cAOdrsghT34XTgKRYWSwv6GOQXnB5/tt/C/AQAA
+                """,
+        """
+                androidx/compose/foundation/layout/Dp.class:
+                H4sIAAAAAAAA/41Oy07DQAwcb6Ep4ZXykMoHIG6krXrjxENIlYqQQIJDT9tm
+                C9sku1V2U4Vbv4sD6pmPQjjlB7Cl8diWZ/z98/kFYIATwrk0SWF1UsVTmy+s
+                U/HMliaRXlsTZ/LDlj6+WwQgQjSXS8kz8xY/TuZq6gM0CO1Ran2mTfygvOQ7
+                eUUQ+bLBBlRDQKCUR5Wuuy6zpEc4Xa9aoeiIUETMZp31qi+6VC/7hIvRv55i
+                I7DSja1etX+/tcb5Qmrj3WXqCeGzLYuputeZIpw9lcbrXL1opyeZujbG+o2a
+                a7IntvAXAkcbbOOYa4/VtzmbYzSGCIZoMWKnhnCIXeyNQQ77OBhDOBw6RL/m
+                nxtjWQEAAA==
+                """
+    )
+
+    @Test
+    fun unreferencedConstraints() {
+        lint().files(
+            kotlin(
+                """
+                package foo
+
+                import androidx.compose.foundation.layout.BoxWithConstraints
+                import androidx.compose.runtime.Composable
+
+                @Composable
+                fun Test() {
+                    val foo = 123
+                    BoxWithConstraints { /**/ }
+                    BoxWithConstraints { foo }
+                    BoxWithConstraints(content = { /**/ })
+                    BoxWithConstraints(propagateMinConstraints = false, content = { /**/ })
+                }
+                """.trimIndent()
+            ),
+            BoxWithConstraintsStub,
+            Stubs.Composable,
+        )
+            .run()
+            .expect(
+                """
+src/foo/test.kt:9: Error: BoxWithConstraints scope is not used [UnusedBoxWithConstraintsScope]
+    BoxWithConstraints { /**/ }
+                       ~~~~~~~~
+src/foo/test.kt:10: Error: BoxWithConstraints scope is not used [UnusedBoxWithConstraintsScope]
+    BoxWithConstraints { foo }
+                       ~~~~~~~
+src/foo/test.kt:11: Error: BoxWithConstraints scope is not used [UnusedBoxWithConstraintsScope]
+    BoxWithConstraints(content = { /**/ })
+                                 ~~~~~~~~
+src/foo/test.kt:12: Error: BoxWithConstraints scope is not used [UnusedBoxWithConstraintsScope]
+    BoxWithConstraints(propagateMinConstraints = false, content = { /**/ })
+                                                                  ~~~~~~~~
+4 errors, 0 warnings
+                """
+            )
+    }
+
+    @Test
+    fun referencedConstraints() {
+        lint().files(
+            kotlin(
+                """
+                package foo
+
+                import androidx.compose.foundation.layout.BoxWithConstraints
+                import androidx.compose.runtime.Composable
+
+                @Composable
+                fun Foo(content: @Composable ()->Unit) {}
+                @Composable
+                fun Bar() {}
+
+                @Composable
+                fun Test() {
+                    BoxWithConstraints { constraints }
+                    BoxWithConstraints { constraints.minWidth }
+                    BoxWithConstraints { minWidth }
+                    BoxWithConstraints { maxWidth }
+                    BoxWithConstraints { minHeight }
+                    BoxWithConstraints { maxHeight }
+                    BoxWithConstraints(content = { maxWidth })
+                    BoxWithConstraints(propagateMinConstraints = false, content = { minWidth })
+                    BoxWithConstraints {
+                        if (constraints.minWidth > 100) {
+                            Foo {}
+                        } else {
+                            Bar()
+                        }
+                    }
+                    BoxWithConstraints {
+                        Foo {
+                            constraints
+                        }
+                    }
+                }
+                """.trimIndent()
+            ),
+            BoxWithConstraintsStub,
+            Stubs.Composable,
+        )
+            .run()
+            .expectClean()
+    }
+}
diff --git a/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/LazyBoxWithConstraintsActivity.kt b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/LazyBoxWithConstraintsActivity.kt
index d4714d9..54c3d1a 100644
--- a/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/LazyBoxWithConstraintsActivity.kt
+++ b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/LazyBoxWithConstraintsActivity.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.integration.macrobenchmark.target
 
+import android.annotation.SuppressLint
 import android.os.Bundle
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
@@ -73,6 +74,7 @@
     }
 }
 
+@SuppressLint("UnusedBoxWithConstraintsScope") // Need the nested subcompose layout for testing
 @Composable
 private fun NonLazyRow(entry: NestedListEntry) {
     BoxWithConstraints {
diff --git a/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorSnackbarWithButtonTest.java b/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorSnackbarWithButtonTest.java
index 203ba8b..e66d965 100644
--- a/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorSnackbarWithButtonTest.java
+++ b/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorSnackbarWithButtonTest.java
@@ -40,6 +40,7 @@
 
 import org.hamcrest.Matcher;
 import org.junit.After;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.concurrent.CountDownLatch;
@@ -132,6 +133,7 @@
         verifyBarViewStacking(textView, 0);
     }
 
+    @Ignore // b/292019798
     @Test
     public void testBehaviorBasedSlidingFromClassAnnotation() {
         // Use a layout in which a custom child view has Behavior object configured via
@@ -160,6 +162,7 @@
         verifyBarViewStacking(textView, 0);
     }
 
+    @Ignore // b/292021877
     @Test
     public void testBehaviorBasedSlidingFromRuntimeApiCall() {
         // Use a layout in which a TextView child doesn't have any configured Behavior
diff --git a/core/core-performance-play-services/build.gradle b/core/core-performance-play-services/build.gradle
index f6643d6..42cab7be 100644
--- a/core/core-performance-play-services/build.gradle
+++ b/core/core-performance-play-services/build.gradle
@@ -25,7 +25,12 @@
 dependencies {
     api(libs.kotlinStdlib)
 
+    implementation(libs.playServicesDevicePerformance)
+
+    // Coroutines
     implementation(libs.kotlinCoroutinesCore)
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1")
+
     implementation(project(":core:core-performance"))
 
     testImplementation(libs.testCore)
@@ -37,6 +42,9 @@
 }
 
 android {
+    defaultConfig {
+        minSdkVersion 24
+    }
     namespace "androidx.core.performance.play.services"
 }
 
diff --git a/core/core-performance-play-services/src/main/java/androidx/core/performance/play/services/PlayServicesDevicePerformanceRetriever.kt b/core/core-performance-play-services/src/main/java/androidx/core/performance/play/services/PlayServicesDevicePerformanceRetriever.kt
index 0682f5a..ea1ea30 100644
--- a/core/core-performance-play-services/src/main/java/androidx/core/performance/play/services/PlayServicesDevicePerformanceRetriever.kt
+++ b/core/core-performance-play-services/src/main/java/androidx/core/performance/play/services/PlayServicesDevicePerformanceRetriever.kt
@@ -18,6 +18,9 @@
 
 import android.content.Context
 import androidx.core.performance.DevicePerformanceRetriever
+import com.google.android.gms.deviceperformance.DevicePerformanceClient
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.tasks.await
 
 /**
  * A DevicePerformanceRetriever that uses Google Play Services to retrieve media performance class data.
@@ -31,10 +34,11 @@
             );
 
         companion object {
-            @Suppress("UNUSED_PARAMETER")
             @JvmStatic
             fun getPerformanceClass(context: Context): Int {
-                return 0
+                val client: DevicePerformanceClient =
+                    com.google.android.gms.deviceperformance.DevicePerformance.getClient(context)
+                return runBlocking { client.mediaPerformanceClass().await() }
             }
         }
 }
diff --git a/core/core-performance-testing/build.gradle b/core/core-performance-testing/build.gradle
index 2109a27..39b4dd1 100644
--- a/core/core-performance-testing/build.gradle
+++ b/core/core-performance-testing/build.gradle
@@ -36,6 +36,9 @@
 }
 
 android {
+    defaultConfig {
+        minSdkVersion 24
+    }
     namespace "androidx.core.performance.testing"
 }
 
diff --git a/core/core-performance/build.gradle b/core/core-performance/build.gradle
index 044a5ad..3dd2a66 100644
--- a/core/core-performance/build.gradle
+++ b/core/core-performance/build.gradle
@@ -47,5 +47,8 @@
 }
 
 android {
+    defaultConfig {
+        minSdkVersion 24
+    }
     namespace "androidx.core.performance"
 }
diff --git a/core/core-performance/samples/build.gradle b/core/core-performance/samples/build.gradle
index cbd177a..0087990 100644
--- a/core/core-performance/samples/build.gradle
+++ b/core/core-performance/samples/build.gradle
@@ -38,5 +38,8 @@
 }
 
 android {
+    defaultConfig {
+        minSdkVersion 24
+    }
     namespace "androidx.core.performance.samples"
 }
diff --git a/core/core/api/1.12.0-beta01.txt b/core/core/api/1.12.0-beta01.txt
index 4bb3fb0..7ff5c2a 100644
--- a/core/core/api/1.12.0-beta01.txt
+++ b/core/core/api/1.12.0-beta01.txt
@@ -2390,6 +2390,7 @@
   public class TypedValueCompat {
     method public static float deriveDimension(int, float, android.util.DisplayMetrics);
     method public static float dpToPx(float, android.util.DisplayMetrics);
+    method public static int getUnitFromComplexDimension(int);
     method public static float pxToDp(float, android.util.DisplayMetrics);
     method public static float pxToSp(float, android.util.DisplayMetrics);
     method public static float spToPx(float, android.util.DisplayMetrics);
@@ -4199,6 +4200,7 @@
     method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, int, @FloatRange(from=0) float);
     method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
     method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
     method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
diff --git a/core/core/api/current.ignore b/core/core/api/current.ignore
index f623e8e..a3517f0 100644
--- a/core/core/api/current.ignore
+++ b/core/core/api/current.ignore
@@ -1,51 +1,5 @@
 // Baseline format: 1.0
-AddedClass: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.Builder:
-    Added class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.Builder
-
-
-AddedField: androidx.core.view.accessibility.AccessibilityEventCompat#CONTENT_CHANGE_TYPE_CONTENT_INVALID:
-    Added field androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_INVALID
-AddedField: androidx.core.view.accessibility.AccessibilityEventCompat#CONTENT_CHANGE_TYPE_ENABLED:
-    Added field androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_ENABLED
-AddedField: androidx.core.view.accessibility.AccessibilityEventCompat#CONTENT_CHANGE_TYPE_ERROR:
-    Added field androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_ERROR
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_ANCESTORS:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_ANCESTORS
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_DESCENDANTS_HYBRID:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_HYBRID
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_SIBLINGS:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_SIBLINGS
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_UNINTERRUPTIBLE:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_UNINTERRUPTIBLE
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#MAX_NUMBER_OF_PREFETCHED_NODES:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MAX_NUMBER_OF_PREFETCHED_NODES
-AddedField: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#TYPE_MAGNIFICATION_OVERLAY:
-    Added field androidx.core.view.accessibility.AccessibilityWindowInfoCompat.TYPE_MAGNIFICATION_OVERLAY
-
-
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getBoundsInWindow(android.graphics.Rect):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getBoundsInWindow(android.graphics.Rect)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getChild(int, int):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getChild(int,int)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getContainerTitle():
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getContainerTitle()
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getParent(int):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getParent(int)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setBoundsInWindow(android.graphics.Rect):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.setBoundsInWindow(android.graphics.Rect)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setContainerTitle(CharSequence):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.setContainerTitle(CharSequence)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setQueryFromAppProcessEnabled(android.view.View, boolean):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.setQueryFromAppProcessEnabled(android.view.View,boolean)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat#getColumnTitle():
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.getColumnTitle()
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat#getRowTitle():
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.getRowTitle()
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat#RangeInfoCompat(int, float, float, float):
-    Added constructor androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat(int,float,float,float)
-AddedMethod: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getRoot(int):
-    Added method androidx.core.view.accessibility.AccessibilityWindowInfoCompat.getRoot(int)
+AddedMethod: androidx.core.util.TypedValueCompat#getUnitFromComplexDimension(int):
+    Added method androidx.core.util.TypedValueCompat.getUnitFromComplexDimension(int)
+AddedMethod: androidx.core.widget.TextViewCompat#setLineHeight(android.widget.TextView, int, float):
+    Added method androidx.core.widget.TextViewCompat.setLineHeight(android.widget.TextView,int,float)
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 4bb3fb0..7ff5c2a 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -2390,6 +2390,7 @@
   public class TypedValueCompat {
     method public static float deriveDimension(int, float, android.util.DisplayMetrics);
     method public static float dpToPx(float, android.util.DisplayMetrics);
+    method public static int getUnitFromComplexDimension(int);
     method public static float pxToDp(float, android.util.DisplayMetrics);
     method public static float pxToSp(float, android.util.DisplayMetrics);
     method public static float spToPx(float, android.util.DisplayMetrics);
@@ -4199,6 +4200,7 @@
     method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, int, @FloatRange(from=0) float);
     method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
     method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
     method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
diff --git a/core/core/api/restricted_1.12.0-beta01.txt b/core/core/api/restricted_1.12.0-beta01.txt
index 102534f..7be35d5 100644
--- a/core/core/api/restricted_1.12.0-beta01.txt
+++ b/core/core/api/restricted_1.12.0-beta01.txt
@@ -2814,6 +2814,7 @@
   public class TypedValueCompat {
     method public static float deriveDimension(int, float, android.util.DisplayMetrics);
     method public static float dpToPx(float, android.util.DisplayMetrics);
+    method public static int getUnitFromComplexDimension(int);
     method public static float pxToDp(float, android.util.DisplayMetrics);
     method public static float pxToSp(float, android.util.DisplayMetrics);
     method public static float spToPx(float, android.util.DisplayMetrics);
@@ -4700,6 +4701,7 @@
     method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, int, @FloatRange(from=0) float);
     method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
     method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
     method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
diff --git a/core/core/api/restricted_current.ignore b/core/core/api/restricted_current.ignore
index f623e8e..a3517f0 100644
--- a/core/core/api/restricted_current.ignore
+++ b/core/core/api/restricted_current.ignore
@@ -1,51 +1,5 @@
 // Baseline format: 1.0
-AddedClass: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.Builder:
-    Added class androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.Builder
-
-
-AddedField: androidx.core.view.accessibility.AccessibilityEventCompat#CONTENT_CHANGE_TYPE_CONTENT_INVALID:
-    Added field androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_INVALID
-AddedField: androidx.core.view.accessibility.AccessibilityEventCompat#CONTENT_CHANGE_TYPE_ENABLED:
-    Added field androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_ENABLED
-AddedField: androidx.core.view.accessibility.AccessibilityEventCompat#CONTENT_CHANGE_TYPE_ERROR:
-    Added field androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_ERROR
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_ANCESTORS:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_ANCESTORS
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_DESCENDANTS_HYBRID:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_HYBRID
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_SIBLINGS:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_SIBLINGS
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#FLAG_PREFETCH_UNINTERRUPTIBLE:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.FLAG_PREFETCH_UNINTERRUPTIBLE
-AddedField: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#MAX_NUMBER_OF_PREFETCHED_NODES:
-    Added field androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MAX_NUMBER_OF_PREFETCHED_NODES
-AddedField: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#TYPE_MAGNIFICATION_OVERLAY:
-    Added field androidx.core.view.accessibility.AccessibilityWindowInfoCompat.TYPE_MAGNIFICATION_OVERLAY
-
-
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getBoundsInWindow(android.graphics.Rect):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getBoundsInWindow(android.graphics.Rect)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getChild(int, int):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getChild(int,int)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getContainerTitle():
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getContainerTitle()
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#getParent(int):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.getParent(int)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setBoundsInWindow(android.graphics.Rect):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.setBoundsInWindow(android.graphics.Rect)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setContainerTitle(CharSequence):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.setContainerTitle(CharSequence)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat#setQueryFromAppProcessEnabled(android.view.View, boolean):
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.setQueryFromAppProcessEnabled(android.view.View,boolean)
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat#getColumnTitle():
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.getColumnTitle()
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat#getRowTitle():
-    Added method androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat.getRowTitle()
-AddedMethod: androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat#RangeInfoCompat(int, float, float, float):
-    Added constructor androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat(int,float,float,float)
-AddedMethod: androidx.core.view.accessibility.AccessibilityWindowInfoCompat#getRoot(int):
-    Added method androidx.core.view.accessibility.AccessibilityWindowInfoCompat.getRoot(int)
+AddedMethod: androidx.core.util.TypedValueCompat#getUnitFromComplexDimension(int):
+    Added method androidx.core.util.TypedValueCompat.getUnitFromComplexDimension(int)
+AddedMethod: androidx.core.widget.TextViewCompat#setLineHeight(android.widget.TextView, int, float):
+    Added method androidx.core.widget.TextViewCompat.setLineHeight(android.widget.TextView,int,float)
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index 102534f..7be35d5 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -2814,6 +2814,7 @@
   public class TypedValueCompat {
     method public static float deriveDimension(int, float, android.util.DisplayMetrics);
     method public static float dpToPx(float, android.util.DisplayMetrics);
+    method public static int getUnitFromComplexDimension(int);
     method public static float pxToDp(float, android.util.DisplayMetrics);
     method public static float pxToSp(float, android.util.DisplayMetrics);
     method public static float spToPx(float, android.util.DisplayMetrics);
@@ -4700,6 +4701,7 @@
     method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
     method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, int, @FloatRange(from=0) float);
     method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
     method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
     method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
diff --git a/core/core/build.gradle b/core/core/build.gradle
index 149662a..967e12e 100644
--- a/core/core/build.gradle
+++ b/core/core/build.gradle
@@ -57,6 +57,7 @@
     androidTestImplementation(project(":internal-testutils-mockito"))
 
     testImplementation(libs.junit)
+    testImplementation(libs.testExtJunit)
     testImplementation(libs.testCore)
     testImplementation(libs.testRunner)
     testImplementation(libs.truth)
diff --git a/core/core/src/androidTest/java/androidx/core/math/MathUtilsTest.java b/core/core/src/androidTest/java/androidx/core/math/MathUtilsTest.java
index 856acd4..a717d3d 100644
--- a/core/core/src/androidTest/java/androidx/core/math/MathUtilsTest.java
+++ b/core/core/src/androidTest/java/androidx/core/math/MathUtilsTest.java
@@ -17,7 +17,6 @@
 package androidx.core.math;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -30,78 +29,6 @@
 public class MathUtilsTest {
 
     @Test
-    public void testAddExact() {
-        assertEquals(2, MathUtils.addExact(1, 1));
-        assertEquals(2L, MathUtils.addExact(1L, 1L));
-        assertEquals(0, MathUtils.addExact(1, -1));
-        assertEquals(0L, MathUtils.addExact(1L, -1L));
-        assertThrows(ArithmeticException.class, () -> MathUtils.addExact(Integer.MAX_VALUE, 1));
-        assertThrows(ArithmeticException.class, () -> MathUtils.addExact(Long.MAX_VALUE, 1L));
-        assertThrows(ArithmeticException.class, () -> MathUtils.addExact(Integer.MIN_VALUE, -1));
-        assertThrows(ArithmeticException.class, () -> MathUtils.addExact(Long.MIN_VALUE, -1L));
-    }
-
-    @Test
-    public void testSubtractExact() {
-        assertEquals(0, MathUtils.subtractExact(1, 1));
-        assertEquals(0L, MathUtils.subtractExact(1L, 1L));
-        assertEquals(2, MathUtils.subtractExact(1, -1));
-        assertEquals(2L, MathUtils.subtractExact(1L, -1L));
-        assertThrows(ArithmeticException.class,
-                () -> MathUtils.subtractExact(Integer.MAX_VALUE, -1));
-        assertThrows(ArithmeticException.class, () -> MathUtils.subtractExact(Long.MAX_VALUE, -1L));
-        assertThrows(ArithmeticException.class,
-                () -> MathUtils.subtractExact(Integer.MIN_VALUE, 1));
-        assertThrows(ArithmeticException.class, () -> MathUtils.subtractExact(Long.MIN_VALUE, 1L));
-    }
-
-    @Test
-    public void testMultiplyExact() {
-        assertEquals(4, MathUtils.multiplyExact(2, 2));
-        assertEquals(4L, MathUtils.multiplyExact(2L, 2L));
-        assertEquals(0, MathUtils.multiplyExact(2, 0));
-        assertEquals(0L, MathUtils.multiplyExact(2L, 0L));
-        assertEquals(-4, MathUtils.multiplyExact(2, -2));
-        assertEquals(-4L, MathUtils.multiplyExact(2L, -2L));
-        assertThrows(ArithmeticException.class,
-                () -> MathUtils.multiplyExact(Integer.MAX_VALUE, 2));
-        assertThrows(ArithmeticException.class, () -> MathUtils.multiplyExact(Long.MAX_VALUE, 2L));
-        assertThrows(ArithmeticException.class,
-                () -> MathUtils.multiplyExact(Integer.MIN_VALUE, 2));
-        assertThrows(ArithmeticException.class, () -> MathUtils.multiplyExact(Long.MIN_VALUE, 2L));
-    }
-
-    @Test
-    public void testIncrementExact() {
-        assertEquals(1, MathUtils.incrementExact(0));
-        assertEquals(1L, MathUtils.incrementExact(0L));
-        assertThrows(ArithmeticException.class, () -> MathUtils.incrementExact(Integer.MAX_VALUE));
-        assertThrows(ArithmeticException.class, () -> MathUtils.incrementExact(Long.MAX_VALUE));
-    }
-
-    @Test
-    public void testDecrementExact() {
-        assertEquals(-1, MathUtils.decrementExact(0));
-        assertEquals(-1L, MathUtils.decrementExact(0L));
-        assertThrows(ArithmeticException.class, () -> MathUtils.decrementExact(Integer.MIN_VALUE));
-        assertThrows(ArithmeticException.class, () -> MathUtils.decrementExact(Long.MIN_VALUE));
-    }
-
-    @Test
-    public void testNegateExact() {
-        assertEquals(Integer.MIN_VALUE + 1, MathUtils.negateExact(Integer.MAX_VALUE));
-        assertEquals(Long.MIN_VALUE + 1, MathUtils.negateExact(Long.MAX_VALUE));
-        assertThrows(ArithmeticException.class, () -> MathUtils.negateExact(Integer.MIN_VALUE));
-        assertThrows(ArithmeticException.class, () -> MathUtils.negateExact(Long.MIN_VALUE));
-    }
-
-    @Test
-    public void testToIntExact() {
-        assertEquals(1, MathUtils.toIntExact(1L));
-        assertThrows(ArithmeticException.class, () -> MathUtils.toIntExact(Long.MAX_VALUE));
-    }
-
-    @Test
     public void testClamp() {
         // Int
         assertEquals(0, MathUtils.clamp(-4, 0, 7));
diff --git a/core/core/src/main/java/androidx/core/math/MathUtils.java b/core/core/src/main/java/androidx/core/math/MathUtils.java
index 8a42777..f6129cc 100644
--- a/core/core/src/main/java/androidx/core/math/MathUtils.java
+++ b/core/core/src/main/java/androidx/core/math/MathUtils.java
@@ -24,172 +24,225 @@
     private MathUtils() {}
 
     /**
-     * See {@link Math#addExact(int, int)}.
+     * Returns the sum of its arguments, throwing an exception if the result overflows an
+     * {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
      */
     public static int addExact(int x, int y) {
-        // copied from Math.java
-        int r = x + y;
-        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
-        if (((x ^ r) & (y ^ r)) < 0) {
+        int sum = x + y;
+        // If x and y have the same sign, their sum should have the same sign as well
+        if ((x >= 0 == y >= 0) && (x >= 0 != sum >= 0)) {
             throw new ArithmeticException("integer overflow");
+        } else {
+            return sum;
         }
-        return r;
     }
 
     /**
-     * See {@link Math#addExact(long, long)}.
+     * Returns the sum of its arguments, throwing an exception if the result overflows a
+     * {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
      */
     public static long addExact(long x, long y) {
-        // copied from Math.java
-        long r = x + y;
-        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
-        if (((x ^ r) & (y ^ r)) < 0) {
-            throw new ArithmeticException("long overflow");
+        long sum = x + y;
+        // If x and y have the same sign, their sum should have the same sign as well
+        if ((x >= 0 == y >= 0) && (x >= 0 != sum >= 0)) {
+            throw new ArithmeticException("integer overflow");
+        } else {
+            return sum;
         }
-        return r;
     }
 
-
     /**
-     * See {@link Math#subtractExact(int, int)}.
+     * Returns the difference of the arguments, throwing an exception if the result overflows an
+     * {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value to subtract from the first
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
      */
     public static int subtractExact(int x, int y) {
-        // copied from Math.java
-        int r = x - y;
-        // HD 2-12 Overflow iff the arguments have different signs and
-        // the sign of the result is different than the sign of x
-        if (((x ^ y) & (x ^ r)) < 0) {
+        int difference = x - y;
+        // If only one of x or y is negative, the difference should have the same sign as x
+        if ((x < 0 != y < 0) && (x < 0 != difference < 0)) {
             throw new ArithmeticException("integer overflow");
         }
-        return r;
+        return difference;
     }
 
     /**
-     * See {@link Math#subtractExact(long, long)}.
+     * Returns the difference of the arguments, throwing an exception if the result overflows a
+     * {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value to subtract from the first
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
      */
     public static long subtractExact(long x, long y) {
-        // copied from Math.java
-        long r = x - y;
-        // HD 2-12 Overflow iff the arguments have different signs and
-        // the sign of the result is different than the sign of x
-        if (((x ^ y) & (x ^ r)) < 0) {
-            throw new ArithmeticException("long overflow");
+        long difference = x - y;
+        // If only one of x or y is negative, the difference should have the same sign as x
+        if ((x < 0 != y < 0) && (x < 0 != difference < 0)) {
+            throw new ArithmeticException("integer overflow");
         }
-        return r;
+        return difference;
     }
 
     /**
-     * See {@link Math#multiplyExact(int, int)}.
+     * Returns the product of the arguments, throwing an exception if the result overflows an
+     * {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
      */
     public static int multiplyExact(int x, int y) {
-        // copied from Math.java
-        long r = (long) x * (long) y;
-        if ((int) r != r) {
+        int product = x * y;
+        // Dividing back by one of x or y should get the other back unless there was overflow
+        if (x != 0 && y != 0 && (product / x != y || product / y != x)) {
             throw new ArithmeticException("integer overflow");
         }
-        return (int) r;
+        return product;
     }
 
     /**
-     * See {@link Math#multiplyExact(long, long)}.
+     * Returns the product of the arguments, throwing an exception if the result overflows a
+     * {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
      */
     public static long multiplyExact(long x, long y) {
-        // copied from Math.java
-        long r = x * y;
-        long ax = Math.abs(x);
-        long ay = Math.abs(y);
-        if (((ax | ay) >>> 31 != 0)) {
-            // Some bits greater than 2^31 that might cause overflow
-            // Check the result using the divide operator
-            // and check for the special case of Long.MIN_VALUE * -1
-            if (((y != 0) && (r / y != x)) || (x == Long.MIN_VALUE && y == -1)) {
-                throw new ArithmeticException("long overflow");
-            }
+        long product = x * y;
+        // Dividing back by one of x or y should get the other back unless there was overflow
+        if (x != 0 && y != 0 && (product / x != y || product / y != x)) {
+            throw new ArithmeticException("integer overflow");
         }
-        return r;
+        return product;
     }
 
     /**
-     * See {@link Math#incrementExact(int)}.
+     * Returns the argument incremented by one, throwing an exception if the result overflows an
+     * {@code int}. The overflow only occurs for {@linkplain Integer#MAX_VALUE the maximum value}.
+     *
+     * @param a the value to increment
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
      */
     public static int incrementExact(int a) {
-        // copied from Math.java
         if (a == Integer.MAX_VALUE) {
             throw new ArithmeticException("integer overflow");
+        } else {
+            return a + 1;
         }
-
-        return a + 1;
     }
 
     /**
-     * See {@link Math#incrementExact(long)}.
+     * Returns the argument incremented by one, throwing an exception if the result overflows a
+     * {@code long}. The overflow only occurs for {@linkplain Long#MAX_VALUE the maximum value}.
+     *
+     * @param a the value to increment
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
      */
     public static long incrementExact(long a) {
-        // copied from Math.java
         if (a == Long.MAX_VALUE) {
-            throw new ArithmeticException("long overflow");
+            throw new ArithmeticException("integer overflow");
+        } else {
+            return a + 1;
         }
-
-        return a + 1L;
     }
 
     /**
-     * See {@link Math#decrementExact(int)}.
+     * Returns the argument decremented by one, throwing an exception if the result overflows an
+     * {@code int}. The overflow only occurs for {@linkplain Integer#MIN_VALUE the minimum value}.
+     *
+     * @param a the value to decrement
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
      */
     public static int decrementExact(int a) {
-        // copied from Math.java
         if (a == Integer.MIN_VALUE) {
             throw new ArithmeticException("integer overflow");
+        } else {
+            return a - 1;
         }
-
-        return a - 1;
     }
 
     /**
-     * See {@link Math#decrementExact(long)}.
+     * Returns the argument decremented by one, throwing an exception if the result overflows a
+     * {@code long}. The overflow only occurs for {@linkplain Long#MIN_VALUE the minimum value}.
+     *
+     * @param a the value to decrement
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
      */
     public static long decrementExact(long a) {
-        // copied from Math.java
         if (a == Long.MIN_VALUE) {
-            throw new ArithmeticException("long overflow");
+            throw new ArithmeticException("integer overflow");
+        } else {
+            return a - 1;
         }
-
-        return a - 1L;
     }
 
     /**
-     * See {@link Math#negateExact(int)}.
+     * Returns the negation of the argument, throwing an exception if the result overflows an
+     * {@code int}. The overflow only occurs for {@linkplain Integer#MIN_VALUE the minimum value}.
+     *
+     * @param a the value to negate
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
      */
     public static int negateExact(int a) {
-        // copied from Math.java
         if (a == Integer.MIN_VALUE) {
             throw new ArithmeticException("integer overflow");
+        } else {
+            return -a;
         }
-
-        return -a;
     }
 
     /**
-     * See {@link Math#negateExact(long)}.
+     * Returns the negation of the argument, throwing an exception if the result overflows a
+     * {@code long}. The overflow only occurs for {@linkplain Long#MIN_VALUE the minimum value}.
+     *
+     * @param a the value to negate
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
      */
     public static long negateExact(long a) {
-        // copied from Math.java
         if (a == Long.MIN_VALUE) {
-            throw new ArithmeticException("long overflow");
+            throw new ArithmeticException("integer overflow");
+        } else {
+            return -a;
         }
-
-        return -a;
     }
 
     /**
-     * See {@link Math#toIntExact(long)}.
+     * Returns the value of the {@code long} argument, throwing an exception if the value
+     * overflows an {@code int}.
+     *
+     * @param value the long value
+     * @return the argument as an int
+     * @throws ArithmeticException if the {@code argument} overflows an int
      */
     public static int toIntExact(long value) {
-        // copied from Math.java
-        if ((int) value != value) {
+        if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
             throw new ArithmeticException("integer overflow");
+        } else {
+            return (int) value;
         }
-        return (int) value;
     }
 
     /**
diff --git a/core/core/src/main/java/androidx/core/util/TypedValueCompat.java b/core/core/src/main/java/androidx/core/util/TypedValueCompat.java
index 49f3bab..55f102d 100644
--- a/core/core/src/main/java/androidx/core/util/TypedValueCompat.java
+++ b/core/core/src/main/java/androidx/core/util/TypedValueCompat.java
@@ -44,6 +44,17 @@
     private TypedValueCompat() {}
 
     /**
+     * Return the complex unit type for the given complex dimension. For example, a dimen type
+     * with value 12sp will return {@link TypedValue#COMPLEX_UNIT_SP}.
+     *
+     * @param complexDimension the dimension, typically {@link TypedValue#data}
+     * @return The complex unit type
+     */
+    public static int getUnitFromComplexDimension(int complexDimension) {
+        return TypedValue.COMPLEX_UNIT_MASK & (complexDimension >> TypedValue.COMPLEX_UNIT_SHIFT);
+    }
+
+    /**
      * Converts a pixel value to the given dimension, e.g. PX to DP.
      *
      * <p>This is the inverse of {@link TypedValue#applyDimension(int, float, DisplayMetrics)}
diff --git a/core/core/src/main/java/androidx/core/widget/TextViewCompat.java b/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
index 915d0af2..0e58694 100644
--- a/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
+++ b/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
@@ -54,6 +54,7 @@
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.DrawableRes;
+import androidx.annotation.FloatRange;
 import androidx.annotation.IntDef;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
@@ -806,6 +807,7 @@
      * Sets an explicit line height for this TextView. This is equivalent to the vertical distance
      * between subsequent baselines in the TextView.
      *
+     * @param textView the TextView to modify
      * @param lineHeight the line height in pixels
      *
      * @see TextView#setLineSpacing(float, float)
@@ -827,6 +829,38 @@
     }
 
     /**
+     * Sets an explicit line height to a given unit and value for the TextView. This is equivalent
+     * to the vertical distance between subsequent baselines in the TextView. See {@link
+     * TypedValue} for the possible dimension units.
+     *
+     * @param textView the TextView to modify
+     * @param unit The desired dimension unit. SP units are strongly recommended so that line height
+     *             stays proportional to the text size when fonts are scaled up for accessibility.
+     * @param lineHeight The desired line height in the given units.
+     *
+     * @see TextView#setLineSpacing(float, float)
+     * @see TextView#getLineSpacingExtra()
+     *
+     * @attr ref android.R.styleable#TextView_lineHeight
+     */
+    public static void setLineHeight(
+            @NonNull TextView textView,
+            int unit,
+            @FloatRange(from = 0) float lineHeight
+    ) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            Api34Impl.setLineHeight(textView, unit, lineHeight);
+        } else {
+            float lineHeightPx = TypedValue.applyDimension(
+                    unit,
+                    lineHeight,
+                    textView.getResources().getDisplayMetrics()
+            );
+            setLineHeight(textView, Math.round(lineHeightPx));
+        }
+    }
+
+    /**
      * Gets the parameters for text layout precomputation, for use with
      * {@link PrecomputedTextCompat}.
      *
@@ -1283,4 +1317,20 @@
             return DecimalFormatSymbols.getInstance(locale);
         }
     }
+
+    @RequiresApi(34)
+    static class Api34Impl {
+        private Api34Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        public static void setLineHeight(
+                @NonNull TextView textView,
+                int unit,
+                @FloatRange(from = 0) float lineHeight
+        ) {
+            textView.setLineHeight(unit, lineHeight);
+        }
+    }
 }
diff --git a/core/core/src/test/java/androidx/core/math/MathUtilsTest.kt b/core/core/src/test/java/androidx/core/math/MathUtilsTest.kt
new file mode 100644
index 0000000..3074b56
--- /dev/null
+++ b/core/core/src/test/java/androidx/core/math/MathUtilsTest.kt
@@ -0,0 +1,354 @@
+/*
+ * 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.core.math
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class MathUtilsTest {
+
+    @Test
+    fun testAddExact() {
+        // zero + zero
+        Assert.assertEquals(0, MathUtils.addExact(0, 0).toLong())
+        Assert.assertEquals(0L, MathUtils.addExact(0L, 0L))
+        // positive + positive
+        Assert.assertEquals(2, MathUtils.addExact(1, 1).toLong())
+        Assert.assertEquals(2L, MathUtils.addExact(1L, 1L))
+        // negative + negative
+        Assert.assertEquals(-2, MathUtils.addExact(-1, -1).toLong())
+        Assert.assertEquals(-2L, MathUtils.addExact(-1L, -1L))
+        // positive + negative
+        Assert.assertEquals(0, MathUtils.addExact(1, -1).toLong())
+        Assert.assertEquals(0L, MathUtils.addExact(1L, -1L))
+        Assert.assertEquals(-1, MathUtils.addExact(1, -2).toLong())
+        Assert.assertEquals(-1L, MathUtils.addExact(1L, -2L))
+        Assert.assertEquals(1, MathUtils.addExact(2, -1).toLong())
+        Assert.assertEquals(1L, MathUtils.addExact(2L, -1L))
+        // negative + positive
+        Assert.assertEquals(0, MathUtils.addExact(-1, 1).toLong())
+        Assert.assertEquals(0L, MathUtils.addExact(-1L, 1L))
+        Assert.assertEquals(1, MathUtils.addExact(-1, 2).toLong())
+        Assert.assertEquals(1L, MathUtils.addExact(-1L, 2L))
+        Assert.assertEquals(-1, MathUtils.addExact(-2, 1).toLong())
+        Assert.assertEquals(-1L, MathUtils.addExact(-2L, 1L))
+        // zero + positive, positive + zero
+        Assert.assertEquals(1, MathUtils.addExact(0, 1).toLong())
+        Assert.assertEquals(1L, MathUtils.addExact(0L, 1L))
+        Assert.assertEquals(1, MathUtils.addExact(1, 0).toLong())
+        Assert.assertEquals(1L, MathUtils.addExact(1L, 0L))
+        // zero + negative, negative + zero
+        Assert.assertEquals(-1, MathUtils.addExact(0, -1).toLong())
+        Assert.assertEquals(-1L, MathUtils.addExact(0L, -1L))
+        Assert.assertEquals(-1, MathUtils.addExact(-1, 0).toLong())
+        Assert.assertEquals(-1L, MathUtils.addExact(-1L, 0L))
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Int.MAX_VALUE,
+                1
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Long.MAX_VALUE,
+                1L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Int.MIN_VALUE,
+                -1
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Long.MIN_VALUE,
+                -1L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Integer.MIN_VALUE,
+                Integer.MIN_VALUE
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Long.MIN_VALUE,
+                Long.MIN_VALUE
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Integer.MAX_VALUE,
+                Integer.MAX_VALUE
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.addExact(
+                Long.MAX_VALUE,
+                Long.MAX_VALUE
+            )
+        }
+    }
+
+    @Test
+    fun testSubtractExact() {
+        // zero - zero
+        Assert.assertEquals(0, MathUtils.subtractExact(0, 0).toLong())
+        Assert.assertEquals(0L, MathUtils.subtractExact(0L, 0L))
+        // positive - positive
+        Assert.assertEquals(0, MathUtils.subtractExact(1, 1).toLong())
+        Assert.assertEquals(0L, MathUtils.subtractExact(1L, 1L))
+        Assert.assertEquals(1, MathUtils.subtractExact(2, 1).toLong())
+        Assert.assertEquals(1L, MathUtils.subtractExact(2L, 1L))
+        Assert.assertEquals(-1, MathUtils.subtractExact(1, 2).toLong())
+        Assert.assertEquals(-1L, MathUtils.subtractExact(1L, 2L))
+        // negative - negative
+        Assert.assertEquals(0, MathUtils.subtractExact(-1, -1).toLong())
+        Assert.assertEquals(0L, MathUtils.subtractExact(-1L, -1L))
+        Assert.assertEquals(-1, MathUtils.subtractExact(-2, -1).toLong())
+        Assert.assertEquals(-1L, MathUtils.subtractExact(-2L, -1L))
+        Assert.assertEquals(1, MathUtils.subtractExact(-1, -2).toLong())
+        Assert.assertEquals(1L, MathUtils.subtractExact(-1L, -2L))
+        // positive - negative, negative - positive
+        Assert.assertEquals(2, MathUtils.subtractExact(1, -1).toLong())
+        Assert.assertEquals(2L, MathUtils.subtractExact(1L, -1L))
+        Assert.assertEquals(-2, MathUtils.subtractExact(-1, 1).toLong())
+        Assert.assertEquals(-2L, MathUtils.subtractExact(-1L, 1L))
+        // zero - positive, positive - zero
+        Assert.assertEquals(-1, MathUtils.subtractExact(0, 1).toLong())
+        Assert.assertEquals(-1L, MathUtils.subtractExact(0L, 1L))
+        Assert.assertEquals(1, MathUtils.subtractExact(1, 0).toLong())
+        Assert.assertEquals(1L, MathUtils.subtractExact(1L, 0L))
+        // zero - negative, negative - zero
+        Assert.assertEquals(1, MathUtils.subtractExact(0, -1).toLong())
+        Assert.assertEquals(1L, MathUtils.subtractExact(0L, -1L))
+        Assert.assertEquals(-1, MathUtils.subtractExact(-1, 0).toLong())
+        Assert.assertEquals(-1L, MathUtils.subtractExact(-1L, 0))
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.subtractExact(
+                Int.MAX_VALUE,
+                -1
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.subtractExact(
+                Long.MAX_VALUE,
+                -1L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.subtractExact(
+                Int.MIN_VALUE,
+                1
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.subtractExact(
+                Long.MIN_VALUE,
+                1L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.subtractExact(
+                0,
+                Int.MIN_VALUE
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.subtractExact(
+                0,
+                Long.MIN_VALUE
+            )
+        }
+    }
+
+    @Test
+    fun testMultiplyExact() {
+        Assert.assertEquals(0, MathUtils.multiplyExact(0, 0).toLong())
+        Assert.assertEquals(4, MathUtils.multiplyExact(2, 2).toLong())
+        Assert.assertEquals(0L, MathUtils.multiplyExact(0L, 0L))
+        Assert.assertEquals(4L, MathUtils.multiplyExact(2L, 2L))
+        Assert.assertEquals(0, MathUtils.multiplyExact(2, 0).toLong())
+        Assert.assertEquals(0L, MathUtils.multiplyExact(2L, 0L))
+        Assert.assertEquals(-4, MathUtils.multiplyExact(2, -2).toLong())
+        Assert.assertEquals(-4L, MathUtils.multiplyExact(2L, -2L))
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Int.MAX_VALUE,
+                2
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Long.MAX_VALUE,
+                2L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Int.MIN_VALUE,
+                2
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Long.MIN_VALUE,
+                2L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Int.MAX_VALUE / 2 + 1,
+                2
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Long.MAX_VALUE / 2L + 1L,
+                2L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Int.MIN_VALUE / 2 - 1,
+                2
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Long.MIN_VALUE / 2L - 1L,
+                2L
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Int.MIN_VALUE,
+                -1
+            )
+        }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) {
+            MathUtils.multiplyExact(
+                Long.MIN_VALUE,
+                -1L
+            )
+        }
+    }
+
+    @Test
+    fun testIncrementExact() {
+        Assert.assertEquals(1, MathUtils.incrementExact(0).toLong())
+        Assert.assertEquals(1L, MathUtils.incrementExact(0L))
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.incrementExact(Int.MAX_VALUE) }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.incrementExact(Long.MAX_VALUE) }
+    }
+
+    @Test
+    fun testDecrementExact() {
+        Assert.assertEquals(-1, MathUtils.decrementExact(0).toLong())
+        Assert.assertEquals(-1L, MathUtils.decrementExact(0L))
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.decrementExact(Int.MIN_VALUE) }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.decrementExact(Long.MIN_VALUE) }
+    }
+
+    @Test
+    fun testNegateExact() {
+        Assert.assertEquals(
+            (Int.MIN_VALUE + 1).toLong(),
+            MathUtils.negateExact(Int.MAX_VALUE).toLong()
+        )
+        Assert.assertEquals(Long.MIN_VALUE + 1, MathUtils.negateExact(Long.MAX_VALUE))
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.negateExact(Int.MIN_VALUE) }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.negateExact(Long.MIN_VALUE) }
+    }
+
+    @Test
+    fun testToIntExact() {
+        Assert.assertEquals(1, MathUtils.toIntExact(1L).toLong())
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.toIntExact(Long.MAX_VALUE) }
+        Assert.assertThrows(
+            ArithmeticException::class.java
+        ) { MathUtils.toIntExact(Long.MIN_VALUE) }
+    }
+}
diff --git a/credentials/credentials-play-services-auth/src/androidTest/AndroidManifest.xml b/credentials/credentials-play-services-auth/src/androidTest/AndroidManifest.xml
index 73badf7..d7b0e91 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/AndroidManifest.xml
+++ b/credentials/credentials-play-services-auth/src/androidTest/AndroidManifest.xml
@@ -21,9 +21,5 @@
             android:name="androidx.credentials.playservices.TestCredentialsActivity"
             android:exported="false"
             />
-        <activity
-            android:name="androidx.credentials.playservices.TestCredentialsFragmentActivity"
-            android:exported="false"
-            />
     </application>
 </manifest>
\ No newline at end of file
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/TestCredentialsFragmentActivity.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/TestCredentialsFragmentActivity.kt
deleted file mode 100644
index f7ad106..0000000
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/TestCredentialsFragmentActivity.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.credentials.playservices
-
-import android.os.Build
-import androidx.annotation.RequiresApi
-import androidx.fragment.app.FragmentActivity
-
-/**
- * This is a test activity used by the Robolectric Activity Scenario tests. It acts as a calling
- * activity in our test cases. This activity uses fragments.
- */
-@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
-class TestCredentialsFragmentActivity : FragmentActivity()
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
index acbfe57..e4cddda 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
@@ -20,14 +20,12 @@
 
 import static org.junit.Assert.assertThrows;
 
-import android.app.Activity;
-import android.os.Build;
-
 import androidx.credentials.GetCredentialRequest;
 import androidx.credentials.GetPasswordOption;
 import androidx.credentials.playservices.TestCredentialsActivity;
 import androidx.credentials.playservices.controllers.BeginSignIn.CredentialProviderBeginSignInController;
 import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.google.android.gms.auth.api.identity.BeginSignInRequest;
@@ -35,56 +33,19 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.util.HashSet;
 import java.util.List;
 
-@RunWith(Parameterized.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 @SuppressWarnings("deprecation")
 public class CredentialProviderBeginSignInControllerJavaTest {
-
-    private final boolean mUseFragmentActivity;
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        return new Object[] {true, false};
-    }
-
-    public CredentialProviderBeginSignInControllerJavaTest(final boolean useFragmentActivity)
-            throws Throwable {
-        mUseFragmentActivity = useFragmentActivity;
-    }
-
-    interface TestActivityListener {
-        void onActivity(Activity a);
-    }
-
-    private void launchTestActivity(TestActivityListener listener) {
-        if (mUseFragmentActivity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-            ActivityScenario<androidx.credentials.playservices.TestCredentialsFragmentActivity>
-                    activityScenario =
-                            ActivityScenario.launch(
-                                    androidx.credentials.playservices
-                                            .TestCredentialsFragmentActivity.class);
-            activityScenario.onActivity(
-                    activity -> {
-                        listener.onActivity((Activity) activity);
-                    });
-        } else {
-            ActivityScenario<TestCredentialsActivity> activityScenario =
-                    ActivityScenario.launch(TestCredentialsActivity.class);
-            activityScenario.onActivity(
-                    activity -> {
-                        listener.onActivity((Activity) activity);
-                    });
-        }
-    }
-
     @Test
     public void convertRequestToPlayServices_setPasswordOptionRequestAndFalseAutoSelect_success() {
-        launchTestActivity(
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(
                 activity -> {
                     BeginSignInRequest actualResponse =
                             CredentialProviderBeginSignInController.getInstance(activity)
@@ -99,7 +60,9 @@
 
     @Test
     public void convertRequestToPlayServices_setPasswordOptionRequestAndTrueAutoSelect_success() {
-        launchTestActivity(
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(
                 activity -> {
                     BeginSignInRequest actualResponse =
                             CredentialProviderBeginSignInController.getInstance(activity)
@@ -116,7 +79,9 @@
 
     @Test
     public void convertRequestToPlayServices_nullRequest_throws() {
-        launchTestActivity(
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(
                 activity -> {
                     assertThrows(
                             "null get credential request must throw exception",
@@ -129,7 +94,9 @@
 
     @Test
     public void convertResponseToCredentialManager_nullRequest_throws() {
-        launchTestActivity(
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(
                 activity -> {
                     assertThrows(
                             "null sign in credential response must throw exception",
@@ -142,6 +109,9 @@
 
     @Test
     public void convertRequestToPlayServices_setGoogleIdOptionRequestAndTrueAutoSelect_success() {
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+
         GetGoogleIdOption option =
                 new GetGoogleIdOption.Builder()
                         .setServerClientId("server_client_id")
@@ -152,7 +122,7 @@
                         .setAutoSelectEnabled(true)
                         .build();
 
-        launchTestActivity(
+        activityScenario.onActivity(
                 activity -> {
                     BeginSignInRequest actualRequest =
                             CredentialProviderBeginSignInController.getInstance(activity)
@@ -181,7 +151,9 @@
 
     @Test
     public void duplicateGetInstance_shouldBeEqual() {
-        launchTestActivity(
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(
                 activity -> {
                     CredentialProviderBeginSignInController firstInstance =
                             CredentialProviderBeginSignInController.getInstance(activity);
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
index 5e05605..d245c4b 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
@@ -16,55 +16,32 @@
 
 package androidx.credentials.playservices.beginsignin
 
-import android.app.Activity
 import android.os.Build
 import androidx.annotation.RequiresApi
 import androidx.credentials.GetCredentialRequest
 import androidx.credentials.GetPasswordOption
 import androidx.credentials.playservices.TestCredentialsActivity
-import androidx.credentials.playservices.TestCredentialsFragmentActivity
 import androidx.credentials.playservices.controllers.BeginSignIn.CredentialProviderBeginSignInController.Companion.getInstance
 import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.android.libraries.identity.googleid.GetGoogleIdOption
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
 
-@RunWith(Parameterized::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @Suppress("deprecation")
 @RequiresApi(api = Build.VERSION_CODES.O)
-class CredentialProviderBeginSignInControllerTest(val useFragmentActivity: Boolean) {
-
-    companion object {
-        @JvmStatic
-        @Parameterized.Parameters(name = "{0}")
-        fun initParameters() = listOf(true, false)
-    }
-
-    private fun launchTestActivity(callback: (activity: Activity) -> Unit) {
-        if (useFragmentActivity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-            var activityScenario =
-                            ActivityScenario.launch(
-                                    androidx.credentials.playservices
-                                            .TestCredentialsFragmentActivity::class.java)
-            activityScenario.onActivity { activity: Activity ->
-                callback.invoke(activity)
-            }
-        } else {
-            var activityScenario = ActivityScenario.launch(TestCredentialsActivity::class.java)
-            activityScenario.onActivity { activity: Activity ->
-                callback.invoke(activity)
-            }
-        }
-    }
-
+class CredentialProviderBeginSignInControllerTest {
     @Test
     fun convertRequestToPlayServices_setPasswordOptionRequestAndFalseAutoSelect_success() {
-        launchTestActivity { activity: Activity ->
-            val actualResponse = getInstance(activity)
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
+            val actualResponse = getInstance(activity!!)
                 .convertRequestToPlayServices(
                     GetCredentialRequest(
                         listOf(
@@ -81,8 +58,11 @@
 
     @Test
     fun convertRequestToPlayServices_setPasswordOptionRequestAndTrueAutoSelect_success() {
-        launchTestActivity { activity: Activity ->
-            val actualResponse = getInstance(activity)
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
+            val actualResponse = getInstance(activity!!)
                 .convertRequestToPlayServices(
                     GetCredentialRequest(
                         listOf(
@@ -99,6 +79,10 @@
 
     @Test
     fun convertRequestToPlayServices_setGoogleIdOptionRequest_success() {
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+
         val option = GetGoogleIdOption.Builder()
             .setServerClientId("server_client_id")
             .setNonce("nonce")
@@ -108,8 +92,8 @@
             .setAutoSelectEnabled(true)
             .build()
 
-        launchTestActivity { activity: Activity ->
-            val actualRequest = getInstance(activity)
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
+            val actualRequest = getInstance(activity!!)
                 .convertRequestToPlayServices(
                     GetCredentialRequest(
                         listOf(
@@ -136,9 +120,12 @@
 
     @Test
     fun duplicateGetInstance_shouldBeEqual() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
-            val firstInstance = getInstance(activity)
+            val firstInstance = getInstance(activity!!)
             val secondInstance = getInstance(activity)
             assertThat(firstInstance).isEqualTo(secondInstance)
         }
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerJavaTest.java b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerJavaTest.java
index f0d5a85..00b86ba 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerJavaTest.java
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerJavaTest.java
@@ -20,8 +20,6 @@
 
 import static org.junit.Assert.assertThrows;
 
-import android.app.Activity;
-import android.os.Build;
 import android.os.Bundle;
 
 import androidx.credentials.CreateCredentialResponse;
@@ -31,6 +29,7 @@
 import androidx.credentials.playservices.TestUtils;
 import androidx.credentials.playservices.controllers.CreatePassword.CredentialProviderCreatePasswordController;
 import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.google.android.gms.auth.api.identity.SignInPassword;
@@ -39,53 +38,17 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
-@RunWith(Parameterized.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class CredentialProviderCreatePasswordControllerJavaTest {
 
-    private final boolean mUseFragmentActivity;
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        return new Object[] {true, false};
-    }
-
-    public CredentialProviderCreatePasswordControllerJavaTest(final boolean useFragmentActivity)
-            throws Throwable {
-        mUseFragmentActivity = useFragmentActivity;
-    }
-
-    interface TestActivityListener {
-        void onActivity(Activity a);
-    }
-
-    private void launchTestActivity(TestActivityListener listener) {
-        if (mUseFragmentActivity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-            ActivityScenario<androidx.credentials.playservices.TestCredentialsFragmentActivity>
-                    activityScenario =
-                            ActivityScenario.launch(
-                                    androidx.credentials.playservices
-                                            .TestCredentialsFragmentActivity.class);
-            activityScenario.onActivity(
-                    activity -> {
-                        listener.onActivity((Activity) activity);
-                    });
-        } else {
-            ActivityScenario<TestCredentialsActivity> activityScenario =
-                    ActivityScenario.launch(TestCredentialsActivity.class);
-            activityScenario.onActivity(
-                    activity -> {
-                        listener.onActivity((Activity) activity);
-                    });
-        }
-    }
-
     @Test
     public void convertResponseToCredentialManager_unitInput_success() {
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
         String expectedResponseType = new CreatePasswordResponse().getType();
-        launchTestActivity(
+        activityScenario.onActivity(
                 activity -> {
                     CreateCredentialResponse actualResponse =
                             CredentialProviderCreatePasswordController.getInstance(activity)
@@ -99,9 +62,11 @@
 
     @Test
     public void convertRequestToPlayServices_createPasswordRequest_success() {
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
         String expectedId = "LM";
         String expectedPassword = "SodaButton";
-        launchTestActivity(
+        activityScenario.onActivity(
                 activity -> {
                     SignInPassword actualRequest =
                             CredentialProviderCreatePasswordController.getInstance(activity)
@@ -118,7 +83,7 @@
     public void convertRequestToPlayServices_nullRequest_throws() {
         ActivityScenario<TestCredentialsActivity> activityScenario =
                 ActivityScenario.launch(TestCredentialsActivity.class);
-        launchTestActivity(
+        activityScenario.onActivity(
                 activity -> {
                     assertThrows(
                             "null create password request must throw exception",
@@ -132,7 +97,9 @@
 
     @Test
     public void convertResponseToCredentialManager_nullRequest_throws() {
-        launchTestActivity(
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(
                 activity -> {
                     assertThrows(
                             "null unit response must throw exception",
@@ -145,7 +112,9 @@
 
     @Test
     public void duplicateGetInstance_shouldBeEqual() {
-        launchTestActivity(
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(
                 activity -> {
                     CredentialProviderCreatePasswordController firstInstance =
                             CredentialProviderCreatePasswordController.getInstance(activity);
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerTest.kt
index cc2e365..0710e37 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpassword/CredentialProviderCreatePasswordControllerTest.kt
@@ -16,56 +16,31 @@
 
 package androidx.credentials.playservices.createpassword
 
-import android.app.Activity
-import android.os.Build
 import android.os.Bundle
-import androidx.annotation.DoNotInline
 import androidx.credentials.CreatePasswordRequest
 import androidx.credentials.CreatePasswordResponse
 import androidx.credentials.playservices.TestCredentialsActivity
 import androidx.credentials.playservices.TestUtils.Companion.equals
 import androidx.credentials.playservices.controllers.CreatePassword.CredentialProviderCreatePasswordController.Companion.getInstance
 import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
 
-@RunWith(Parameterized::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
-class CredentialProviderCreatePasswordControllerTest(val useFragmentActivity: Boolean) {
-
-    companion object {
-        @JvmStatic
-        @Parameterized.Parameters(name = "{0}")
-        fun initParameters() = listOf(true, false)
-    }
-
-    @DoNotInline
-    private fun launchTestActivity(callback: (activity: Activity) -> Unit) {
-        if (useFragmentActivity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-            var activityScenario =
-                            ActivityScenario.launch(
-                                    androidx.credentials.playservices
-                                            .TestCredentialsFragmentActivity::class.java)
-            activityScenario.onActivity { activity: Activity ->
-                callback.invoke(activity)
-            }
-        } else {
-            var activityScenario = ActivityScenario.launch(TestCredentialsActivity::class.java)
-            activityScenario.onActivity { activity: Activity ->
-                callback.invoke(activity)
-            }
-        }
-    }
-
+class CredentialProviderCreatePasswordControllerTest {
     @Test
     fun convertResponseToCredentialManager_unitInput_success() {
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
         val expectedResponseType = CreatePasswordResponse().type
-        launchTestActivity { activity: Activity ->
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
-            val actualResponse = getInstance(activity)
+            val actualResponse = getInstance(activity!!)
                 .convertResponseToCredentialManager(Unit)
 
             assertThat(actualResponse.type)
@@ -76,11 +51,14 @@
 
     @Test
     fun convertRequestToPlayServices_createPasswordRequest_success() {
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
         val expectedId = "LM"
         val expectedPassword = "SodaButton"
-        launchTestActivity { activity: Activity ->
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
-            val actualRequest = getInstance(activity)
+            val actualRequest = getInstance(activity!!)
                 .convertRequestToPlayServices(CreatePasswordRequest(
                         expectedId, expectedPassword)).signInPassword
 
@@ -92,9 +70,12 @@
 
     @Test
     fun duplicateGetInstance_shouldBeEqual() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
-            val firstInstance = getInstance(activity)
+            val firstInstance = getInstance(activity!!)
             val secondInstance = getInstance(activity)
             assertThat(firstInstance).isEqualTo(secondInstance)
         }
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerJavaTest.java b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerJavaTest.java
index 48d07d7..a814d5f 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerJavaTest.java
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerJavaTest.java
@@ -16,6 +16,7 @@
 
 package androidx.credentials.playservices.createpublickeycredential;
 
+
 import static androidx.credentials.playservices.createkeycredential.CreatePublicKeyCredentialControllerTestUtils.ALL_REQUIRED_AND_OPTIONAL_SIGNATURE;
 import static androidx.credentials.playservices.createkeycredential.CreatePublicKeyCredentialControllerTestUtils.ALL_REQUIRED_FIELDS_SIGNATURE;
 import static androidx.credentials.playservices.createkeycredential.CreatePublicKeyCredentialControllerTestUtils.MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT;
@@ -33,14 +34,12 @@
 
 import static org.junit.Assert.assertThrows;
 
-import android.app.Activity;
-import android.os.Build;
-
 import androidx.credentials.CreatePublicKeyCredentialRequest;
 import androidx.credentials.playservices.TestCredentialsActivity;
 import androidx.credentials.playservices.TestUtils;
 import androidx.credentials.playservices.controllers.CreatePublicKeyCredential.CredentialProviderCreatePublicKeyCredentialController;
 import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialCreationOptions;
@@ -49,212 +48,156 @@
 import org.json.JSONObject;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
-@RunWith(Parameterized.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class CredentialProviderCreatePublicKeyCredentialControllerJavaTest {
-
-    private final boolean mUseFragmentActivity;
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        return new Object[] {true, false};
-    }
-
-    public CredentialProviderCreatePublicKeyCredentialControllerJavaTest(
-            final boolean useFragmentActivity) throws Throwable {
-        mUseFragmentActivity = useFragmentActivity;
-    }
-
-    interface TestActivityListener {
-        void onActivity(Activity a);
-    }
-
-    private void launchTestActivity(TestActivityListener listener) {
-        if (mUseFragmentActivity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-            ActivityScenario<androidx.credentials.playservices.TestCredentialsFragmentActivity>
-                    activityScenario =
-                            ActivityScenario.launch(
-                                    androidx.credentials.playservices
-                                            .TestCredentialsFragmentActivity.class);
-            activityScenario.onActivity(
-                    activity -> {
-                        listener.onActivity((Activity) activity);
-                    });
-        } else {
-            ActivityScenario<TestCredentialsActivity> activityScenario =
-                    ActivityScenario.launch(TestCredentialsActivity.class);
-            activityScenario.onActivity(
-                    activity -> {
-                        listener.onActivity((Activity) activity);
-                    });
-        }
-    }
-
-    private PublicKeyCredentialCreationOptions convertRequestToPlayServices(
-            Activity activity, String type) {
-        CreatePublicKeyCredentialRequest pubKeyRequest = new CreatePublicKeyCredentialRequest(type);
-        return CredentialProviderCreatePublicKeyCredentialController.getInstance(activity)
-                .convertRequestToPlayServices(pubKeyRequest);
-    }
-
     @Test
     public void convertRequestToPlayServices_correctRequiredOnlyRequest_success() {
-        launchTestActivity(
-                activity -> {
-                    try {
-                        JSONObject expectedJson =
-                                new JSONObject(MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT);
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(activity -> {
+            try {
+                JSONObject expectedJson = new JSONObject(
+                        MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT);
 
-                        PublicKeyCredentialCreationOptions actualResponse =
-                                convertRequestToPlayServices(
-                                        activity, MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT);
-                        JSONObject actualJson =
-                                createJsonObjectFromPublicKeyCredentialCreationOptions(
-                                        actualResponse);
-                        JSONObject requiredKeys = new JSONObject(ALL_REQUIRED_FIELDS_SIGNATURE);
+                PublicKeyCredentialCreationOptions actualResponse =
+                        CredentialProviderCreatePublicKeyCredentialController.getInstance(activity)
+                                .convertRequestToPlayServices(
+                                        new CreatePublicKeyCredentialRequest(
+                                                MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT));
+                JSONObject actualJson = createJsonObjectFromPublicKeyCredentialCreationOptions(
+                        actualResponse);
+                JSONObject requiredKeys = new JSONObject(ALL_REQUIRED_FIELDS_SIGNATURE);
 
-                        assertThat(
-                                        TestUtils.Companion.isSubsetJson(
-                                                expectedJson, actualJson, requiredKeys))
-                                .isTrue();
-                    } catch (JSONException e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+                assertThat(TestUtils.Companion.isSubsetJson(expectedJson, actualJson,
+                        requiredKeys)).isTrue();
+                // TODO("Add remaining tests in detail after discussing ideal form")
+            } catch (JSONException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
     public void convertRequestToPlayServices_correctRequiredAndOptionalRequest_success() {
-        launchTestActivity(
-                activity -> {
-                    try {
-                        JSONObject expectedJson =
-                                new JSONObject(
-                                        MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT);
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(activity -> {
+            try {
+                JSONObject expectedJson = new JSONObject(
+                        MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT);
 
-                        PublicKeyCredentialCreationOptions actualResponse =
-                                convertRequestToPlayServices(
-                                        activity,
-                                        MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT);
-                        JSONObject actualJson =
-                                createJsonObjectFromPublicKeyCredentialCreationOptions(
-                                        actualResponse);
-                        JSONObject requiredKeys =
-                                new JSONObject(ALL_REQUIRED_AND_OPTIONAL_SIGNATURE);
+                PublicKeyCredentialCreationOptions actualResponse =
+                        CredentialProviderCreatePublicKeyCredentialController.getInstance(activity)
+                                .convertRequestToPlayServices(new CreatePublicKeyCredentialRequest(
+                                        MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT));
+                JSONObject actualJson =
+                        createJsonObjectFromPublicKeyCredentialCreationOptions(
+                                actualResponse);
+                JSONObject requiredKeys = new JSONObject(ALL_REQUIRED_AND_OPTIONAL_SIGNATURE);
 
-                        assertThat(
-                                        TestUtils.Companion.isSubsetJson(
-                                                expectedJson, actualJson, requiredKeys))
-                                .isTrue();
-                    } catch (JSONException e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+                assertThat(TestUtils.Companion.isSubsetJson(expectedJson, actualJson,
+                        requiredKeys)).isTrue();
+                // TODO("Add remaining tests in detail after discussing ideal form")
+            } catch (JSONException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
-
     @Test
     public void convertRequestToPlayServices_missingRequired_throws() {
-        launchTestActivity(
-                activity -> {
-                    try {
-                        PublicKeyCredentialCreationOptions actualResponse =
-                                convertRequestToPlayServices(
-                                        activity, MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT);
-
-                        CreatePublicKeyCredentialRequest pubKeyRequest =
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(activity -> {
+            try {
+                CredentialProviderCreatePublicKeyCredentialController
+                        .getInstance(activity)
+                        .convertRequestToPlayServices(
                                 new CreatePublicKeyCredentialRequest(
-                                        MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT);
-                        CredentialProviderCreatePublicKeyCredentialController.getInstance(activity)
-                                .convertRequestToPlayServices(
-                                        new CreatePublicKeyCredentialRequest(
-                                                MAIN_CREATE_JSON_MISSING_REQUIRED_FIELD));
+                                        MAIN_CREATE_JSON_MISSING_REQUIRED_FIELD));
 
-                        // Should not reach here.
-                        assertWithMessage("Exception should be thrown").that(true).isFalse();
-                    } catch (Exception e) {
-                        assertThat(e.getMessage().contains("No value for id")).isTrue();
-                        assertThat(e.getClass().getName().contains("JSONException")).isTrue();
-                    }
-                });
+                // Should not reach here.
+                assertWithMessage("Exception should be thrown").that(true).isFalse();
+            } catch (Exception e) {
+                assertThat(e.getMessage().contains("No value for id")).isTrue();
+                assertThat(e.getClass().getName().contains("JSONException")).isTrue();
+            }
+        });
     }
 
     @Test
     public void convertRequestToPlayServices_emptyRequired_throws() {
-        launchTestActivity(
-                activity -> {
-                    assertThrows(
-                            "Expected bad required json to throw",
-                            JSONException.class,
-                            () ->
-                                    convertRequestToPlayServices(
-                                            activity, MAIN_CREATE_JSON_REQUIRED_FIELD_EMPTY));
-                });
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(activity -> {
+
+            assertThrows("Expected bad required json to throw",
+                    JSONException.class,
+                    () -> CredentialProviderCreatePublicKeyCredentialController
+                            .getInstance(activity).convertRequestToPlayServices(
+                                    new CreatePublicKeyCredentialRequest(
+                                            MAIN_CREATE_JSON_REQUIRED_FIELD_EMPTY)));
+        });
     }
 
     @Test
     public void convertRequestToPlayServices_missingOptionalRequired_throws() {
-        launchTestActivity(
-                activity -> {
-                    assertThrows(
-                            "Expected bad required json to throw",
-                            JSONException.class,
-                            () ->
-                                    convertRequestToPlayServices(
-                                            activity, OPTIONAL_FIELD_MISSING_REQUIRED_SUBFIELD));
-                });
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(activity -> {
+
+            assertThrows("Expected bad required json to throw",
+                    JSONException.class,
+                    () -> CredentialProviderCreatePublicKeyCredentialController
+                            .getInstance(activity)
+                            .convertRequestToPlayServices(
+                                    new CreatePublicKeyCredentialRequest(
+                                            OPTIONAL_FIELD_MISSING_REQUIRED_SUBFIELD)));
+        });
     }
 
     @Test
     public void convertRequestToPlayServices_emptyOptionalRequired_throws() {
-        launchTestActivity(
-                activity -> {
-                    assertThrows(
-                            "Expected bad required json to throw",
-                            JSONException.class,
-                            () ->
-                                    convertRequestToPlayServices(
-                                            activity, OPTIONAL_FIELD_WITH_EMPTY_REQUIRED_SUBFIELD));
-                });
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(activity -> {
+
+            assertThrows("Expected bad required json to throw",
+                    JSONException.class,
+                    () -> CredentialProviderCreatePublicKeyCredentialController
+                            .getInstance(activity)
+                            .convertRequestToPlayServices(
+                                    new CreatePublicKeyCredentialRequest(
+                                            OPTIONAL_FIELD_WITH_EMPTY_REQUIRED_SUBFIELD)));
+        });
     }
 
     @Test
     public void convertRequestToPlayServices_missingOptionalNotRequired_success() {
-        launchTestActivity(
-                activity -> {
-                    try {
-                        JSONObject expectedJson =
-                                new JSONObject(OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD);
+        ActivityScenario<TestCredentialsActivity> activityScenario =
+                ActivityScenario.launch(TestCredentialsActivity.class);
+        activityScenario.onActivity(activity -> {
+            try {
+                JSONObject expectedJson = new JSONObject(
+                        OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD);
 
-                        PublicKeyCredentialCreationOptions actualResponse =
-                                convertRequestToPlayServices(
-                                        activity, OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD);
-                        JSONObject actualJson =
-                                createJsonObjectFromPublicKeyCredentialCreationOptions(
-                                        actualResponse);
-                        JSONObject requiredKeys =
-                                new JSONObject(OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD_SIGNATURE);
+                PublicKeyCredentialCreationOptions actualResponse =
+                        CredentialProviderCreatePublicKeyCredentialController.getInstance(activity)
+                                .convertRequestToPlayServices(
+                                        new CreatePublicKeyCredentialRequest(
+                                                OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD));
+                JSONObject actualJson = createJsonObjectFromPublicKeyCredentialCreationOptions(
+                        actualResponse);
+                JSONObject requiredKeys = new
+                        JSONObject(OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD_SIGNATURE);
 
-                        assertThat(
-                                        TestUtils.Companion.isSubsetJson(
-                                                expectedJson, actualJson, requiredKeys))
-                                .isTrue();
-                    } catch (JSONException e) {
-                        throw new RuntimeException(e);
-                    }
-                });
-    }
-
-    @Test
-    public void getInstanceRepeatedTest() {
-        launchTestActivity(
-                a -> {
-                    CredentialProviderCreatePublicKeyCredentialController firstInstance =
-                            CredentialProviderCreatePublicKeyCredentialController.getInstance(a);
-                    CredentialProviderCreatePublicKeyCredentialController secondInstance =
-                            CredentialProviderCreatePublicKeyCredentialController.getInstance(a);
-                    assertThat(firstInstance).isEqualTo(secondInstance);
-                });
+                assertThat(TestUtils.Companion.isSubsetJson(expectedJson, actualJson,
+                        requiredKeys)).isTrue();
+                // TODO("Add remaining tests in detail after discussing ideal form")
+            } catch (JSONException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 }
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerTest.kt
index 0e8a50e..3a9ae60 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/createpublickeycredential/CredentialProviderCreatePublicKeyCredentialControllerTest.kt
@@ -16,9 +16,6 @@
 
 package androidx.credentials.playservices.createpublickeycredential
 
-import android.app.Activity
-import android.os.Build
-import androidx.annotation.DoNotInline
 import androidx.credentials.CreatePublicKeyCredentialRequest
 import androidx.credentials.playservices.TestCredentialsActivity
 import androidx.credentials.playservices.TestUtils.Companion.isSubsetJson
@@ -35,6 +32,7 @@
 import androidx.credentials.playservices.createkeycredential.CreatePublicKeyCredentialControllerTestUtils.Companion.OPTIONAL_FIELD_WITH_EMPTY_REQUIRED_SUBFIELD
 import androidx.credentials.playservices.createkeycredential.CreatePublicKeyCredentialControllerTestUtils.Companion.createJsonObjectFromPublicKeyCredentialCreationOptions
 import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import org.json.JSONException
@@ -43,51 +41,29 @@
 import org.junit.Test
 import org.junit.function.ThrowingRunnable
 import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
 
-@RunWith(Parameterized::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
-class CredentialProviderCreatePublicKeyCredentialControllerTest(val useFragmentActivity: Boolean) {
-
-    companion object {
-        @JvmStatic
-        @Parameterized.Parameters(name = "{0}")
-        fun initParameters() = listOf(true, false)
-    }
-
-    @DoNotInline
-    private fun launchTestActivity(callback: (activity: Activity) -> Unit) {
-        if (useFragmentActivity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-            var activityScenario =
-                            ActivityScenario.launch(
-                                    androidx.credentials.playservices
-                                            .TestCredentialsFragmentActivity::class.java)
-            activityScenario.onActivity { activity: Activity ->
-                callback.invoke(activity)
-            }
-        } else {
-            var activityScenario = ActivityScenario.launch(TestCredentialsActivity::class.java)
-            activityScenario.onActivity { activity: Activity ->
-                callback.invoke(activity)
-            }
-        }
-    }
-
+class CredentialProviderCreatePublicKeyCredentialControllerTest {
     @Test
     fun convertRequestToPlayServices_correctRequiredOnlyRequest_success() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
             try {
                 val expectedJson = JSONObject(MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT)
 
-                val actualResponse = getInstance(activity).convertRequestToPlayServices(
-                            CreatePublicKeyCredentialRequest(
-                                MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT))
+                val actualResponse = getInstance(activity!!).convertRequestToPlayServices(
+                    CreatePublicKeyCredentialRequest(
+                        MAIN_CREATE_JSON_ALL_REQUIRED_FIELDS_PRESENT))
                 val actualJson =
                     createJsonObjectFromPublicKeyCredentialCreationOptions(actualResponse)
                 val requiredKeys =
                     JSONObject(ALL_REQUIRED_FIELDS_SIGNATURE)
 
                 assertThat(isSubsetJson(expectedJson, actualJson, requiredKeys)).isTrue()
+                // TODO("Add remaining tests in detail after discussing ideal form")
             } catch (e: JSONException) {
                 throw RuntimeException(e)
             }
@@ -96,20 +72,24 @@
 
     @Test
     fun convertRequestToPlayServices_correctRequiredAndOptionalRequest_success() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
             try {
                 val expectedJson = JSONObject(
                     MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT)
 
-                val actualResponse = getInstance(activity)
-                        .convertRequestToPlayServices(CreatePublicKeyCredentialRequest(
-                            MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT))
+                val actualResponse = getInstance(activity!!)
+                    .convertRequestToPlayServices(CreatePublicKeyCredentialRequest(
+                        MAIN_CREATE_JSON_ALL_REQUIRED_AND_OPTIONAL_FIELDS_PRESENT))
                 val actualJson =
                     createJsonObjectFromPublicKeyCredentialCreationOptions(actualResponse)
                 val requiredKeys =
                     JSONObject(ALL_REQUIRED_AND_OPTIONAL_SIGNATURE)
 
                 assertThat(isSubsetJson(expectedJson, actualJson, requiredKeys)).isTrue()
+                // TODO("Add remaining tests in detail after discussing ideal form")
             } catch (e: JSONException) {
                 throw java.lang.RuntimeException(e)
             }
@@ -118,88 +98,94 @@
 
     @Test
     fun convertRequestToPlayServices_missingRequired_throws() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
             Assert.assertThrows("Expected bad required json to throw",
                 JSONException::class.java,
                 ThrowingRunnable {
                     getInstance(
-                        activity
+                        activity!!
                     ).convertRequestToPlayServices(
-                            CreatePublicKeyCredentialRequest(
-                                MAIN_CREATE_JSON_MISSING_REQUIRED_FIELD
-                            )) })
+                        CreatePublicKeyCredentialRequest(
+                            MAIN_CREATE_JSON_MISSING_REQUIRED_FIELD
+                        )) })
         }
     }
 
     @Test
     fun convertRequestToPlayServices_emptyRequired_throws() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
             Assert.assertThrows("Expected bad required json to throw",
                 JSONException::class.java,
-                ThrowingRunnable { getInstance(activity
-                    ).convertRequestToPlayServices(CreatePublicKeyCredentialRequest(
-                                MAIN_CREATE_JSON_REQUIRED_FIELD_EMPTY)) })
+                ThrowingRunnable { getInstance(activity!!
+                ).convertRequestToPlayServices(CreatePublicKeyCredentialRequest(
+                    MAIN_CREATE_JSON_REQUIRED_FIELD_EMPTY)) })
         }
     }
     @Test
     fun convertRequestToPlayServices_missingOptionalRequired_throws() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
             Assert.assertThrows("Expected bad required json to throw",
                 JSONException::class.java,
                 ThrowingRunnable {
                     getInstance(
-                        activity
+                        activity!!
                     ).convertRequestToPlayServices(
-                            CreatePublicKeyCredentialRequest(
-                                OPTIONAL_FIELD_MISSING_REQUIRED_SUBFIELD)) })
+                        CreatePublicKeyCredentialRequest(
+                            OPTIONAL_FIELD_MISSING_REQUIRED_SUBFIELD)) })
         }
     }
 
     @Test
     fun convertRequestToPlayServices_emptyOptionalRequired_throws() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
 
             Assert.assertThrows("Expected bad required json to throw",
                 JSONException::class.java,
-                ThrowingRunnable { getInstance(activity).convertRequestToPlayServices(
-                            CreatePublicKeyCredentialRequest(
-                                OPTIONAL_FIELD_WITH_EMPTY_REQUIRED_SUBFIELD)) })
+                ThrowingRunnable { getInstance(activity!!).convertRequestToPlayServices(
+                    CreatePublicKeyCredentialRequest(
+                        OPTIONAL_FIELD_WITH_EMPTY_REQUIRED_SUBFIELD)) })
         }
     }
 
     @Test
     fun convertRequestToPlayServices_missingOptionalNotRequired_success() {
-        launchTestActivity { activity: Activity ->
+        val activityScenario = ActivityScenario.launch(
+            TestCredentialsActivity::class.java
+        )
+        activityScenario.onActivity { activity: TestCredentialsActivity? ->
             try {
                 val expectedJson = JSONObject(OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD)
 
                 val actualResponse =
-                    getInstance(activity)
+                    getInstance(activity!!)
                         .convertRequestToPlayServices(
                             CreatePublicKeyCredentialRequest(
                                 OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD))
                 val actualJson = createJsonObjectFromPublicKeyCredentialCreationOptions(
-                        actualResponse)
+                    actualResponse)
                 val requiredKeys =
                     JSONObject(OPTIONAL_FIELD_MISSING_OPTIONAL_SUBFIELD_SIGNATURE)
 
                 assertThat(isSubsetJson(expectedJson, actualJson, requiredKeys)).isTrue()
+                // TODO("Add remaining tests in detail after discussing ideal form")
             } catch (e: JSONException) {
                 throw java.lang.RuntimeException(e)
             }
         }
     }
-
-    @Test
-    fun getInstanceRepeatedTest() {
-        launchTestActivity { activity: Activity ->
-
-            val firstInstance = getInstance(activity)
-            val secondInstance = getInstance(activity)
-            assertThat(firstInstance).isEqualTo(secondInstance)
-        }
-    }
 }
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderFragment.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderFragment.kt
deleted file mode 100644
index 2d7f1e9..0000000
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderFragment.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.credentials.playservices
-
-import android.content.Intent
-import android.os.Bundle
-import android.os.ResultReceiver
-import androidx.annotation.RestrictTo
-import androidx.credentials.playservices.controllers.CredentialProviderBaseController
-import androidx.fragment.app.Fragment
-
-/** A fragment used if we are passed a fragment activity. */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-@Suppress("Deprecation")
-open class CredentialProviderFragment : Fragment() {
-
-  private var resultReceiver: ResultReceiver? = null
-  private var mWaitingForActivityResult = false
-
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-
-    resultReceiver = getResultReceiver()
-    if (resultReceiver == null) {
-      return
-    }
-
-    restoreState(savedInstanceState)
-    if (mWaitingForActivityResult) {
-      return // Past call still active
-    }
-  }
-
-  private fun getResultReceiver(): ResultReceiver? {
-    if (getArguments() == null) {
-      return null
-    }
-
-    return getArguments()!!.getParcelable(CredentialProviderBaseController.RESULT_RECEIVER_TAG)
-      as? ResultReceiver
-  }
-
-  private fun restoreState(savedInstanceState: Bundle?) {
-    if (savedInstanceState != null) {
-      mWaitingForActivityResult = savedInstanceState.getBoolean(KEY_AWAITING_RESULT, false)
-    }
-  }
-
-  override fun onSaveInstanceState(outState: Bundle) {
-    outState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult)
-    super.onSaveInstanceState(outState)
-  }
-
-  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-    super.onActivityResult(requestCode, resultCode, data)
-    val bundle = Bundle()
-    bundle.putBoolean(CredentialProviderBaseController.FAILURE_RESPONSE_TAG, false)
-    bundle.putInt(CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG, requestCode)
-    bundle.putParcelable(CredentialProviderBaseController.RESULT_DATA_TAG, data)
-    resultReceiver?.send(resultCode, bundle)
-    mWaitingForActivityResult = false
-  }
-
-  companion object {
-    private const val TAG = "CredentialProviderFragment"
-    private const val KEY_AWAITING_RESULT = "androidx.credentials.playservices.AWAITING_RESULT"
-
-    fun createFrom(resultReceiver: ResultReceiver): CredentialProviderFragment {
-      val f = CredentialProviderFragment()
-
-      // Supply index input as an argument.
-      val args = Bundle()
-      args.putParcelable(CredentialProviderBaseController.RESULT_RECEIVER_TAG, resultReceiver)
-      f.setArguments(args)
-
-      return f
-    }
-  }
-}
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/GmsCoreUtils.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/GmsCoreUtils.kt
deleted file mode 100644
index 112599d..0000000
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/GmsCoreUtils.kt
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.credentials.playservices
-
-import android.app.Activity
-import android.app.PendingIntent
-import android.content.IntentSender
-import android.os.Bundle
-import android.os.ResultReceiver
-import android.util.Log
-import androidx.annotation.RestrictTo
-import androidx.credentials.playservices.controllers.CredentialProviderBaseController
-import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.CREATE_INTERRUPTED
-import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.CREATE_UNKNOWN
-import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.GET_INTERRUPTED
-import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.GET_NO_CREDENTIALS
-import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.GET_UNKNOWN
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentActivity
-import com.google.android.gms.auth.api.identity.BeginSignInRequest
-import com.google.android.gms.auth.api.identity.CredentialSavingClient
-import com.google.android.gms.auth.api.identity.SavePasswordRequest
-import com.google.android.gms.auth.api.identity.SignInClient
-import com.google.android.gms.common.api.ApiException
-import com.google.android.gms.fido.fido2.Fido2ApiClient
-import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialCreationOptions
-
-/** A util class for interacting with GmsCore. */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-@Suppress("Deprecation", "ForbiddenSuperClass")
-open class GmsCoreUtils {
-
-  class GmsCoreUtilsResult(var waitingForActivityResult: Boolean, var hasFinished: Boolean)
-
-  internal companion object {
-    private const val TAG = "GmsCoreUtils"
-
-    const val DEFAULT_REQUEST_CODE = 1
-
-    class FragmentCreationException() : Exception("Failed to create exception")
-
-    fun handleCreatePublicKeyCredential(
-      apiClient: Fido2ApiClient,
-      resultReceiver: ResultReceiver,
-      fidoRegistrationRequest: PublicKeyCredentialCreationOptions?,
-      requestCode: Int,
-      activity: Activity
-    ): GmsCoreUtilsResult {
-      var waitingForActivityResult = false
-      var hasActivityFinished = false
-      var fragment = setupFragmentActivity(activity, resultReceiver)
-
-      fidoRegistrationRequest?.let {
-        apiClient
-          .getRegisterPendingIntent(fidoRegistrationRequest)
-          .addOnSuccessListener { result: PendingIntent ->
-            try {
-              startIntentSender(
-                activity,
-                result.intentSender,
-                requestCode,
-                fragment,
-              )
-            } catch (e: IntentSender.SendIntentException) {
-              setupFailure(
-                resultReceiver,
-                CREATE_UNKNOWN,
-                "During public key credential, found IntentSender " +
-                  "failure on public key creation: ${e.message}"
-              )
-            }
-          }
-          .addOnFailureListener { e: Exception ->
-            var errName: String = CREATE_UNKNOWN
-            if (e is ApiException && e.statusCode in CredentialProviderBaseController.retryables) {
-              errName = CREATE_INTERRUPTED
-            }
-            setupFailure(
-              resultReceiver,
-              errName,
-              "During create public key credential, fido registration " + "failure: ${e.message}"
-            )
-          }
-      }
-        ?: run {
-          Log.w(
-            TAG,
-            "During create public key credential, request is null, so nothing to " +
-              "launch for public key credentials"
-          )
-          hasActivityFinished = true
-        }
-      return GmsCoreUtilsResult(waitingForActivityResult, hasActivityFinished)
-    }
-
-    fun handleBeginSignIn(
-      apiClient: SignInClient,
-      resultReceiver: ResultReceiver,
-      params: BeginSignInRequest?,
-      requestCode: Int,
-      activity: Activity
-    ): GmsCoreUtilsResult {
-      var waitingForActivityResult = false
-      var hasFinished = false
-      var fragment = setupFragmentActivity(activity, resultReceiver)
-
-      params?.let {
-        apiClient
-          .beginSignIn(params)
-          .addOnSuccessListener {
-            try {
-              waitingForActivityResult = true
-              startIntentSender(
-                activity,
-                it.pendingIntent.intentSender,
-                requestCode,
-                fragment,
-              )
-            } catch (e: IntentSender.SendIntentException) {
-              setupFailure(
-                resultReceiver,
-                GET_UNKNOWN,
-                "During begin sign in, one tap ui intent sender " + "failure: ${e.message}"
-              )
-            }
-          }
-          .addOnFailureListener { e: Exception ->
-            var errName: String = GET_NO_CREDENTIALS
-            if (e is ApiException && e.statusCode in CredentialProviderBaseController.retryables) {
-              errName = GET_INTERRUPTED
-            }
-            setupFailure(
-              resultReceiver,
-              errName,
-              "During begin sign in, failure response from one tap: ${e.message}"
-            )
-          }
-      }
-        ?: run {
-          Log.i(
-            TAG,
-            "During begin sign in, params is null, nothing to launch for " + "begin sign in"
-          )
-          hasFinished = true
-        }
-      return GmsCoreUtilsResult(waitingForActivityResult, hasFinished)
-    }
-
-    fun handleCreatePassword(
-      apiClient: CredentialSavingClient,
-      resultReceiver: ResultReceiver,
-      params: SavePasswordRequest?,
-      requestCode: Int,
-      activity: Activity
-    ): GmsCoreUtilsResult {
-      var waitingForActivityResult = false
-      var hasFinished = false
-      var fragment = setupFragmentActivity(activity, resultReceiver)
-
-      params?.let {
-        apiClient
-          .savePassword(params)
-          .addOnSuccessListener {
-            try {
-              waitingForActivityResult = true
-              startIntentSender(
-                activity,
-                it.pendingIntent.intentSender,
-                requestCode,
-                fragment,
-              )
-            } catch (e: IntentSender.SendIntentException) {
-              setupFailure(
-                resultReceiver,
-                CREATE_UNKNOWN,
-                "During save password, found UI intent sender " + "failure: ${e.message}"
-              )
-            }
-          }
-          .addOnFailureListener { e: Exception ->
-            var errName: String = CREATE_UNKNOWN
-            if (e is ApiException && e.statusCode in CredentialProviderBaseController.retryables) {
-              errName = CREATE_INTERRUPTED
-            }
-            setupFailure(
-              resultReceiver,
-              errName,
-              "During save password, found " + "password failure response from one tap ${e.message}"
-            )
-          }
-      }
-        ?: run {
-          Log.i(
-            TAG,
-            "During save password, params is null, nothing to launch for create" + " password"
-          )
-          hasFinished = true
-        }
-      return GmsCoreUtilsResult(waitingForActivityResult, hasFinished)
-    }
-
-    private fun setupFragmentActivity(
-      activity: Activity,
-      resultReceiver: ResultReceiver
-    ): Fragment? {
-      if (activity is FragmentActivity) {
-        val fragment = CredentialProviderFragment.createFrom(resultReceiver)
-        val manager = activity.getSupportFragmentManager()
-        manager.beginTransaction().add(fragment, "credman").commit()
-
-        if (!fragment.isAdded()) {
-          throw FragmentCreationException()
-        }
-
-        return fragment
-      }
-
-      return null
-    }
-
-    private fun startIntentSender(
-      activity: Activity,
-      intentSender: IntentSender,
-      requestCode: Int,
-      fragment: Fragment?,
-    ) {
-      if (fragment != null && fragment.isAdded() && activity is FragmentActivity) {
-        activity.startIntentSenderFromFragment(
-          fragment,
-          intentSender,
-          requestCode,
-          null,
-          0,
-          0,
-          0,
-          null,
-        )
-        return
-      }
-
-      activity.startIntentSenderForResult(intentSender, requestCode, null, 0, 0, 0, null)
-    }
-
-    private fun setupFailure(resultReceiver: ResultReceiver, errName: String, errMsg: String) {
-      val bundle = Bundle()
-      bundle.putBoolean(CredentialProviderBaseController.FAILURE_RESPONSE_TAG, true)
-      bundle.putString(CredentialProviderBaseController.EXCEPTION_TYPE_TAG, errName)
-      bundle.putString(CredentialProviderBaseController.EXCEPTION_MESSAGE_TAG, errMsg)
-      resultReceiver.send(Integer.MAX_VALUE, bundle)
-    }
-  }
-}
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/HiddenActivity.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/HiddenActivity.kt
index 8586305..bde5471 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/HiddenActivity.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/HiddenActivity.kt
@@ -17,150 +17,230 @@
 package androidx.credentials.playservices
 
 import android.app.Activity
+import android.app.PendingIntent
 import android.content.Intent
+import android.content.IntentSender
 import android.os.Bundle
 import android.os.ResultReceiver
 import android.util.Log
 import androidx.annotation.RestrictTo
 import androidx.credentials.playservices.controllers.CredentialProviderBaseController
+import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.CREATE_INTERRUPTED
+import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.CREATE_UNKNOWN
+import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.GET_INTERRUPTED
+import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.GET_NO_CREDENTIALS
+import androidx.credentials.playservices.controllers.CredentialProviderBaseController.Companion.GET_UNKNOWN
 import com.google.android.gms.auth.api.identity.BeginSignInRequest
 import com.google.android.gms.auth.api.identity.Identity
 import com.google.android.gms.auth.api.identity.SavePasswordRequest
+import com.google.android.gms.common.api.ApiException
 import com.google.android.gms.fido.Fido
 import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialCreationOptions
 
-/** An activity used to ensure all required API versions work as intended. */
+/**
+ * An activity used to ensure all required API versions work as intended.
+ */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 @Suppress("Deprecation", "ForbiddenSuperClass")
 open class HiddenActivity : Activity() {
 
-  private var resultReceiver: ResultReceiver? = null
-  private var mWaitingForActivityResult = false
+    private var resultReceiver: ResultReceiver? = null
+    private var mWaitingForActivityResult = false
 
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-    overridePendingTransition(0, 0)
-    val type: String? = intent.getStringExtra(CredentialProviderBaseController.TYPE_TAG)
-    resultReceiver = intent.getParcelableExtra(CredentialProviderBaseController.RESULT_RECEIVER_TAG)
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        overridePendingTransition(0, 0)
+        val type: String? = intent.getStringExtra(CredentialProviderBaseController.TYPE_TAG)
+        resultReceiver = intent.getParcelableExtra(
+            CredentialProviderBaseController.RESULT_RECEIVER_TAG)
 
-    if (resultReceiver == null) {
-      finish()
+        if (resultReceiver == null) {
+            finish()
+        }
+
+        restoreState(savedInstanceState)
+        if (mWaitingForActivityResult) {
+            return; // Past call still active
+        }
+
+        when (type) {
+            CredentialProviderBaseController.BEGIN_SIGN_IN_TAG -> {
+                handleBeginSignIn()
+            }
+            CredentialProviderBaseController.CREATE_PASSWORD_TAG -> {
+                handleCreatePassword()
+            }
+            CredentialProviderBaseController.CREATE_PUBLIC_KEY_CREDENTIAL_TAG -> {
+                handleCreatePublicKeyCredential()
+            } else -> {
+                Log.w(TAG, "Activity handed an unsupported type")
+                finish()
+            }
+        }
     }
 
-    restoreState(savedInstanceState)
-    if (mWaitingForActivityResult) {
-      return
-      // Past call still active
+    private fun restoreState(savedInstanceState: Bundle?) {
+        if (savedInstanceState != null) {
+            mWaitingForActivityResult = savedInstanceState.getBoolean(KEY_AWAITING_RESULT, false)
+        }
     }
 
-    when (type) {
-      CredentialProviderBaseController.BEGIN_SIGN_IN_TAG -> {
-        handleBeginSignIn(intent, resultReceiver)
-      }
-      CredentialProviderBaseController.CREATE_PASSWORD_TAG -> {
-        handleCreatePassword(intent, resultReceiver)
-      }
-      CredentialProviderBaseController.CREATE_PUBLIC_KEY_CREDENTIAL_TAG -> {
-        handleCreatePublicKeyCredential(intent, resultReceiver)
-      }
-      else -> {
-        Log.w(TAG, "Activity handed an unsupported type")
+    private fun handleCreatePublicKeyCredential() {
+        val fidoRegistrationRequest: PublicKeyCredentialCreationOptions? = intent
+            .getParcelableExtra(CredentialProviderBaseController.REQUEST_TAG)
+        val requestCode: Int = intent.getIntExtra(
+            CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG,
+                DEFAULT_VALUE)
+        fidoRegistrationRequest?.let {
+            Fido.getFido2ApiClient(this)
+                .getRegisterPendingIntent(fidoRegistrationRequest)
+                .addOnSuccessListener { result: PendingIntent ->
+                    try {
+                        mWaitingForActivityResult = true
+                        startIntentSenderForResult(
+                            result.intentSender,
+                            requestCode,
+                            null, /* fillInIntent= */
+                            0, /* flagsMask= */
+                            0, /* flagsValue= */
+                            0, /* extraFlags= */
+                            null /* options= */
+                        )
+                    } catch (e: IntentSender.SendIntentException) {
+                        setupFailure(resultReceiver!!,
+                            CREATE_UNKNOWN,
+                            "During public key credential, found IntentSender " +
+                                "failure on public key creation: ${e.message}")
+                    }
+                }
+                .addOnFailureListener { e: Exception ->
+                    var errName: String = CREATE_UNKNOWN
+                    if (e is ApiException && e.statusCode in
+                        CredentialProviderBaseController.retryables) {
+                        errName = CREATE_INTERRUPTED
+                    }
+                    setupFailure(resultReceiver!!, errName,
+                        "During create public key credential, fido registration " +
+                            "failure: ${e.message}")
+                }
+        } ?: run {
+            Log.w(TAG, "During create public key credential, request is null, so nothing to " +
+                "launch for public key credentials")
+            finish()
+        }
+    }
+
+    private fun setupFailure(resultReceiver: ResultReceiver, errName: String, errMsg: String) {
+        val bundle = Bundle()
+        bundle.putBoolean(CredentialProviderBaseController.FAILURE_RESPONSE_TAG, true)
+        bundle.putString(CredentialProviderBaseController.EXCEPTION_TYPE_TAG, errName)
+        bundle.putString(CredentialProviderBaseController.EXCEPTION_MESSAGE_TAG, errMsg)
+        resultReceiver.send(Integer.MAX_VALUE, bundle)
         finish()
-      }
     }
-  }
 
-  private fun restoreState(savedInstanceState: Bundle?) {
-    if (savedInstanceState != null) {
-      mWaitingForActivityResult = savedInstanceState.getBoolean(KEY_AWAITING_RESULT, false)
+    override fun onSaveInstanceState(outState: Bundle) {
+        outState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult)
+        super.onSaveInstanceState(outState)
     }
-  }
 
-  private fun handleBeginSignIn(intent: Intent, resultReceiver: ResultReceiver?) {
-    val params: BeginSignInRequest? =
-      intent.getParcelableExtra(CredentialProviderBaseController.REQUEST_TAG)
-    val requestCode: Int =
-      intent.getIntExtra(CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG, DEFAULT_VALUE)
+    private fun handleBeginSignIn() {
+        val params: BeginSignInRequest? = intent.getParcelableExtra(
+            CredentialProviderBaseController.REQUEST_TAG)
+        val requestCode: Int = intent.getIntExtra(
+            CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG,
+            DEFAULT_VALUE)
+        params?.let {
+            Identity.getSignInClient(this).beginSignIn(params).addOnSuccessListener {
+                try {
+                    mWaitingForActivityResult = true
+                    startIntentSenderForResult(
+                        it.pendingIntent.intentSender,
+                        requestCode,
+                        null,
+                        0,
+                        0,
+                        0,
+                        null
+                    )
+                } catch (e: IntentSender.SendIntentException) {
+                    setupFailure(resultReceiver!!,
+                        GET_UNKNOWN,
+                            "During begin sign in, one tap ui intent sender " +
+                                "failure: ${e.message}")
+                }
+            }.addOnFailureListener { e: Exception ->
+                var errName: String = GET_NO_CREDENTIALS
+                if (e is ApiException && e.statusCode in
+                    CredentialProviderBaseController.retryables) {
+                    errName = GET_INTERRUPTED
+                }
+                setupFailure(resultReceiver!!, errName,
+                    "During begin sign in, failure response from one tap: ${e.message}")
+            }
+        } ?: run {
+            Log.i(TAG, "During begin sign in, params is null, nothing to launch for " +
+                "begin sign in")
+            finish()
+        }
+    }
 
-    if (intent.hasExtra(CredentialProviderBaseController.REQUEST_TAG) && resultReceiver != null) {
-      val result =
-        GmsCoreUtils.handleBeginSignIn(
-          Identity.getSignInClient(this),
-          resultReceiver,
-          params!!,
-          requestCode,
-          this
-        )
-      mWaitingForActivityResult = result.waitingForActivityResult
-      if (result.hasFinished) {
+    private fun handleCreatePassword() {
+        val params: SavePasswordRequest? = intent.getParcelableExtra(
+            CredentialProviderBaseController.REQUEST_TAG)
+        val requestCode: Int = intent.getIntExtra(
+            CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG,
+            DEFAULT_VALUE)
+        params?.let {
+            Identity.getCredentialSavingClient(this).savePassword(params)
+                .addOnSuccessListener {
+                    try {
+                        mWaitingForActivityResult = true
+                        startIntentSenderForResult(
+                            it.pendingIntent.intentSender,
+                            requestCode,
+                            null,
+                            0,
+                            0,
+                            0,
+                            null
+                        )
+                    } catch (e: IntentSender.SendIntentException) {
+                        setupFailure(resultReceiver!!,
+                            CREATE_UNKNOWN,
+                                "During save password, found UI intent sender " +
+                                    "failure: ${e.message}")
+                    }
+            }.addOnFailureListener { e: Exception ->
+                    var errName: String = CREATE_UNKNOWN
+                    if (e is ApiException && e.statusCode in
+                        CredentialProviderBaseController.retryables) {
+                        errName = CREATE_INTERRUPTED
+                    }
+                    setupFailure(resultReceiver!!, errName, "During save password, found " +
+                        "password failure response from one tap ${e.message}")
+            }
+        } ?: run {
+            Log.i(TAG, "During save password, params is null, nothing to launch for create" +
+                " password")
+            finish()
+        }
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        super.onActivityResult(requestCode, resultCode, data)
+        val bundle = Bundle()
+        bundle.putBoolean(CredentialProviderBaseController.FAILURE_RESPONSE_TAG, false)
+        bundle.putInt(CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG, requestCode)
+        bundle.putParcelable(CredentialProviderBaseController.RESULT_DATA_TAG, data)
+        resultReceiver?.send(resultCode, bundle)
+        mWaitingForActivityResult = false
         finish()
-      }
     }
-  }
 
-  private fun handleCreatePassword(intent: Intent, resultReceiver: ResultReceiver?) {
-    val params: SavePasswordRequest? =
-      intent.getParcelableExtra(CredentialProviderBaseController.REQUEST_TAG)
-    val requestCode: Int =
-      intent.getIntExtra(CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG, DEFAULT_VALUE)
-
-    if (intent.hasExtra(CredentialProviderBaseController.REQUEST_TAG) && resultReceiver != null) {
-      val result =
-        GmsCoreUtils.handleCreatePassword(
-          Identity.getCredentialSavingClient(this),
-          resultReceiver,
-          params!!,
-          requestCode,
-          this
-        )
-      mWaitingForActivityResult = result.waitingForActivityResult
-      if (result.hasFinished) {
-        finish()
-      }
+    companion object {
+        private const val DEFAULT_VALUE: Int = 1
+        private const val TAG = "HiddenActivity"
+        private const val KEY_AWAITING_RESULT = "androidx.credentials.playservices.AWAITING_RESULT"
     }
-  }
-
-  private fun handleCreatePublicKeyCredential(intent: Intent, resultReceiver: ResultReceiver?) {
-    val fidoRegistrationRequest: PublicKeyCredentialCreationOptions? =
-      intent.getParcelableExtra(CredentialProviderBaseController.REQUEST_TAG)
-    val requestCode: Int =
-      intent.getIntExtra(CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG, DEFAULT_VALUE)
-
-    if (intent.hasExtra(CredentialProviderBaseController.REQUEST_TAG) && resultReceiver != null) {
-      val result =
-        GmsCoreUtils.handleCreatePublicKeyCredential(
-          Fido.getFido2ApiClient(this),
-          resultReceiver,
-          fidoRegistrationRequest!!,
-          requestCode,
-          this
-        )
-      mWaitingForActivityResult = result.waitingForActivityResult
-      if (result.hasFinished) {
-        finish()
-      }
-    }
-  }
-
-  override fun onSaveInstanceState(outState: Bundle) {
-    outState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult)
-    super.onSaveInstanceState(outState)
-  }
-
-  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-    super.onActivityResult(requestCode, resultCode, data)
-    val bundle = Bundle()
-    bundle.putBoolean(CredentialProviderBaseController.FAILURE_RESPONSE_TAG, false)
-    bundle.putInt(CredentialProviderBaseController.ACTIVITY_REQUEST_CODE_TAG, requestCode)
-    bundle.putParcelable(CredentialProviderBaseController.RESULT_DATA_TAG, data)
-    resultReceiver?.send(resultCode, bundle)
-    mWaitingForActivityResult = false
-    finish()
-  }
-
-  companion object {
-    private const val DEFAULT_VALUE: Int = 1
-    private const val TAG = "HiddenActivity"
-    private const val KEY_AWAITING_RESULT = "androidx.credentials.playservices.AWAITING_RESULT"
-  }
 }
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
index 18f8a16..b0d9453 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
@@ -36,13 +36,11 @@
 import androidx.credentials.exceptions.GetCredentialInterruptedException
 import androidx.credentials.exceptions.GetCredentialUnknownException
 import androidx.credentials.playservices.CredentialProviderPlayServicesImpl
-import androidx.credentials.playservices.GmsCoreUtils
 import androidx.credentials.playservices.HiddenActivity
 import androidx.credentials.playservices.controllers.BeginSignIn.BeginSignInControllerUtility.Companion.constructBeginSignInRequest
 import androidx.credentials.playservices.controllers.CreatePublicKeyCredential.PublicKeyCredentialControllerUtility
 import androidx.credentials.playservices.controllers.CredentialProviderBaseController
 import androidx.credentials.playservices.controllers.CredentialProviderController
-import androidx.fragment.app.FragmentActivity
 import com.google.android.gms.auth.api.identity.BeginSignInRequest
 import com.google.android.gms.auth.api.identity.Identity
 import com.google.android.gms.auth.api.identity.SignInCredential
@@ -119,20 +117,6 @@
         }
 
         val convertedRequest: BeginSignInRequest = this.convertRequestToPlayServices(request)
-
-        // If we were passed a fragment activity use that instead of a hidden one.
-        if (context is FragmentActivity) {
-            try {
-                GmsCoreUtils.handleBeginSignIn(
-                    Identity.getSignInClient(context),
-                    resultReceiver, convertedRequest, GmsCoreUtils.DEFAULT_REQUEST_CODE,
-                    context)
-                return
-            } catch (e: Exception) {
-                Log.e(TAG, "Failed to use fragment flow", e)
-            }
-        }
-
         val hiddenIntent = Intent(context, HiddenActivity::class.java)
         hiddenIntent.putExtra(REQUEST_TAG, convertedRequest)
         generateHiddenActivityIntent(resultReceiver, hiddenIntent, BEGIN_SIGN_IN_TAG)
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePassword/CredentialProviderCreatePasswordController.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePassword/CredentialProviderCreatePasswordController.kt
index ee4c3bb..360b0c6 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePassword/CredentialProviderCreatePasswordController.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePassword/CredentialProviderCreatePasswordController.kt
@@ -32,12 +32,9 @@
 import androidx.credentials.exceptions.CreateCredentialException
 import androidx.credentials.exceptions.CreateCredentialUnknownException
 import androidx.credentials.playservices.CredentialProviderPlayServicesImpl
-import androidx.credentials.playservices.GmsCoreUtils
 import androidx.credentials.playservices.HiddenActivity
 import androidx.credentials.playservices.controllers.CredentialProviderBaseController
 import androidx.credentials.playservices.controllers.CredentialProviderController
-import androidx.fragment.app.FragmentActivity
-import com.google.android.gms.auth.api.identity.Identity
 import com.google.android.gms.auth.api.identity.SavePasswordRequest
 import com.google.android.gms.auth.api.identity.SignInPassword
 import java.util.concurrent.Executor
@@ -103,20 +100,6 @@
         }
 
         val convertedRequest: SavePasswordRequest = this.convertRequestToPlayServices(request)
-
-        // If we were passed a fragment activity use that instead of a hidden one.
-        if (context is FragmentActivity) {
-            try {
-                GmsCoreUtils.handleCreatePassword(
-                    Identity.getCredentialSavingClient(context),
-                    resultReceiver, convertedRequest, GmsCoreUtils.DEFAULT_REQUEST_CODE,
-                    context)
-                return
-            } catch (e: Exception) {
-                Log.e(TAG, "Failed to use fragment flow", e)
-            }
-        }
-
         val hiddenIntent = Intent(context, HiddenActivity::class.java)
         hiddenIntent.putExtra(REQUEST_TAG, convertedRequest)
         generateHiddenActivityIntent(resultReceiver, hiddenIntent, CREATE_PASSWORD_TAG)
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePublicKeyCredential/CredentialProviderCreatePublicKeyCredentialController.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePublicKeyCredential/CredentialProviderCreatePublicKeyCredentialController.kt
index 17a5b34..1302a81 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePublicKeyCredential/CredentialProviderCreatePublicKeyCredentialController.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/CreatePublicKeyCredential/CredentialProviderCreatePublicKeyCredentialController.kt
@@ -35,11 +35,9 @@
 import androidx.credentials.exceptions.domerrors.UnknownError
 import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
 import androidx.credentials.playservices.CredentialProviderPlayServicesImpl
-import androidx.credentials.playservices.GmsCoreUtils
 import androidx.credentials.playservices.HiddenActivity
 import androidx.credentials.playservices.controllers.CredentialProviderBaseController
 import androidx.credentials.playservices.controllers.CredentialProviderController
-import androidx.fragment.app.FragmentActivity
 import com.google.android.gms.fido.Fido
 import com.google.android.gms.fido.fido2.api.common.PublicKeyCredential
 import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialCreationOptions
@@ -121,19 +119,6 @@
         if (CredentialProviderPlayServicesImpl.cancellationReviewer(cancellationSignal)) {
             return
         }
-
-        // If we were passed a fragment activity use that instead of a hidden one.
-        if (context is FragmentActivity) {
-            try {
-                GmsCoreUtils.handleCreatePublicKeyCredential(Fido.getFido2ApiClient(context),
-                    resultReceiver, fidoRegistrationRequest, GmsCoreUtils.DEFAULT_REQUEST_CODE,
-                    context)
-                return
-            } catch (e: Exception) {
-                Log.e(TAG, "Failed to use fragment flow", e)
-            }
-        }
-
         val hiddenIntent = Intent(context, HiddenActivity::class.java)
         hiddenIntent.putExtra(REQUEST_TAG, fidoRegistrationRequest)
         generateHiddenActivityIntent(resultReceiver, hiddenIntent,
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceJavaTest.java
index a2c44d0..e8d55f0 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceJavaTest.java
@@ -23,16 +23,22 @@
 import android.os.CancellationSignal;
 import android.os.OutcomeReceiver;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
+import java.util.List;
 
-//@RunWith(AndroidJUnit4.class)
-//@SmallTest
+@RunWith(AndroidJUnit4.class)
+@SmallTest
 @SdkSuppress(minSdkVersion = 34)
 public class CredentialProviderServiceJavaTest {
 
-    //@Test
+    @Test
     public void test_createRequest() {
         CredentialProviderServiceTestImpl service = new CredentialProviderServiceTestImpl();
         service.setTestMode(true);
@@ -60,54 +66,59 @@
         assertThat(service.getLastCreateRequest()).isNotNull();
     }
 
-    //@Test
+    @Test
     public void test_getRequest() {
         CredentialProviderServiceTestImpl service = new CredentialProviderServiceTestImpl();
         service.setTestMode(true);
 
-        BeginGetCredentialRequest request =
-                new BeginGetCredentialRequest(new ArrayList<BeginGetCredentialOption>());
-        OutcomeReceiver<
-                        androidx.credentials.provider.BeginGetCredentialResponse,
-                        androidx.credentials.exceptions.GetCredentialException>
-                outcome =
-                        new OutcomeReceiver<
-                                androidx.credentials.provider.BeginGetCredentialResponse,
-                                androidx.credentials.exceptions.GetCredentialException>() {
-                    public void onResult(
-                                    androidx.credentials.provider.BeginGetCredentialResponse
-                                            response) {}
+        android.service.credentials.BeginGetCredentialOption option =
+                new android.service.credentials.BeginGetCredentialOption(
+                        "id", "type", new Bundle());
+        List<android.service.credentials.BeginGetCredentialOption> options = new ArrayList<>();
+        options.add(option);
 
-                    public void onError(
-                                    androidx.credentials.exceptions.GetCredentialException error) {}
+        android.service.credentials.BeginGetCredentialRequest request =
+                        new android.service.credentials.BeginGetCredentialRequest.Builder()
+                .setBeginGetCredentialOptions(options).build();
+        OutcomeReceiver<
+                        android.service.credentials.BeginGetCredentialResponse,
+                        android.credentials.GetCredentialException>
+                outcome = new OutcomeReceiver<
+                        android.service.credentials.BeginGetCredentialResponse,
+                                android.credentials.GetCredentialException>() {
+                        public void onResult(
+                                android.service.credentials.BeginGetCredentialResponse response) {}
+
+                        public void onError(android.credentials.GetCredentialException error) {}
                 };
 
         // Call the service.
         assertThat(service.getLastGetRequest()).isNull();
-        service.onBeginGetCredentialRequest(request, new CancellationSignal(), outcome);
+        service.onBeginGetCredential(request, new CancellationSignal(), outcome);
         assertThat(service.getLastGetRequest()).isNotNull();
     }
 
-    //@Test
+    @Test
     public void test_clearRequest() {
         CredentialProviderServiceTestImpl service = new CredentialProviderServiceTestImpl();
         service.setTestMode(true);
 
-        ProviderClearCredentialStateRequest request =
-                new ProviderClearCredentialStateRequest(
-                        new CallingAppInfo("name", new SigningInfo()));
-        OutcomeReceiver<Void, androidx.credentials.exceptions.ClearCredentialException> outcome =
+        android.service.credentials.ClearCredentialStateRequest request =
+                new android.service.credentials.ClearCredentialStateRequest(
+                        new android.service.credentials.CallingAppInfo(
+                                "name", new SigningInfo()), new Bundle());
+        OutcomeReceiver<Void, android.credentials.ClearCredentialStateException> outcome =
                 new OutcomeReceiver<
-                        Void, androidx.credentials.exceptions.ClearCredentialException>() {
+                        Void, android.credentials.ClearCredentialStateException>() {
                     public void onResult(Void response) {}
 
                     public void onError(
-                            androidx.credentials.exceptions.ClearCredentialException error) {}
+                            android.credentials.ClearCredentialStateException error) {}
                 };
 
         // Call the service.
         assertThat(service.getLastClearRequest()).isNull();
-        service.onClearCredentialStateRequest(request, new CancellationSignal(), outcome);
+        service.onClearCredentialState(request, new CancellationSignal(), outcome);
         assertThat(service.getLastClearRequest()).isNotNull();
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceTest.kt
index 700c7bd..df32b01 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CredentialProviderServiceTest.kt
@@ -21,17 +21,21 @@
 import android.os.CancellationSignal
 import android.os.OutcomeReceiver
 import android.util.Log
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
 
 @SdkSuppress(minSdkVersion = 34)
-// @RunWith(AndroidJUnit4::class)
-// @SmallTest
+@RunWith(AndroidJUnit4::class)
+@SmallTest
 class CredentialProviderServiceTest {
 
     private val LOG_TAG = "CredentialProviderServiceTest"
 
-    // @Test
+    @Test
     fun test_createRequest() {
         var service = CredentialProviderServiceTestImpl()
         service.isTestMode = true
@@ -54,49 +58,53 @@
         assertThat(service.lastCreateRequest).isNotNull()
     }
 
-    // @Test
+    @Test
     fun test_getRequest() {
         var service = CredentialProviderServiceTestImpl()
         service.isTestMode = true
 
-        var request = BeginGetCredentialRequest(listOf<BeginGetCredentialOption>())
-        val outcome = OutcomeReceiver<androidx.credentials.provider.BeginGetCredentialResponse,
-            androidx.credentials.exceptions.GetCredentialException> {
-            fun onResult(response: androidx.credentials.provider.BeginGetCredentialResponse) {
+        var option = android.service.credentials.BeginGetCredentialOption("id", "type", Bundle())
+        var request = android.service.credentials.BeginGetCredentialRequest.Builder()
+            .setBeginGetCredentialOptions(listOf(option)).build()
+        val outcome = OutcomeReceiver<
+            android.service.credentials.BeginGetCredentialResponse,
+            android.credentials.GetCredentialException> {
+            fun onResult(response: android.service.credentials.BeginGetCredentialResponse) {
                 Log.i(LOG_TAG, "get request: " + response.toString())
             }
 
-            fun onError(error: androidx.credentials.exceptions.GetCredentialException) {
+            fun onError(error: android.credentials.GetCredentialException) {
                 Log.e(LOG_TAG, "get request error", error)
             }
         }
 
         // Call the service.
         assertThat(service.lastGetRequest).isNull()
-        service.onBeginGetCredentialRequest(request, CancellationSignal(), outcome)
+        service.onBeginGetCredential(request, CancellationSignal(), outcome)
         assertThat(service.lastGetRequest).isNotNull()
     }
 
-    // @Test
+    @Test
     fun test_clearRequest() {
         var service = CredentialProviderServiceTestImpl()
         service.isTestMode = true
 
-        var request = ProviderClearCredentialStateRequest(CallingAppInfo("name", SigningInfo()))
-        val outcome = OutcomeReceiver<Void?,
-            androidx.credentials.exceptions.ClearCredentialException> {
-            fun onResult(response: Void?) {
+        var request = android.service.credentials.ClearCredentialStateRequest(
+            android.service.credentials.CallingAppInfo("name", SigningInfo()), Bundle())
+        val outcome = OutcomeReceiver<Void,
+            android.credentials.ClearCredentialStateException> {
+            fun onResult(response: Void) {
                 Log.i(LOG_TAG, "clear request: " + response.toString())
             }
 
-            fun onError(error: androidx.credentials.exceptions.ClearCredentialException) {
+            fun onError(error: android.credentials.ClearCredentialStateException) {
                 Log.e(LOG_TAG, "clear request error", error)
             }
         }
 
         // Call the service.
         assertThat(service.lastClearRequest).isNull()
-        service.onClearCredentialStateRequest(request, CancellationSignal(), outcome)
+        service.onClearCredentialState(request, CancellationSignal(), outcome)
         assertThat(service.lastClearRequest).isNotNull()
     }
 }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFrameworkImpl.kt b/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFrameworkImpl.kt
index c61120c..2843f46 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFrameworkImpl.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFrameworkImpl.kt
@@ -241,14 +241,6 @@
         val builder = android.credentials.GetCredentialRequest.Builder(
             GetCredentialRequest.toRequestDataBundle(request))
         request.credentialOptions.forEach {
-            if (request.preferImmediatelyAvailableCredentials &&
-                it is GetPublicKeyCredentialOption) {
-                it.requestData.putBoolean(
-                    "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS",
-                    true,
-                )
-            }
-
             builder.addCredentialOption(
                 android.credentials.CredentialOption.Builder(
                     it.type, it.requestData, it.candidateQueryData
diff --git a/development/referenceDocs/switcher.py b/development/referenceDocs/switcher.py
index 63195ae..562d433 100755
--- a/development/referenceDocs/switcher.py
+++ b/development/referenceDocs/switcher.py
@@ -81,14 +81,14 @@
       stub = doc.replace(java_source_abs_path, kotlin_source_abs_path)
       # Always add the switcher for java files, switch to the package summary if
       # the page itself doesn't exist in kotlin
-      slug1 = "sed -i 's/<\/h1>/{}/' {}".format("<\/h1>\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_java_switcher2.md\" %}",doc)
+      slug1 = "sed -i 's/<div id=\"refdoc-switcher-placeholder\">/{}/' {}".format("\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_java_switcher2.md\" %}",doc)
     else:
       file_path = doc[len(kotlin_ref_root)+1:]
       stub = doc.replace(kotlin_source_abs_path, java_source_abs_path)
       if (both):
-        slug1 = "sed -i 's/<\/h1>/{}/' {}".format("<\/h1>\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc)
+        slug1 = "sed -i 's/<div id=\"refdoc-switcher-placeholder\">/{}/' {}".format("\\n{% setvar page_path %}_page_path_{% endsetvar %}\\n{% setvar can_switch %}1{% endsetvar %}\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc)
       else:
-        slug1 = "sed -i 's/<\/h1>/{}/' {}".format("<\/h1>\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc)
+        slug1 = "sed -i 's/<div id=\"refdoc-switcher-placeholder\">/{}/' {}".format("\\n{% include \"reference\/_kotlin_switcher2.md\" %}",doc)
 
     os.system(slug1)
     if both or java:
diff --git a/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java b/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java
index 35c63ca..ca2a19f 100644
--- a/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java
+++ b/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java
@@ -579,97 +579,36 @@
     }
 
     @Test
-    @LargeTest
-    @Ignore("b/290382533")
+    @SmallTest
     public void testDoNotFailOnCorruptedImage() throws Throwable {
-        // ExifInterface shouldn't raise any exceptions except an IOException when unable to open
-        // a file, even with a corrupted image. Generates randomly corrupted image stream for
-        // testing. Uses Epoch date count as random seed so that we can reproduce a broken test.
-        long seed = System.currentTimeMillis() / (86400 * 1000);
-        Log.d(TAG, "testDoNotFailOnCorruptedImage random seed: " + seed);
-        Random random = new Random(seed);
+        Random random = new Random(/* seed= */ 0);
         byte[] bytes = new byte[8096];
+        random.nextBytes(bytes);
+        // Overwrite the start of the random bytes with some JPEG-like data, so it starts like a
+        // plausible image with EXIF data.
         ByteBuffer buffer = ByteBuffer.wrap(bytes);
-        for (int i = 0; i < TEST_NUMBER_OF_CORRUPTED_IMAGE_STREAMS; i++) {
-            buffer.clear();
-            random.nextBytes(bytes);
-            if (!randomlyCorrupted(random)) {
-                buffer.put(ExifInterface.JPEG_SIGNATURE);
-            }
-            if (!randomlyCorrupted(random)) {
-                buffer.put(ExifInterface.MARKER_APP1);
-            }
-            buffer.putShort((short) (random.nextInt(100) + 300));
-            if (!randomlyCorrupted(random)) {
-                buffer.put(ExifInterface.IDENTIFIER_EXIF_APP1);
-            }
-            if (!randomlyCorrupted(random)) {
-                buffer.putShort(ExifInterface.BYTE_ALIGN_MM);
-            }
-            if (!randomlyCorrupted(random)) {
-                buffer.put((byte) 0);
-                buffer.put(ExifInterface.START_CODE);
-            }
-            buffer.putInt(8);
+        buffer.put(ExifInterface.JPEG_SIGNATURE);
+        buffer.put(ExifInterface.MARKER_APP1);
+        buffer.putShort((short) 350);
+        buffer.put(ExifInterface.IDENTIFIER_EXIF_APP1);
+        buffer.putShort(ExifInterface.BYTE_ALIGN_MM);
+        buffer.put((byte) 0);
+        buffer.put(ExifInterface.START_CODE);
+        buffer.putInt(8);
+        // Number of primary tag directories
+        buffer.putShort((short) 1);
+        // Corruption starts here
 
-            // Primary Tags
-            int numberOfDirectory = random.nextInt(8) + 1;
-            if (!randomlyCorrupted(random)) {
-                buffer.putShort((short) numberOfDirectory);
-            }
-            for (int j = 0; j < numberOfDirectory; j++) {
-                generateRandomExifTag(buffer, ExifInterface.IFD_TYPE_PRIMARY, random);
-            }
-            if (!randomlyCorrupted(random)) {
-                buffer.putInt(buffer.position() - 8);
-            }
-
-            // Thumbnail Tags
-            numberOfDirectory = random.nextInt(8) + 1;
-            if (!randomlyCorrupted(random)) {
-                buffer.putShort((short) numberOfDirectory);
-            }
-            for (int j = 0; j < numberOfDirectory; j++) {
-                generateRandomExifTag(buffer, ExifInterface.IFD_TYPE_THUMBNAIL, random);
-            }
-            if (!randomlyCorrupted(random)) {
-                buffer.putInt(buffer.position() - 8);
-            }
-
-            // Preview Tags
-            numberOfDirectory = random.nextInt(8) + 1;
-            if (!randomlyCorrupted(random)) {
-                buffer.putShort((short) numberOfDirectory);
-            }
-            for (int j = 0; j < numberOfDirectory; j++) {
-                generateRandomExifTag(buffer, ExifInterface.IFD_TYPE_PREVIEW, random);
-            }
-            if (!randomlyCorrupted(random)) {
-                buffer.putInt(buffer.position() - 8);
-            }
-
-            if (!randomlyCorrupted(random)) {
-                buffer.put(ExifInterface.MARKER);
-            }
-            if (!randomlyCorrupted(random)) {
-                buffer.put(ExifInterface.MARKER_EOI);
-            }
-
-            try {
-                new ExifInterface(new ByteArrayInputStream(bytes));
-                // Always success
-            } catch (IOException e) {
-                fail("Should not reach here!");
-            }
-        }
+        ExifInterface exifInterface = new ExifInterface(new ByteArrayInputStream(bytes));
+        exifInterface.getAttribute(ExifInterface.TAG_ARTIST);
+        // Test will fail if the ExifInterface constructor or getter throw an exception.
     }
 
     @Test
     @SmallTest
-    @Ignore("b/290382533")
     public void testSetGpsInfo() throws IOException {
         final String provider = "ExifInterfaceTest";
-        final long timestamp = System.currentTimeMillis();
+        final long timestamp = 1689328448000L; // 2023-07-14T09:54:32.000Z
         final float speedInMeterPerSec = 36.627533f;
         Location location = new Location(provider);
         location.setLatitude(TEST_LATITUDE_VALID_VALUES[TEST_LATITUDE_VALID_VALUES.length - 1]);
@@ -761,7 +700,6 @@
      */
     @Test
     @SmallTest
-    @Ignore("b/290382533")
     public void testGetSetDateTime() throws IOException {
         final long expectedGetDatetimeValue =
                 1454027547000L /* TAG_DATETIME value ("2016:01:29 18:32:27") converted to msec */
@@ -788,12 +726,12 @@
                 exif.getAttribute(ExifInterface.TAG_OFFSET_TIME_DIGITIZED));
 
         // Test setting datetime values
-        final long currentTimeStamp = System.currentTimeMillis();
+        final long newTimestamp = 1689328448000L; // 2023-07-14T09:54:32.000Z
         final long expectedDatetimeOffsetLongValue = 32400000L;
-        exif.setDateTime(currentTimeStamp);
+        exif.setDateTime(newTimestamp);
         exif.saveAttributes();
         exif = new ExifInterface(imageFile.getAbsolutePath());
-        assertEquals(currentTimeStamp - expectedDatetimeOffsetLongValue, (long) exif.getDateTime());
+        assertEquals(newTimestamp - expectedDatetimeOffsetLongValue, (long) exif.getDateTime());
 
         // Test that setting null throws NPE
         try {
@@ -1433,31 +1371,6 @@
         assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
     }
 
-    private void generateRandomExifTag(ByteBuffer buffer, int ifdType, Random random) {
-        ExifInterface.ExifTag[] tagGroup = ExifInterface.EXIF_TAGS[ifdType];
-        ExifInterface.ExifTag tag = tagGroup[random.nextInt(tagGroup.length)];
-        if (!randomlyCorrupted(random)) {
-            buffer.putShort((short) tag.number);
-        }
-        int dataFormat = random.nextInt(ExifInterface.IFD_FORMAT_NAMES.length);
-        if (!randomlyCorrupted(random)) {
-            buffer.putShort((short) dataFormat);
-        }
-        buffer.putInt(1);
-        int dataLength = ExifInterface.IFD_FORMAT_BYTES_PER_FORMAT[dataFormat];
-        if (dataLength > 4) {
-            buffer.putShort((short) random.nextInt(8096 - dataLength));
-            buffer.position(buffer.position() + 2);
-        } else {
-            buffer.position(buffer.position() + 4);
-        }
-    }
-
-    private boolean randomlyCorrupted(Random random) {
-        // Corrupts somewhere in a possibility of 1/500.
-        return random.nextInt(500) == 0;
-    }
-
     private void closeQuietly(Closeable closeable) {
         if (closeable != null) {
             try {
diff --git a/glance/glance-appwidget/build.gradle b/glance/glance-appwidget/build.gradle
index 4b59ee3..a8e7d1c 100644
--- a/glance/glance-appwidget/build.gradle
+++ b/glance/glance-appwidget/build.gradle
@@ -117,7 +117,6 @@
 
 LayoutGeneratorTask.registerLayoutGenerator(
         project,
-        android,
         /* containerLayoutDirectory= */ file("src/main/layoutTemplates"),
         /* childLayoutDirectory= */ file("src/main/res/layout")
 )
diff --git a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt
index 75f6129..a54cc8a 100644
--- a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt
+++ b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt
@@ -20,7 +20,7 @@
 import androidx.glance.appwidget.layoutgenerator.LayoutGenerator
 import androidx.glance.appwidget.layoutgenerator.cleanResources
 import androidx.glance.appwidget.layoutgenerator.generateRegistry
-import com.android.build.gradle.LibraryExtension
+import com.android.build.api.variant.AndroidComponentsExtension
 import java.io.File
 import org.gradle.api.DefaultTask
 import org.gradle.api.Project
@@ -57,6 +57,10 @@
 
     @TaskAction
     fun execute() {
+
+        outputSourceDir.asFile.get().mkdirs()
+        outputResourcesDir.asFile.get().mkdirs()
+
         val generatedLayouts = LayoutGenerator().generateAllFiles(
             checkNotNull(containerLayoutDirectory.get().asFile.listFiles()).asList(),
             checkNotNull(childLayoutDirectory.get().asFile.listFiles()).asList(),
@@ -70,54 +74,51 @@
             outputSourceDir = outputSourceDir.get().asFile
         )
         cleanResources(
-            outputResourcesDir.get().asFile,
-            generatedLayouts.extractGeneratedFiles()
+            outputResourcesDir.get().asFile, generatedLayouts.extractGeneratedFiles()
         )
     }
 
     private fun GeneratedFiles.extractGeneratedFiles(): Set<File> =
         generatedContainers.values.flatMap { container ->
             container.map { it.generatedFile }
-        }.toSet() +
-        generatedBoxChildren.values.flatMap { child ->
+        }.toSet() + generatedBoxChildren.values.flatMap { child ->
             child.map { it.generatedFile }
-        }.toSet() +
-        generatedRowColumnChildren.values.flatMap { child ->
+        }.toSet() + generatedRowColumnChildren.values.flatMap { child ->
             child.map { it.generatedFile }
-        }.toSet() +
-        extraFiles
+        }.toSet() + extraFiles
 
     companion object {
         /**
-         * Registers [LayoutGeneratorTask] in [project] for all variants in [libraryExtension].
+         * Registers [LayoutGeneratorTask] in [project] for all variants.
          */
         @JvmStatic
         fun registerLayoutGenerator(
             project: Project,
-            libraryExtension: LibraryExtension,
             containerLayoutDirectory: File,
             childLayoutDirectory: File,
         ) {
-            libraryExtension.libraryVariants.all { variant ->
-                val variantName = variant.name
-                val outputDirectory = project.buildDir.resolve("generatedLayouts/$variantName")
-                val outputResourcesDir = outputDirectory.resolve("res/layouts")
-                val outputSourceDir = outputDirectory.resolve("kotlin")
-                val taskName =
-                    "generateLayouts" + variantName.replaceFirstChar { it.uppercaseChar() }
-                outputResourcesDir.mkdirs()
-                outputSourceDir.mkdirs()
-                val task = project.tasks.register(taskName, LayoutGeneratorTask::class.java) {
-                    it.containerLayoutDirectory.set(containerLayoutDirectory)
-                    it.childLayoutDirectory.set(childLayoutDirectory)
-                    it.outputResourcesDir.set(outputResourcesDir)
-                    it.outputSourceDir.set(outputSourceDir)
-                }
-                variant.registerGeneratedResFolders(
-                    project.files(outputResourcesDir).builtBy(task)
-                )
-                variant.registerJavaGeneratingTask(task, outputSourceDir)
+
+            val outputDirectory = "generatedLayouts"
+            val buildDirectory = project.layout.buildDirectory
+
+            val taskName = "generateLayouts"
+
+            val task = project.tasks.register(taskName, LayoutGeneratorTask::class.java) {
+                it.containerLayoutDirectory.set(containerLayoutDirectory)
+                it.childLayoutDirectory.set(childLayoutDirectory)
+                it.outputSourceDir.set(buildDirectory.dir("$outputDirectory/kotlin"))
+                it.outputResourcesDir.set(buildDirectory.dir("$outputDirectory/res/layouts"))
             }
+
+            project.extensions.getByType(AndroidComponentsExtension::class.java)
+                .onVariants { variant ->
+                    variant.sources.java?.addGeneratedSourceDirectory(
+                        task, LayoutGeneratorTask::outputSourceDir
+                    )
+                    variant.sources.res?.addGeneratedSourceDirectory(
+                        task, LayoutGeneratorTask::outputResourcesDir
+                    )
+                }
         }
     }
 }
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt
index 0ec5659..f9a902b 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt
@@ -19,6 +19,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.graphics.Color
 import androidx.glance.Emittable
+import androidx.glance.EmittableCheckable
 import androidx.glance.ExperimentalGlanceApi
 import androidx.glance.GlanceModifier
 import androidx.glance.GlanceNode
@@ -229,12 +230,8 @@
 
 internal class EmittableCheckBox(
     var colors: CheckBoxColors
-) : Emittable {
+) : EmittableCheckable() {
     override var modifier: GlanceModifier = GlanceModifier
-    var checked: Boolean = false
-    var text: String = ""
-    var style: TextStyle? = null
-    var maxLines: Int = Int.MAX_VALUE
 
     override fun copy(): Emittable = EmittableCheckBox(colors = colors).also {
         it.modifier = modifier
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/RadioButton.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/RadioButton.kt
index 63e99e3..aca8172 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/RadioButton.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/RadioButton.kt
@@ -19,6 +19,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.graphics.Color
 import androidx.glance.Emittable
+import androidx.glance.EmittableCheckable
 import androidx.glance.ExperimentalGlanceApi
 import androidx.glance.GlanceModifier
 import androidx.glance.GlanceNode
@@ -39,13 +40,9 @@
 
 internal class EmittableRadioButton(
     var colors: RadioButtonColors
-) : Emittable {
+) : EmittableCheckable() {
     override var modifier: GlanceModifier = GlanceModifier
-    var checked: Boolean = false
     var enabled: Boolean = true
-    var text: String = ""
-    var style: TextStyle? = null
-    var maxLines: Int = Int.MAX_VALUE
 
     override fun copy(): Emittable = EmittableRadioButton(colors = colors).also {
         it.modifier = modifier
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt
index 2eb8a9f..dab1746 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.runtime.Composable
 import androidx.glance.Emittable
+import androidx.glance.EmittableCheckable
 import androidx.glance.ExperimentalGlanceApi
 import androidx.glance.GlanceModifier
 import androidx.glance.GlanceNode
@@ -226,12 +227,8 @@
 
 internal class EmittableSwitch(
     var colors: SwitchColors
-) : Emittable {
+) : EmittableCheckable() {
     override var modifier: GlanceModifier = GlanceModifier
-    var checked: Boolean = false
-    var text: String = ""
-    var style: TextStyle? = null
-    var maxLines: Int = Int.MAX_VALUE
 
     override fun copy(): Emittable = EmittableSwitch(colors = colors).also {
         it.modifier = modifier
diff --git a/glance/glance/src/main/java/androidx/glance/Emittables.kt b/glance/glance/src/main/java/androidx/glance/Emittables.kt
index 52a538a..5b03dbf 100644
--- a/glance/glance/src/main/java/androidx/glance/Emittables.kt
+++ b/glance/glance/src/main/java/androidx/glance/Emittables.kt
@@ -18,6 +18,7 @@
 
 import androidx.annotation.RestrictTo
 import androidx.glance.layout.Alignment
+import androidx.glance.text.TextStyle
 
 /** @suppress */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -43,3 +44,17 @@
 abstract class EmittableLazyItemWithChildren : EmittableWithChildren() {
     var alignment: Alignment = Alignment.CenterStart
 }
+
+/** @suppress */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+abstract class EmittableWithText : Emittable {
+    var text: String = ""
+    var style: TextStyle? = null
+    var maxLines: Int = Int.MAX_VALUE
+}
+
+/** @suppress */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+abstract class EmittableCheckable : EmittableWithText() {
+    var checked: Boolean = false
+}
diff --git a/glance/glance/src/main/java/androidx/glance/text/Text.kt b/glance/glance/src/main/java/androidx/glance/text/Text.kt
index ace0cfb..2f9974a 100644
--- a/glance/glance/src/main/java/androidx/glance/text/Text.kt
+++ b/glance/glance/src/main/java/androidx/glance/text/Text.kt
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2021 The Android Open Source Project
  *
@@ -21,6 +20,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.graphics.Color
 import androidx.glance.Emittable
+import androidx.glance.EmittableWithText
 import androidx.glance.GlanceModifier
 import androidx.glance.GlanceNode
 import androidx.glance.text.TextDefaults.defaultTextStyle
@@ -60,11 +60,8 @@
 
 /** @suppress */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-class EmittableText : Emittable {
+class EmittableText : EmittableWithText() {
     override var modifier: GlanceModifier = GlanceModifier
-    var text: String = ""
-    var style: TextStyle? = null
-    var maxLines: Int = Int.MAX_VALUE
 
     override fun copy(): Emittable = EmittableText().also {
         it.modifier = modifier
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index abe0e47..a4025c9 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -104,7 +104,7 @@
 checkerframework = { module = "org.checkerframework:checker-qual", version = "2.5.3" }
 checkmark = { module = "net.saff.checkmark:checkmark", version = "0.1.6" }
 constraintLayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.0.1"}
-dackka = { module = "com.google.devsite:dackka", version = "1.3.4" }
+dackka = { module = "com.google.devsite:dackka", version = "1.3.5" }
 dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" }
 daggerCompiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" }
 dexmakerMockito = { module = "com.linkedin.dexmaker:dexmaker-mockito", version.ref = "dexmaker" }
@@ -194,8 +194,8 @@
 kotlinTestJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit" }
 kotlinTestJs = { module = "org.jetbrains.kotlin:kotlin-test-js" }
 kotlinReflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
-kotlinPoet = { module = "com.squareup:kotlinpoet", version = "1.12.0" }
-kotlinPoetJavaPoet = { module = "com.squareup:kotlinpoet-javapoet", version = "1.12.0" }
+kotlinPoet = { module = "com.squareup:kotlinpoet", version = "1.14.2" }
+kotlinPoetJavaPoet = { module = "com.squareup:kotlinpoet-javapoet", version = "1.14.2" }
 kotlinXHtml = { module = "org.jetbrains.kotlinx:kotlinx-html-jvm", version = "0.7.3" }
 ksp = { module = "com.google.devtools.ksp:symbol-processing", version.ref = "ksp" }
 kspApi = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 1a0a755..e094844 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -405,6 +405,7 @@
          </trusted-key>
          <trusted-key id="db0597e3144342256bc81e3ec727d053c4481cf5" group="org.tensorflow"/>
          <trusted-key id="dbd744ace7ade6aa50dd591f66b50994442d2d40">
+            <trusting group="com.squareup"/>
             <trusting group="com.squareup.okhttp3"/>
             <trusting group="com.squareup.okio"/>
             <trusting group="com.squareup.wire"/>
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/BatchingMode.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/BatchingMode.kt
index fa9ea16..b61a875 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/BatchingMode.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/BatchingMode.kt
@@ -37,13 +37,15 @@
 
     public companion object {
         /**
-         * Batching mode for receiving [DataType.HEART_RATE_BPM] updates with fast frequency.
+         * Deliver smaller and more frequent batches of [DataType.HEART_RATE_BPM] when the device is
+         * not interactive (e.g. screen is off).
          *
-         * Note: This mode will cause significantly increased power consumption compared to the
-         * default batching mode, while still being more power efficient than streaming when in
-         * non-interactive state. The exact power/performance tradeoff of this mode is device
-         * implementation dependent and batched updates may be aligned with other wake ups but
-         * target five second updates.
+         * This setting significantly increases power consumption, and is intended to be used by
+         * apps which need to send data to a separate device (e.g. a connected phone or TV) for
+         * real-time visualisation. It has no effect if the device is interactive.
+         *
+         * The exact power/performance tradeoff of this mode is device implementation dependent and
+         * batched updates may be aligned with other wake ups but target five second updates.
          */
         @JvmField public val HEART_RATE_5_SECONDS: BatchingMode = BatchingMode(1)
 
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseCapabilitiesTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseCapabilitiesTest.kt
index 4a43798..2d2bf7e 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseCapabilitiesTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseCapabilitiesTest.kt
@@ -31,8 +31,8 @@
             EXERCISE_CAPABILITIES.getExerciseTypeCapabilities(
                 ExerciseType.WALKING
             ).supportedDataTypes
-        ).isEqualTo(
-            ImmutableSet.of(DataType.STEPS)
+        ).containsExactly(
+            DataType.STEPS
         )
     }
 
@@ -93,6 +93,9 @@
         assertThat(capabilities.autoPauseAndResumeEnabledExercises).containsExactlyElementsIn(
             EXERCISE_CAPABILITIES.autoPauseAndResumeEnabledExercises
         )
+        assertThat(capabilities.supportedBatchingModeOverrides).containsExactlyElementsIn(
+            EXERCISE_CAPABILITIES.supportedBatchingModeOverrides
+        )
     }
 
     @Test
@@ -106,6 +109,9 @@
         assertThat(emptyCapabilities.autoPauseAndResumeEnabledExercises).containsExactlyElementsIn(
             roundTripEmptyCapabilities.autoPauseAndResumeEnabledExercises
         )
+        assertThat(emptyCapabilities.supportedBatchingModeOverrides).containsExactlyElementsIn(
+            roundTripEmptyCapabilities.supportedBatchingModeOverrides
+        )
     }
 
     companion object {
@@ -153,6 +159,7 @@
             )
 
         private val EXERCISE_CAPABILITIES: ExerciseCapabilities =
-            ExerciseCapabilities(EXERCISE_TYPE_TO_EXERCISE_CAPABILITIES_MAPPING)
+            ExerciseCapabilities(EXERCISE_TYPE_TO_EXERCISE_CAPABILITIES_MAPPING,
+                ImmutableSet.of(BatchingMode.HEART_RATE_5_SECONDS))
     }
 }
diff --git a/hilt/hilt-compiler/build.gradle b/hilt/hilt-compiler/build.gradle
index 2418bf7..aec41ba 100644
--- a/hilt/hilt-compiler/build.gradle
+++ b/hilt/hilt-compiler/build.gradle
@@ -39,7 +39,7 @@
     testImplementation(project(":hilt:hilt-common"))
     testImplementation(project(":annotation:annotation"))
     testImplementation(libs.junit)
-    testImplementation(project(":kruth:kruth"))
+    testImplementation(libs.truth)
     testImplementation(project(":room:room-compiler-processing-testing"))
     testImplementation(libs.hiltCore)
     testImplementationAarAsJar(project(":hilt:hilt-work"))
diff --git a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/AGPExtensions.kt b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/AGPExtensions.kt
index 6d6a8e6..520e21d7 100644
--- a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/AGPExtensions.kt
+++ b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/AGPExtensions.kt
@@ -20,6 +20,8 @@
 import java.io.File
 import java.util.Locale
 import org.gradle.api.Project
+import org.gradle.api.file.Directory
+import org.gradle.api.provider.Provider
 
 internal fun Variant.taskName(baseName: String) =
     "$baseName${name.replaceFirstChar(Char::titlecase)}"
@@ -27,9 +29,8 @@
 internal fun Project.taskWorkingDir(
     variant: Variant,
     baseName: String
-): File {
-    val inspectionDir = File(project.buildDir, "androidx_inspection")
-    return File(File(inspectionDir, baseName), variant.name)
+): Provider<Directory> {
+    return layout.buildDirectory.dir("androidx_inspection/$baseName/${variant.name}")
 }
 
 // Functions below will be removed once registerGenerateProguardDetectionFileTask is migrated
diff --git a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/DexInspectorTask.kt b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/DexInspectorTask.kt
index 7d95e6b..e8edc46 100644
--- a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/DexInspectorTask.kt
+++ b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/DexInspectorTask.kt
@@ -128,7 +128,8 @@
 ): TaskProvider<Copy> {
     return tasks.register(variant.taskName("unpackInspectorAAR"), Copy::class.java) {
         it.from(zipTree(variant.artifacts.get(SingleArtifact.AAR)))
-        it.destinationDir = taskWorkingDir(variant, "unpackedInspectorAAR")
+        // Remove .get().asFile once https://github.com/gradle/gradle/issues/25824 is fixed
+        it.destinationDir = taskWorkingDir(variant, "unpackedInspectorAAR").get().asFile
     }
 }
 
@@ -139,15 +140,14 @@
     jar: TaskProvider<out Jar>
 ): TaskProvider<Zip> {
     val name = jarName ?: "${project.name}.jar"
-    val out = File(taskWorkingDir(variant, "dexedInspector"), name)
+    val output = taskWorkingDir(variant, "dexedInspector").map { it.file(name) }
 
     val dex = tasks.register(variant.taskName("dexInspector"), DexInspectorTask::class.java) {
         it.minSdkVersion = extension.defaultConfig.minSdk!!
         it.setD8(extension.sdkDirectory, extension.buildToolsVersion)
         it.setAndroidJar(extension.sdkDirectory, extension.compileSdkVersion!!)
         it.jars.from(jar.get().archiveFile)
-        it.outputFile.set(out)
-        @Suppress("UnstableApiUsage")
+        it.outputFile.set(output)
         it.compileClasspath.from(
             variant.compileConfiguration.incoming.artifactView {
                 it.attributes {
@@ -163,11 +163,10 @@
 
     return tasks.register(variant.taskName("assembleInspectorJar"), Zip::class.java) {
         it.from(zipTree(jar.map { it.archiveFile }))
-        it.from(zipTree(out))
+        it.from(dex.map { zipTree(it.outputFile) })
         it.exclude("**/*.class")
         it.archiveFileName.set(name)
         it.destinationDirectory.set(taskWorkingDir(variant, "assembleInspectorJar"))
-        it.dependsOn(dex)
         it.includeEmptyDirs = false
     }
 }
diff --git a/libraryversions.toml b/libraryversions.toml
index 0e4ded9..19c0a44 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -59,7 +59,7 @@
 EXIFINTERFACE = "1.4.0-alpha01"
 FRAGMENT = "1.7.0-alpha02"
 FUTURES = "1.2.0-alpha02"
-GLANCE = "1.0.0-rc01"
+GLANCE = "1.1.0-alpha01"
 GLANCE_PREVIEW = "1.0.0-alpha06"
 GLANCE_TEMPLATE = "1.0.0-alpha06"
 GLANCE_WEAR_TILES = "1.0.0-alpha06"
diff --git a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinNavWriter.kt b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinNavWriter.kt
index e2a61cc..b1021c3 100644
--- a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinNavWriter.kt
+++ b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinNavWriter.kt
@@ -128,11 +128,16 @@
         val className = ClassName("", action.id.javaIdentifier.toCamelCase())
 
         val actionIdPropSpec =
-            PropertySpec.builder("actionId", Int::class, KModifier.OVERRIDE)
+            PropertySpec.builder("actionId", Int::class, KModifier.PUBLIC, KModifier.OVERRIDE)
                 .initializer("%L", action.id.accessor()).build()
 
         val argumentsPropSpec =
-            PropertySpec.builder("arguments", BUNDLE_CLASSNAME, KModifier.OVERRIDE)
+            PropertySpec.builder(
+                "arguments",
+                BUNDLE_CLASSNAME,
+                KModifier.PUBLIC,
+                KModifier.OVERRIDE
+            )
                 .getter(
                     FunSpec.getterBuilder().apply {
                         if (action.args.any { it.type is ObjectType }) {
diff --git a/privacysandbox/ads/ads-adservices-java/api/current.txt b/privacysandbox/ads/ads-adservices-java/api/current.txt
index 26eea8b..18004f9 100644
--- a/privacysandbox/ads/ads-adservices-java/api/current.txt
+++ b/privacysandbox/ads/ads-adservices-java/api/current.txt
@@ -64,6 +64,7 @@
     method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @SuppressCompatibility @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) @androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures.RegisterSourceOptIn public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest request);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
diff --git a/privacysandbox/ads/ads-adservices-java/api/restricted_current.txt b/privacysandbox/ads/ads-adservices-java/api/restricted_current.txt
index 26eea8b..18004f9 100644
--- a/privacysandbox/ads/ads-adservices-java/api/restricted_current.txt
+++ b/privacysandbox/ads/ads-adservices-java/api/restricted_current.txt
@@ -64,6 +64,7 @@
     method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @SuppressCompatibility @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) @androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures.RegisterSourceOptIn public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest request);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
diff --git a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/measurement/MeasurementManagerTest.java b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/measurement/MeasurementManagerTest.java
index 6a657ad4..7bc4ea9 100644
--- a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/measurement/MeasurementManagerTest.java
+++ b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/endtoend/measurement/MeasurementManagerTest.java
@@ -26,6 +26,7 @@
 import androidx.privacysandbox.ads.adservices.java.endtoend.TestUtil;
 import androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures;
 import androidx.privacysandbox.ads.adservices.measurement.DeletionRequest;
+import androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest;
 import androidx.privacysandbox.ads.adservices.measurement.WebSourceParams;
 import androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest;
 import androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams;
@@ -107,6 +108,19 @@
     }
 
     @Test
+    public void testRegisterAppSources_NoServerSetup_NoErrors() throws Exception {
+        // Skip the test if SDK extension 5 is not present.
+        Assume.assumeTrue(AdServicesInfo.INSTANCE.version() >= 5);
+
+        SourceRegistrationRequest request =
+                new SourceRegistrationRequest.Builder(
+                        Collections.singletonList(SOURCE_REGISTRATION_URI))
+                        .build();
+        assertThat(mMeasurementManager.registerSourceAsync(request).get())
+                .isNotNull();
+    }
+
+    @Test
     public void testRegisterTrigger_NoServerSetup_NoErrors() throws Exception {
         // Skip the test if SDK extension 5 is not present.
         Assume.assumeTrue(AdServicesInfo.INSTANCE.version() >= 5);
diff --git a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFuturesTest.kt b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFuturesTest.kt
index 6e1752b..0bec6eb 100644
--- a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFuturesTest.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFuturesTest.kt
@@ -24,8 +24,10 @@
 import android.os.ext.SdkExtensions
 import android.view.InputEvent
 import androidx.annotation.RequiresExtension
+import androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures
 import androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures.Companion.from
 import androidx.privacysandbox.ads.adservices.measurement.DeletionRequest
+import androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest
 import androidx.privacysandbox.ads.adservices.measurement.WebSourceParams
 import androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest
 import androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams
@@ -36,13 +38,23 @@
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import java.time.Instant
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.Executor
 import kotlin.test.assertNotEquals
+import kotlin.test.assertTrue
+import kotlin.test.fail
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
 import org.junit.Assume
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.atMost
 import org.mockito.Mockito.doAnswer
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.spy
@@ -278,6 +290,112 @@
         assertThat(result.get() == state)
     }
 
+    @ExperimentalFeatures.RegisterSourceOptIn
+    @Test
+    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+    fun testRegisterSourceAsync_allSuccess() {
+        val sdkExtVersion = SdkExtensions.getExtensionVersion(SdkExtensions.AD_SERVICES)
+
+        Assume.assumeTrue("minSdkVersion = API 33 ext 5", sdkExtVersion >= 5)
+        val inputEvent = mock(InputEvent::class.java)
+        val measurementManager = mockMeasurementManager(mContext)
+        val managerCompat = from(mContext)
+        val successCallback = { args: InvocationOnMock ->
+            assertNotEquals(Looper.myLooper(), Looper.getMainLooper())
+            val receiver = args.getArgument<OutcomeReceiver<Any, Exception>>(3)
+            receiver.onResult(Object())
+            null
+        }
+        doAnswer(successCallback).`when`(measurementManager)
+            .registerSource(any(), any(), any(), any())
+
+        // Actually invoke the compat code.
+        val request = SourceRegistrationRequest.Builder(listOf(uri1, uri2))
+            .setInputEvent(inputEvent)
+            .build()
+        managerCompat!!.registerSourceAsync(request).get()
+
+        // Verify that the compat code was invoked correctly.
+        verify(measurementManager).registerSource(
+            eq(uri1),
+            eq(inputEvent),
+            any(Executor::class.java),
+            any())
+        verify(measurementManager).registerSource(
+            eq(uri2),
+            eq(inputEvent),
+            any(Executor::class.java),
+            any())
+    }
+
+    @ExperimentalFeatures.RegisterSourceOptIn
+    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+    @Test
+    fun testRegisterSource_15thOf20Fails_atLeast15thExecutes() {
+        val sdkExtVersion = SdkExtensions.getExtensionVersion(SdkExtensions.AD_SERVICES)
+
+        Assume.assumeTrue("minSdkVersion = API 33 ext 5", sdkExtVersion >= 5)
+        val measurementManager = mockMeasurementManager(mContext)
+        val mockInputEvent = mock(InputEvent::class.java)
+        val managerCompat = from(mContext)
+        val successCallback = { args: InvocationOnMock ->
+            val receiver = args.getArgument<OutcomeReceiver<Any, Exception>>(3)
+            receiver.onResult(Object())
+            null
+        }
+
+        val errorMessage = "some error occurred"
+        val errorCallback = { args: InvocationOnMock ->
+            val receiver = args.getArgument<OutcomeReceiver<Any, Exception>>(3)
+            receiver.onError(IllegalArgumentException(errorMessage))
+            null
+        }
+
+        val uris = (0..20).map { i ->
+            val uri = Uri.parse("www.uri$i.com")
+            if (i == 15) {
+                doAnswer(errorCallback).`when`(measurementManager)
+                    .registerSource(eq(uri), any(), any(), any())
+            } else {
+                doAnswer(successCallback).`when`(measurementManager)
+                    .registerSource(eq(uri), any(), any(), any())
+            }
+            uri
+        }.toList()
+
+        val request = SourceRegistrationRequest(uris, mockInputEvent)
+
+        // Actually invoke the compat code.
+        runBlocking {
+            try {
+                withContext(Dispatchers.Main) {
+                    managerCompat!!.registerSourceAsync(request).get()
+                }
+                fail("Expected failure.")
+            } catch (e: ExecutionException) {
+                assertTrue(e.cause!! is IllegalArgumentException)
+                assertThat(e.cause!!.message).isEqualTo(errorMessage)
+            }
+        }
+
+        // Verify that the compat code was invoked correctly.
+        // registerSource gets called 1-20 times. We cannot predict the exact number because
+        // uri15 would crash asynchronously. Other uris may succeed and those threads on default
+        // dispatcher won't crash.
+        verify(measurementManager, atLeastOnce()).registerSource(
+            any(),
+            eq(mockInputEvent),
+            any(),
+            any()
+        )
+        verify(measurementManager, atMost(20)).registerSource(
+            any(),
+            eq(mockInputEvent),
+            any(),
+            any()
+        )
+    }
+
     @SdkSuppress(minSdkVersion = 30)
     @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
     companion object {
diff --git a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFutures.kt b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFutures.kt
index b04eb21..e6c5487 100644
--- a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFutures.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/measurement/MeasurementManagerFutures.kt
@@ -22,10 +22,12 @@
 import android.view.InputEvent
 import androidx.annotation.DoNotInline
 import androidx.annotation.RequiresPermission
+import androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures
 import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
 import androidx.privacysandbox.ads.adservices.measurement.DeletionRequest
 import androidx.privacysandbox.ads.adservices.measurement.MeasurementManager
 import androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion.obtain
+import androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest
 import androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest
 import androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest
 import com.google.common.util.concurrent.ListenableFuture
@@ -75,6 +77,19 @@
     abstract fun registerTriggerAsync(trigger: Uri): ListenableFuture<Unit>
 
     /**
+     * Register attribution sources(click or view). This API will not process any redirects, all
+     * registration URLs should be supplied with the request.
+     *
+     * @param request source registration request
+     */
+    @ExperimentalFeatures.RegisterSourceOptIn
+    @SuppressWarnings("MissingNullability")
+    @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION)
+    abstract fun registerSourceAsync(
+        request: SourceRegistrationRequest
+    ): ListenableFuture<Unit>
+
+    /**
      * Register an attribution source(click or view) from web context. This API will not process any
      * redirects, all registration URLs should be supplied with the request. At least one of
      * appDestination or webDestination parameters are required to be provided.
@@ -135,6 +150,17 @@
         }
 
         @DoNotInline
+        @ExperimentalFeatures.RegisterSourceOptIn
+        @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION)
+        override fun registerSourceAsync(
+            request: SourceRegistrationRequest
+        ): ListenableFuture<Unit> {
+            return CoroutineScope(Dispatchers.Default).async {
+                mMeasurementManager.registerSource(request)
+            }.asListenableFuture()
+        }
+
+        @DoNotInline
         @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION)
         override fun registerTriggerAsync(trigger: Uri): ListenableFuture<Unit> {
             return CoroutineScope(Dispatchers.Default).async {
diff --git a/privacysandbox/ads/ads-adservices/api/current.txt b/privacysandbox/ads/ads-adservices/api/current.txt
index 839dec6..6a4905b 100644
--- a/privacysandbox/ads/ads-adservices/api/current.txt
+++ b/privacysandbox/ads/ads-adservices/api/current.txt
@@ -126,6 +126,12 @@
     property public final String identifier;
   }
 
+  public sealed interface ExperimentalFeatures {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental.", level=kotlin.RequiresOptIn.Level.WARNING) public static @interface ExperimentalFeatures.RegisterSourceOptIn {
+  }
+
 }
 
 package androidx.privacysandbox.ads.adservices.customaudience {
@@ -249,6 +255,7 @@
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
     method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @SuppressCompatibility @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) @androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures.RegisterSourceOptIn public abstract suspend Object? registerSource(androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -261,6 +268,20 @@
     method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
   }
 
+  @SuppressCompatibility @androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures.RegisterSourceOptIn public final class SourceRegistrationRequest {
+    ctor public SourceRegistrationRequest(java.util.List<? extends android.net.Uri> registrationUris, optional android.view.InputEvent? inputEvent);
+    method public android.view.InputEvent? getInputEvent();
+    method public java.util.List<android.net.Uri> getRegistrationUris();
+    property public final android.view.InputEvent? inputEvent;
+    property public final java.util.List<android.net.Uri> registrationUris;
+  }
+
+  public static final class SourceRegistrationRequest.Builder {
+    ctor public SourceRegistrationRequest.Builder(java.util.List<? extends android.net.Uri> registrationUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+  }
+
   @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
     ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
     method public boolean getDebugKeyAllowed();
diff --git a/privacysandbox/ads/ads-adservices/api/restricted_current.txt b/privacysandbox/ads/ads-adservices/api/restricted_current.txt
index 839dec6..6a4905b 100644
--- a/privacysandbox/ads/ads-adservices/api/restricted_current.txt
+++ b/privacysandbox/ads/ads-adservices/api/restricted_current.txt
@@ -126,6 +126,12 @@
     property public final String identifier;
   }
 
+  public sealed interface ExperimentalFeatures {
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental.", level=kotlin.RequiresOptIn.Level.WARNING) public static @interface ExperimentalFeatures.RegisterSourceOptIn {
+  }
+
 }
 
 package androidx.privacysandbox.ads.adservices.customaudience {
@@ -249,6 +255,7 @@
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
     method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @SuppressCompatibility @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) @androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures.RegisterSourceOptIn public abstract suspend Object? registerSource(androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -261,6 +268,20 @@
     method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
   }
 
+  @SuppressCompatibility @androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures.RegisterSourceOptIn public final class SourceRegistrationRequest {
+    ctor public SourceRegistrationRequest(java.util.List<? extends android.net.Uri> registrationUris, optional android.view.InputEvent? inputEvent);
+    method public android.view.InputEvent? getInputEvent();
+    method public java.util.List<android.net.Uri> getRegistrationUris();
+    property public final android.view.InputEvent? inputEvent;
+    property public final java.util.List<android.net.Uri> registrationUris;
+  }
+
+  public static final class SourceRegistrationRequest.Builder {
+    ctor public SourceRegistrationRequest.Builder(java.util.List<? extends android.net.Uri> registrationUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.SourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+  }
+
   @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
     ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
     method public boolean getDebugKeyAllowed();
diff --git a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManagerTest.kt b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManagerTest.kt
index 191e2d8..1e0a826 100644
--- a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManagerTest.kt
+++ b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManagerTest.kt
@@ -23,13 +23,16 @@
 import android.os.ext.SdkExtensions
 import android.view.InputEvent
 import androidx.annotation.RequiresExtension
+import androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures
 import androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion.obtain
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
+import androidx.testutils.fail
 import com.google.common.truth.Truth.assertThat
 import java.time.Instant
+import kotlin.IllegalArgumentException
 import kotlinx.coroutines.runBlocking
 import org.junit.Assume
 import org.junit.Before
@@ -37,9 +40,12 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mockito.doAnswer
 import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.invocation.InvocationOnMock
@@ -211,6 +217,105 @@
         assertThat(!actualRequest.sourceParams[0].isDebugKeyAllowed)
     }
 
+    @ExperimentalFeatures.RegisterSourceOptIn
+    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+    @Test
+    fun testRegisterSource_allSuccess() {
+        val sdkExtVersion = SdkExtensions.getExtensionVersion(SdkExtensions.AD_SERVICES)
+
+        Assume.assumeTrue("minSdkVersion = API 33 ext 5", sdkExtVersion >= 5)
+        val measurementManager = mockMeasurementManager(mContext)
+        val mockInputEvent = mock(InputEvent::class.java)
+        val managerCompat = obtain(mContext)
+        val successCallback = { args: InvocationOnMock ->
+            val receiver = args.getArgument<OutcomeReceiver<Any, Exception>>(3)
+            receiver.onResult(Object())
+            null
+        }
+        doAnswer(successCallback).`when`(measurementManager)
+            .registerSource(any(), any(), any(), any())
+
+        val request = SourceRegistrationRequest(listOf(uri1, uri2), mockInputEvent)
+
+        // Actually invoke the compat code.
+        runBlocking {
+            managerCompat!!.registerSource(request)
+        }
+
+        // Verify that the compat code was invoked correctly.
+        verify(measurementManager, times(2)).registerSource(
+            any(),
+            eq(mockInputEvent),
+            any(),
+            any()
+        )
+    }
+
+    @ExperimentalFeatures.RegisterSourceOptIn
+    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+    @Test
+    fun testRegisterSource_15thOf20Fails_remaining5DoNotExecute() {
+        val sdkExtVersion = SdkExtensions.getExtensionVersion(SdkExtensions.AD_SERVICES)
+
+        Assume.assumeTrue("minSdkVersion = API 33 ext 5", sdkExtVersion >= 5)
+        val measurementManager = mockMeasurementManager(mContext)
+        val mockInputEvent = mock(InputEvent::class.java)
+        val managerCompat = obtain(mContext)
+        val successCallback = { args: InvocationOnMock ->
+            val receiver = args.getArgument<OutcomeReceiver<Any, Exception>>(3)
+            receiver.onResult(Object())
+            null
+        }
+
+        val errorMessage = "some error occurred"
+        val errorCallback = { args: InvocationOnMock ->
+            val receiver = args.getArgument<OutcomeReceiver<Any, Exception>>(3)
+            receiver.onError(IllegalArgumentException(errorMessage))
+            null
+        }
+        val uris = (0..20).map { i ->
+            val uri = Uri.parse("www.uri$i.com")
+            if (i == 15) {
+                doAnswer(errorCallback).`when`(measurementManager)
+                    .registerSource(eq(uri), any(), any(), any())
+            } else {
+                doAnswer(successCallback).`when`(measurementManager)
+                    .registerSource(eq(uri), any(), any(), any())
+            }
+            uri
+        }.toList()
+
+        val request = SourceRegistrationRequest(uris, mockInputEvent)
+
+        // Actually invoke the compat code.
+        runBlocking {
+            try {
+                managerCompat!!.registerSource(request)
+                fail("Expected failure.")
+            } catch (e: IllegalArgumentException) {
+                assertThat(e.message).isEqualTo(errorMessage)
+            }
+        }
+
+        // Verify that the compat code was invoked correctly.
+        (0..15).forEach { i ->
+            verify(measurementManager).registerSource(
+                eq(Uri.parse("www.uri$i.com")),
+                eq(mockInputEvent),
+                any(),
+                any()
+            )
+        }
+        (16..20).forEach { i ->
+            verify(measurementManager, never()).registerSource(
+                eq(Uri.parse("www.uri$i.com")),
+                eq(mockInputEvent),
+                any(),
+                any()
+            )
+        }
+    }
+
     @Test
     @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
     fun testRegisterWebTrigger() {
diff --git a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/measurement/SourceRegistrationRequestTest.kt b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/measurement/SourceRegistrationRequestTest.kt
new file mode 100644
index 0000000..cff885a
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/measurement/SourceRegistrationRequestTest.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.privacysandbox.ads.adservices.measurement
+
+import android.net.Uri
+import android.view.InputEvent
+import androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures
+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.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+
+@ExperimentalFeatures.RegisterSourceOptIn
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 33)
+class SourceRegistrationRequestTest {
+    @Test
+    fun testToString() {
+        val result = "AppSourcesRegistrationRequest { RegistrationUris=" +
+            "[[www.abc.com, www.xyz.com]], InputEvent=null }"
+
+        val uri1 = Uri.parse("www.abc.com")
+        val uri2 = Uri.parse("www.xyz.com")
+        val params = listOf(uri1, uri2)
+        val request = SourceRegistrationRequest.Builder(params).build()
+        Truth.assertThat(request.toString()).isEqualTo(result)
+    }
+
+    @Test
+    fun testEquals() {
+        val uri1 = Uri.parse("www.abc.com")
+        val uri2 = Uri.parse("www.xyz.com")
+        val params = listOf(uri1, uri2)
+        val inputEvent = mock(InputEvent::class.java)
+        val request1 = SourceRegistrationRequest.Builder(params)
+            .setInputEvent(inputEvent)
+            .build()
+        val request2 = SourceRegistrationRequest(params, inputEvent)
+        val request3 = SourceRegistrationRequest.Builder(params).build()
+
+        Truth.assertThat(request1 == request2).isTrue()
+        Truth.assertThat(request1 != request3).isTrue()
+    }
+}
diff --git a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequestTest.kt b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequestTest.kt
index e76c23e..70cd0c4 100644
--- a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequestTest.kt
+++ b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequestTest.kt
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import androidx.testutils.assertThrows
 import com.google.common.truth.Truth
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -41,4 +42,30 @@
         // Verify equality.
         Truth.assertThat(request == request2).isTrue()
     }
+
+    @Test
+    fun testToString_emptySdkName() {
+        val result = "GetTopicsRequest: adsSdkName=, shouldRecordObservation=true"
+        val request = GetTopicsRequest("", true)
+        Truth.assertThat(request.toString()).isEqualTo(result)
+
+        // Verify Builder.
+        val request2 = GetTopicsRequest.Builder()
+            .setShouldRecordObservation(true)
+            .build()
+        Truth.assertThat(request.toString()).isEqualTo(result)
+
+        // Verify equality.
+        Truth.assertThat(request == request2).isTrue()
+    }
+
+    @Test
+    fun testBuilder_setEmptyAdsSdkName_throwsError() {
+        assertThrows(IllegalStateException::class.java) {
+            GetTopicsRequest.Builder()
+                .setAdsSdkName("")
+                .setShouldRecordObservation(true)
+                .build()
+        }
+    }
 }
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/common/ExperimentalFeatures.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/common/ExperimentalFeatures.kt
new file mode 100644
index 0000000..e1935b3
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/common/ExperimentalFeatures.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.privacysandbox.ads.adservices.common
+
+/**
+ * Contains AdServices experimental feature opt-in anntations.
+ */
+sealed interface ExperimentalFeatures {
+    /**
+     * Clients should use it when they want to use [MeasurementManager#registerSource] API.
+     */
+    @RequiresOptIn("This API is experimental.", RequiresOptIn.Level.WARNING)
+    annotation class RegisterSourceOptIn
+}
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManager.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManager.kt
index e316ab0..de62bd2 100644
--- a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManager.kt
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/measurement/MeasurementManager.kt
@@ -27,7 +27,10 @@
 import androidx.annotation.RequiresExtension
 import androidx.annotation.RequiresPermission
 import androidx.core.os.asOutcomeReceiver
+import androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures
 import androidx.privacysandbox.ads.adservices.internal.AdServicesInfo
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.suspendCancellableCoroutine
 
 /**
@@ -82,6 +85,16 @@
     abstract suspend fun registerWebTrigger(request: WebTriggerRegistrationRequest)
 
     /**
+     * Register an attribution source(click or view) context. This API will not process any
+     * redirects, all registration URLs should be supplied with the request.
+     *
+     * @param request source registration request
+     */
+    @RequiresPermission(ACCESS_ADSERVICES_ATTRIBUTION)
+    @ExperimentalFeatures.RegisterSourceOptIn
+    abstract suspend fun registerSource(request: SourceRegistrationRequest)
+
+    /**
      * Get Measurement API status.
      *
      * The call returns an integer value (see [MEASUREMENT_API_STATE_DISABLED] and
@@ -160,6 +173,26 @@
             }
         }
 
+        @DoNotInline
+        @ExperimentalFeatures.RegisterSourceOptIn
+        @RequiresPermission(ACCESS_ADSERVICES_ATTRIBUTION)
+        override suspend fun registerSource(
+            request: SourceRegistrationRequest
+        ): Unit = coroutineScope {
+            request.registrationUris.forEach { uri ->
+                launch {
+                    suspendCancellableCoroutine<Any> { continuation ->
+                        mMeasurementManager.registerSource(
+                            uri,
+                            request.inputEvent,
+                            Runnable::run,
+                            continuation.asOutcomeReceiver()
+                        )
+                    }
+                }
+            }
+        }
+
         private fun convertWebSourceRequest(
             request: WebSourceRegistrationRequest
         ): android.adservices.measurement.WebSourceRegistrationRequest {
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/measurement/SourceRegistrationRequest.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/measurement/SourceRegistrationRequest.kt
new file mode 100644
index 0000000..7bda8bf
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/measurement/SourceRegistrationRequest.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.privacysandbox.ads.adservices.measurement
+
+import android.net.Uri
+import android.view.InputEvent
+import androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures
+
+/**
+ * Class to hold input to measurement source registration calls from web context.
+ *
+ * @param registrationUris [List] of Registration [Uri]s to fetch sources.
+ * @param inputEvent User Interaction [InputEvent] used by the AttributionReporting API to
+ * distinguish clicks from views.
+ */
+@ExperimentalFeatures.RegisterSourceOptIn
+class SourceRegistrationRequest constructor(
+    val registrationUris: List<Uri>,
+    val inputEvent: InputEvent? = null
+    ) {
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is SourceRegistrationRequest) return false
+        return this.registrationUris == other.registrationUris &&
+            this.inputEvent == other.inputEvent
+    }
+
+    override fun hashCode(): Int {
+        var hash = registrationUris.hashCode()
+        if (inputEvent != null) {
+            hash = 31 * hash + inputEvent.hashCode()
+        }
+        return hash
+    }
+
+    override fun toString(): String {
+        val vals = "RegistrationUris=[$registrationUris], InputEvent=$inputEvent"
+        return "AppSourcesRegistrationRequest { $vals }"
+    }
+
+    /**
+     * Builder for [SourceRegistrationRequest].
+     *
+     * @param registrationUris source registration request [Uri]
+     */
+    class Builder(
+        private val registrationUris: List<Uri>
+    ) {
+        private var inputEvent: InputEvent? = null
+
+        /**
+         * Setter for input event.
+         *
+         * @param inputEvent User Interaction InputEvent used by the AttributionReporting API to
+         *     distinguish clicks from views.
+         * @return builder
+         */
+        fun setInputEvent(inputEvent: InputEvent): Builder = apply {
+            this.inputEvent = inputEvent
+        }
+
+        /** Pre-validates parameters and builds [SourceRegistrationRequest]. */
+        fun build(): SourceRegistrationRequest {
+            return SourceRegistrationRequest(
+                registrationUris,
+                inputEvent
+            )
+        }
+    }
+}
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequest.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequest.kt
index d8f4a81..6dede0c 100644
--- a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequest.kt
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/topics/GetTopicsRequest.kt
@@ -64,7 +64,10 @@
          *
          * @param adsSdkName the Ads Sdk Name.
          */
-        fun setAdsSdkName(adsSdkName: String): Builder = apply { this.adsSdkName = adsSdkName }
+        fun setAdsSdkName(adsSdkName: String): Builder = apply {
+            check(adsSdkName.isNotEmpty()) { "adsSdkName must be set" }
+            this.adsSdkName = adsSdkName
+        }
 
         /**
          * Set the Record Observation.
@@ -80,7 +83,6 @@
 
         /** Builds a [GetTopicsRequest] instance. */
         fun build(): GetTopicsRequest {
-            check(adsSdkName.isNotEmpty()) { "adsSdkName must be set" }
             return GetTopicsRequest(adsSdkName, shouldRecordObservation)
         }
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/AbstractSdkProviderGenerator.kt b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/AbstractSdkProviderGenerator.kt
index 540f146..21bb582 100644
--- a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/AbstractSdkProviderGenerator.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/AbstractSdkProviderGenerator.kt
@@ -61,7 +61,7 @@
 
     private fun generateGetViewFunction(): FunSpec {
         return FunSpec.builder("getView").build {
-            addModifiers(KModifier.OVERRIDE)
+            addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
             addParameter("windowContext", contextClass)
             addParameter("params", bundleClass)
             addParameter("width", Int::class)
diff --git a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/Api33SdkProviderGenerator.kt b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/Api33SdkProviderGenerator.kt
index 5639123..f4c9aef 100644
--- a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/Api33SdkProviderGenerator.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/Api33SdkProviderGenerator.kt
@@ -40,7 +40,7 @@
         ClassName("android.app.sdksandbox", "SandboxedSdkProvider")
 
     override fun generateOnLoadSdkFunction() = FunSpec.builder("onLoadSdk").build {
-        addModifiers(KModifier.OVERRIDE)
+        addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
         addParameter("params", bundleClass)
         returns(sandboxedSdkClass)
 
diff --git a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/CompatSdkProviderGenerator.kt b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/CompatSdkProviderGenerator.kt
index 5053460..14bd699 100644
--- a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/CompatSdkProviderGenerator.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/CompatSdkProviderGenerator.kt
@@ -40,7 +40,7 @@
         ClassName("androidx.privacysandbox.sdkruntime.core", "SandboxedSdkProviderCompat")
 
     override fun generateOnLoadSdkFunction() = FunSpec.builder("onLoadSdk").build {
-        addModifiers(KModifier.OVERRIDE)
+        addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
         addParameter("params", bundleClass)
         returns(sandboxedSdkCompatClass)
 
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyCallbackClientProxy.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyCallbackClientProxy.kt
index b471257..af49258 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyCallbackClientProxy.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyCallbackClientProxy.kt
@@ -7,19 +7,19 @@
     public val remote: IMyCallback,
     public val context: Context,
 ) : MyCallback {
-    public override fun onComplete(response: Response): Unit {
+    public override fun onComplete(response: Response) {
         remote.onComplete(ResponseConverter(context).toParcelable(response))
     }
 
-    public override fun onClick(x: Int, y: Int): Unit {
+    public override fun onClick(x: Int, y: Int) {
         remote.onClick(x, y)
     }
 
-    public override fun onCompleteInterface(myInterface: MyInterface): Unit {
+    public override fun onCompleteInterface(myInterface: MyInterface) {
         remote.onCompleteInterface(MyInterfaceStubDelegate(myInterface, context))
     }
 
-    public override fun onCompleteUiInterface(myUiInterface: MyUiInterface): Unit {
+    public override fun onCompleteUiInterface(myUiInterface: MyUiInterface) {
         remote.onCompleteUiInterface(IMyUiInterfaceCoreLibInfoAndBinderWrapperConverter.toParcelable(myUiInterface.toCoreLibInfo(context),
                 MyUiInterfaceStubDelegate(myUiInterface, context)))
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
index 0f0d2f7..223d580 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
@@ -1,10 +1,8 @@
 package com.mysdk
 
 import android.content.Context
-import com.mysdk.PrivacySandboxThrowableParcelConverter
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Int
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -16,7 +14,7 @@
   private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
 
   public override fun doSomething(request: ParcelableRequest,
-      transactionCallback: IResponseTransactionCallback): Unit {
+      transactionCallback: IResponseTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doSomething(RequestConverter(context).fromParcelable(request))
@@ -31,7 +29,7 @@
   }
 
   public override fun getMyInterface(input: IMyInterface,
-      transactionCallback: IMyInterfaceTransactionCallback): Unit {
+      transactionCallback: IMyInterfaceTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.getMyInterface((input as MyInterfaceStubDelegate).delegate)
@@ -46,7 +44,7 @@
   }
 
   public override fun getMySecondInterface(input: IMySecondInterface,
-      transactionCallback: IMySecondInterfaceTransactionCallback): Unit {
+      transactionCallback: IMySecondInterfaceTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.getMySecondInterface((input as
@@ -61,7 +59,7 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun doMoreStuff(x: Int): Unit {
+  public override fun doMoreStuff(x: Int) {
     coroutineScope.launch {
       delegate.doMoreStuff(x)
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
index b1f2995..3f376f2 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
@@ -3,11 +3,9 @@
 import android.content.Context
 import android.os.Bundle
 import androidx.privacysandbox.ui.provider.toCoreLibInfo
-import com.mysdk.PrivacySandboxThrowableParcelConverter
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Int
 import kotlin.IntArray
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -22,7 +20,7 @@
     x: Int,
     y: Int,
     transactionCallback: IStringTransactionCallback,
-  ): Unit {
+  ) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doStuff(x, y)
@@ -37,7 +35,7 @@
   }
 
   public override fun handleRequest(request: ParcelableRequest,
-      transactionCallback: IResponseTransactionCallback): Unit {
+      transactionCallback: IResponseTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.handleRequest(RequestConverter(context).fromParcelable(request))
@@ -52,7 +50,7 @@
   }
 
   public override fun logRequest(request: ParcelableRequest,
-      transactionCallback: IUnitTransactionCallback): Unit {
+      transactionCallback: IUnitTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         delegate.logRequest(RequestConverter(context).fromParcelable(request))
@@ -66,20 +64,20 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun setListener(listener: IMyCallback): Unit {
+  public override fun setListener(listener: IMyCallback) {
     coroutineScope.launch {
       delegate.setListener(MyCallbackClientProxy(listener, context))
     }
   }
 
-  public override fun doMoreStuff(): Unit {
+  public override fun doMoreStuff() {
     coroutineScope.launch {
       delegate.doMoreStuff()
     }
   }
 
   public override fun getMyInterface(input: IMyInterface,
-      transactionCallback: IMyInterfaceTransactionCallback): Unit {
+      transactionCallback: IMyInterfaceTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.getMyInterface((input as MyInterfaceStubDelegate).delegate)
@@ -93,7 +91,7 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun mutateMySecondInterface(input: IMySecondInterface): Unit {
+  public override fun mutateMySecondInterface(input: IMySecondInterface) {
     coroutineScope.launch {
       delegate.mutateMySecondInterface((input as MySecondInterfaceStubDelegate).delegate)
     }
@@ -103,7 +101,7 @@
     x: IntArray,
     y: IntArray,
     transactionCallback: IListStringTransactionCallback,
-  ): Unit {
+  ) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.handleNullablePrimitives(x.firstOrNull(), y.firstOrNull())
@@ -118,7 +116,7 @@
   }
 
   public override fun handleNullableValues(maybeRequest: ParcelableRequest?,
-      transactionCallback: IResponseTransactionCallback): Unit {
+      transactionCallback: IResponseTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.handleNullableValues(maybeRequest?.let { notNullValue ->
@@ -135,7 +133,7 @@
   }
 
   public override fun handleNullableInterfaces(maybeCallback: IMyCallback?,
-      transactionCallback: IMyInterfaceTransactionCallback): Unit {
+      transactionCallback: IMyInterfaceTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.handleNullableInterfaces(maybeCallback?.let { notNullValue ->
@@ -151,8 +149,7 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun returnUiInterface(transactionCallback: IMyUiInterfaceTransactionCallback):
-      Unit {
+  public override fun returnUiInterface(transactionCallback: IMyUiInterfaceTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.returnUiInterface()
@@ -167,22 +164,20 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun acceptUiInterfaceParam(input: IMyUiInterfaceCoreLibInfoAndBinderWrapper):
-      Unit {
+  public override fun acceptUiInterfaceParam(input: IMyUiInterfaceCoreLibInfoAndBinderWrapper) {
     coroutineScope.launch {
       delegate.acceptUiInterfaceParam((input.binder as MyUiInterfaceStubDelegate).delegate)
     }
   }
 
-  public override fun acceptSdkActivityLauncherParam(activityLauncher: Bundle): Unit {
+  public override fun acceptSdkActivityLauncherParam(activityLauncher: Bundle) {
     coroutineScope.launch {
       delegate.acceptSdkActivityLauncherParam(SdkActivityLauncherAndBinderWrapper(activityLauncher))
     }
   }
 
   public override
-      fun returnSdkActivityLauncher(transactionCallback: ISdkActivityLauncherTransactionCallback):
-      Unit {
+      fun returnSdkActivityLauncher(transactionCallback: ISdkActivityLauncherTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.returnSdkActivityLauncher()
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
index 817f83a..af61158 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
@@ -1,7 +1,6 @@
 package com.mysdk
 
 import android.content.Context
-import com.mysdk.PrivacySandboxThrowableParcelConverter
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Array
 import kotlin.BooleanArray
@@ -11,7 +10,6 @@
 import kotlin.IntArray
 import kotlin.LongArray
 import kotlin.String
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -22,8 +20,7 @@
 ) : IMySecondInterface.Stub() {
   private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
 
-  public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback):
-      Unit {
+  public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doIntStuff(x.toList())
@@ -37,8 +34,7 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun doCharStuff(x: CharArray, transactionCallback: IListCharTransactionCallback):
-      Unit {
+  public override fun doCharStuff(x: CharArray, transactionCallback: IListCharTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doCharStuff(x.toList())
@@ -53,7 +49,7 @@
   }
 
   public override fun doFloatStuff(x: FloatArray,
-      transactionCallback: IListFloatTransactionCallback): Unit {
+      transactionCallback: IListFloatTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doFloatStuff(x.toList())
@@ -67,8 +63,7 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun doLongStuff(x: LongArray, transactionCallback: IListLongTransactionCallback):
-      Unit {
+  public override fun doLongStuff(x: LongArray, transactionCallback: IListLongTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doLongStuff(x.toList())
@@ -83,7 +78,7 @@
   }
 
   public override fun doDoubleStuff(x: DoubleArray,
-      transactionCallback: IListDoubleTransactionCallback): Unit {
+      transactionCallback: IListDoubleTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doDoubleStuff(x.toList())
@@ -98,7 +93,7 @@
   }
 
   public override fun doBooleanStuff(x: BooleanArray,
-      transactionCallback: IListBooleanTransactionCallback): Unit {
+      transactionCallback: IListBooleanTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doBooleanStuff(x.toList())
@@ -112,8 +107,8 @@
     transactionCallback.onCancellable(cancellationSignal)
   }
 
-  public override fun doShortStuff(x: IntArray, transactionCallback: IListShortTransactionCallback):
-      Unit {
+  public override fun doShortStuff(x: IntArray,
+      transactionCallback: IListShortTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doShortStuff(x.map { it.toShort() }.toList())
@@ -128,7 +123,7 @@
   }
 
   public override fun doStringStuff(x: Array<String>,
-      transactionCallback: IListStringTransactionCallback): Unit {
+      transactionCallback: IListStringTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doStringStuff(x.toList())
@@ -143,7 +138,7 @@
   }
 
   public override fun doValueStuff(x: Array<ParcelableRequest>,
-      transactionCallback: IListResponseTransactionCallback): Unit {
+      transactionCallback: IListResponseTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doValueStuff(x.map { RequestConverter(context).fromParcelable(it)
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
index b234751..747598f 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
@@ -2,7 +2,6 @@
 
 import android.content.Context
 import kotlin.Int
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -13,7 +12,7 @@
 ) : IMyUiInterface.Stub() {
   private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
 
-  public override fun doSomethingForUi(x: Int, y: Int): Unit {
+  public override fun doSomethingForUi(x: Int, y: Int) {
     coroutineScope.launch {
       delegate.doSomethingForUi(x, y)
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/TransportCancellationCallback.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/TransportCancellationCallback.kt
index 287dc52..ba1815c 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/TransportCancellationCallback.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/TransportCancellationCallback.kt
@@ -8,7 +8,7 @@
 ) : ICancellationSignal.Stub() {
   private val hasCancelled: AtomicBoolean = AtomicBoolean(false)
 
-  public override fun cancel(): Unit {
+  public override fun cancel() {
     if (hasCancelled.compareAndSet(false, true)) {
       onCancel()
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
index 594b8e3..ad1f00a 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
@@ -5,7 +5,6 @@
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import com.mysdk.TransportCancellationCallback
 import kotlin.Int
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -16,14 +15,14 @@
 ) : IMyOtherPackageInterface.Stub() {
   private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
 
-  public override fun doStuff(x: Int): Unit {
+  public override fun doStuff(x: Int) {
     coroutineScope.launch {
       delegate.doStuff(x)
     }
   }
 
   public override fun useDataClass(x: ParcelableMyOtherPackageDataClass,
-      transactionCallback: IUnitTransactionCallback): Unit {
+      transactionCallback: IUnitTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         delegate.useDataClass(MyOtherPackageDataClassConverter(context).fromParcelable(x))
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
index 661bf8c..c5bf8e7 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
@@ -3,10 +3,8 @@
 import android.content.Context
 import com.myotherpackage.MyOtherPackageDataClassConverter
 import com.myotherpackage.ParcelableMyOtherPackageDataClass
-import com.mysdk.PrivacySandboxThrowableParcelConverter
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.IntArray
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -17,8 +15,7 @@
 ) : IMyMainPackageInterface.Stub() {
   private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
 
-  public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback):
-      Unit {
+  public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doIntStuff(x.toList())
@@ -33,7 +30,7 @@
   }
 
   public override fun useDataClass(x: ParcelableMyOtherPackageDataClass,
-      transactionCallback: IMyOtherPackageDataClassTransactionCallback): Unit {
+      transactionCallback: IMyOtherPackageDataClassTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result =
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
index b9c2fb5..d95fdd0 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
@@ -2,10 +2,8 @@
 
 import android.content.Context
 import com.myotherpackage.MyOtherPackageInterfaceStubDelegate
-import com.mysdk.PrivacySandboxThrowableParcelConverter
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Int
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -20,7 +18,7 @@
     x: Int,
     y: Int,
     transactionCallback: IStringTransactionCallback,
-  ): Unit {
+  ) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doStuff(x, y)
@@ -35,7 +33,7 @@
   }
 
   public override
-      fun getMyInterface(transactionCallback: IMyMainPackageInterfaceTransactionCallback): Unit {
+      fun getMyInterface(transactionCallback: IMyMainPackageInterfaceTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.getMyInterface()
@@ -50,8 +48,7 @@
   }
 
   public override
-      fun getMyOtherPackageInterface(transactionCallback: IMyOtherPackageInterfaceTransactionCallback):
-      Unit {
+      fun getMyOtherPackageInterface(transactionCallback: IMyOtherPackageInterfaceTransactionCallback) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.getMyOtherPackageInterface()
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/TransportCancellationCallback.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/TransportCancellationCallback.kt
index 287dc52..ba1815c 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/TransportCancellationCallback.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/TransportCancellationCallback.kt
@@ -8,7 +8,7 @@
 ) : ICancellationSignal.Stub() {
   private val hasCancelled: AtomicBoolean = AtomicBoolean(false)
 
-  public override fun cancel(): Unit {
+  public override fun cancel() {
     if (hasCancelled.compareAndSet(false, true)) {
       onCancel()
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/TransportCancellationCallback.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/TransportCancellationCallback.kt
index 287dc52..ba1815c 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/TransportCancellationCallback.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/TransportCancellationCallback.kt
@@ -8,7 +8,7 @@
 ) : ICancellationSignal.Stub() {
   private val hasCancelled: AtomicBoolean = AtomicBoolean(false)
 
-  public override fun cancel(): Unit {
+  public override fun cancel() {
     if (hasCancelled.compareAndSet(false, true)) {
       onCancel()
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
index c46719e..a814b72 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
@@ -3,7 +3,6 @@
 import android.content.Context
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Int
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -18,7 +17,7 @@
     x: Int,
     y: Int,
     transactionCallback: IStringTransactionCallback,
-  ): Unit {
+  ) {
     val job = coroutineScope.launch {
       try {
         val result = delegate.doStuff(x, y)
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterface.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterface.kt
index 0474314..0b68d85 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterface.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterface.kt
@@ -1,5 +1,5 @@
 package com.sdkwithcallbacks
 
 public interface MyInterface {
-    public fun doStuff(): Unit
+    public fun doStuff()
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterfaceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterfaceClientProxy.kt
index f325ee4..c11a869 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterfaceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyInterfaceClientProxy.kt
@@ -3,7 +3,7 @@
 public class MyInterfaceClientProxy(
     public val remote: IMyInterface,
 ) : MyInterface {
-    public override fun doStuff(): Unit {
+    public override fun doStuff() {
         remote.doStuff()
     }
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterface.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterface.kt
index 2975910..b337c45 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterface.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterface.kt
@@ -3,5 +3,5 @@
 import androidx.privacysandbox.ui.core.SandboxedUiAdapter
 
 public interface MyUiInterface : SandboxedUiAdapter {
-    public fun doUiStuff(): Unit
+    public fun doUiStuff()
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterfaceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterfaceClientProxy.kt
index 6aa0aae..4d8eeb9 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterfaceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyUiInterfaceClientProxy.kt
@@ -15,7 +15,7 @@
     public val sandboxedUiAdapter: SandboxedUiAdapter =
             SandboxedUiAdapterFactory.createFromCoreLibInfo(coreLibInfo)
 
-    public override fun doUiStuff(): Unit {
+    public override fun doUiStuff() {
         remote.doUiStuff()
     }
 
@@ -27,7 +27,7 @@
         isZOrderOnTop: Boolean,
         clientExecutor: Executor,
         client: SandboxedUiAdapter.SessionClient,
-    ): Unit {
+    ) {
         sandboxedUiAdapter.openSession(context, windowInputToken, initialWidth, initialHeight,
                 isZOrderOnTop, clientExecutor, client)
     }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallback.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallback.kt
index ec21831..040ec55 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallback.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallback.kt
@@ -3,13 +3,13 @@
 import androidx.privacysandbox.ui.core.SdkActivityLauncher
 
 public interface SdkCallback {
-    public fun onCompleteInterface(myInterface: MyInterface): Unit
+    public fun onCompleteInterface(myInterface: MyInterface)
 
-    public fun onEmptyEvent(): Unit
+    public fun onEmptyEvent()
 
-    public fun onPrimitivesReceived(x: Int, y: Int): Unit
+    public fun onPrimitivesReceived(x: Int, y: Int)
 
-    public fun onSdkActivityLauncherReceived(myLauncher: SdkActivityLauncher): Unit
+    public fun onSdkActivityLauncherReceived(myLauncher: SdkActivityLauncher)
 
-    public fun onValueReceived(response: Response): Unit
+    public fun onValueReceived(response: Response)
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
index 3bc4ed5..f98dafb 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
@@ -4,7 +4,6 @@
 import com.sdkwithcallbacks.ResponseConverter.fromParcelable
 import com.sdkwithcallbacks.SdkActivityLauncherConverter.getLocalOrProxyLauncher
 import kotlin.Int
-import kotlin.Unit
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -14,31 +13,31 @@
 ) : ISdkCallback.Stub() {
   private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
 
-  public override fun onCompleteInterface(myInterface: IMyInterface): Unit {
+  public override fun onCompleteInterface(myInterface: IMyInterface) {
     coroutineScope.launch {
       delegate.onCompleteInterface(MyInterfaceClientProxy(myInterface))
     }
   }
 
-  public override fun onEmptyEvent(): Unit {
+  public override fun onEmptyEvent() {
     coroutineScope.launch {
       delegate.onEmptyEvent()
     }
   }
 
-  public override fun onPrimitivesReceived(x: Int, y: Int): Unit {
+  public override fun onPrimitivesReceived(x: Int, y: Int) {
     coroutineScope.launch {
       delegate.onPrimitivesReceived(x, y)
     }
   }
 
-  public override fun onSdkActivityLauncherReceived(myLauncher: Bundle): Unit {
+  public override fun onSdkActivityLauncherReceived(myLauncher: Bundle) {
     coroutineScope.launch {
       delegate.onSdkActivityLauncherReceived(getLocalOrProxyLauncher(myLauncher))
     }
   }
 
-  public override fun onValueReceived(response: ParcelableResponse): Unit {
+  public override fun onValueReceived(response: ParcelableResponse) {
     coroutineScope.launch {
       delegate.onValueReceived(fromParcelable(response))
     }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkService.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkService.kt
index 510bd89..3a427d3 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkService.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkService.kt
@@ -1,5 +1,5 @@
 package com.sdkwithcallbacks
 
 public interface SdkService {
-    public fun registerCallback(callback: SdkCallback): Unit
+    public fun registerCallback(callback: SdkCallback)
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkServiceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkServiceClientProxy.kt
index 83a8df2..d69a96b 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkServiceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkServiceClientProxy.kt
@@ -3,7 +3,7 @@
 public class SdkServiceClientProxy(
     public val remote: ISdkService,
 ) : SdkService {
-    public override fun registerCallback(callback: SdkCallback): Unit {
+    public override fun registerCallback(callback: SdkCallback) {
         remote.registerCallback(SdkCallbackStubDelegate(callback))
     }
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterface.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterface.kt
index cc0fb50..61b2aa6 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterface.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterface.kt
@@ -5,9 +5,9 @@
 public interface MyInterface {
     public suspend fun add(x: Int, y: Int): Int
 
-    public fun doSomething(firstInterface: MyInterface, secondInterface: MySecondInterface): Unit
+    public fun doSomething(firstInterface: MyInterface, secondInterface: MySecondInterface)
 
-    public fun doSomethingWithNullableInterface(maybeInterface: MySecondInterface?): Unit
+    public fun doSomethingWithNullableInterface(maybeInterface: MySecondInterface?)
 
-    public fun doSomethingWithSdkActivityLauncher(launcher: SdkActivityLauncher): Unit
+    public fun doSomethingWithSdkActivityLauncher(launcher: SdkActivityLauncher)
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterfaceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterfaceClientProxy.kt
index 33c8b84..ad696066 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterfaceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MyInterfaceClientProxy.kt
@@ -32,19 +32,19 @@
     }
 
     public override fun doSomething(firstInterface: MyInterface,
-            secondInterface: MySecondInterface): Unit {
+            secondInterface: MySecondInterface) {
         remote.doSomething((firstInterface as MyInterfaceClientProxy).remote,
                 IMySecondInterfaceCoreLibInfoAndBinderWrapperConverter.toParcelable((secondInterface
                 as MySecondInterfaceClientProxy).coreLibInfo, secondInterface.remote))
     }
 
-    public override fun doSomethingWithNullableInterface(maybeInterface: MySecondInterface?): Unit {
+    public override fun doSomethingWithNullableInterface(maybeInterface: MySecondInterface?) {
         remote.doSomethingWithNullableInterface(maybeInterface?.let { notNullValue ->
                 IMySecondInterfaceCoreLibInfoAndBinderWrapperConverter.toParcelable((notNullValue as
                 MySecondInterfaceClientProxy).coreLibInfo, notNullValue.remote) })
     }
 
-    public override fun doSomethingWithSdkActivityLauncher(launcher: SdkActivityLauncher): Unit {
+    public override fun doSomethingWithSdkActivityLauncher(launcher: SdkActivityLauncher) {
         remote.doSomethingWithSdkActivityLauncher(toBinder(launcher))
     }
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySdkClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySdkClientProxy.kt
index 578aa60..fcb3541 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySdkClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySdkClientProxy.kt
@@ -1,6 +1,5 @@
 package com.sdk
 
-import com.sdk.PrivacySandboxThrowableParcelConverter
 import com.sdk.PrivacySandboxThrowableParcelConverter.fromThrowableParcel
 import kotlin.coroutines.resumeWithException
 import kotlinx.coroutines.suspendCancellableCoroutine
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterface.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterface.kt
index 0505e08..36f87f5 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterface.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterface.kt
@@ -3,5 +3,5 @@
 import androidx.privacysandbox.ui.core.SandboxedUiAdapter
 
 public interface MySecondInterface : SandboxedUiAdapter {
-    public fun doStuff(): Unit
+    public fun doStuff()
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterfaceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterfaceClientProxy.kt
index 48db338..d7f90e3 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterfaceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/MySecondInterfaceClientProxy.kt
@@ -15,7 +15,7 @@
     public val sandboxedUiAdapter: SandboxedUiAdapter =
             SandboxedUiAdapterFactory.createFromCoreLibInfo(coreLibInfo)
 
-    public override fun doStuff(): Unit {
+    public override fun doStuff() {
         remote.doStuff()
     }
 
@@ -27,7 +27,7 @@
         isZOrderOnTop: Boolean,
         clientExecutor: Executor,
         client: SandboxedUiAdapter.SessionClient,
-    ): Unit {
+    ) {
         sandboxedUiAdapter.openSession(context, windowInputToken, initialWidth, initialHeight,
                 isZOrderOnTop, clientExecutor, client)
     }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdk.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdk.kt
index 912155e..cb65c54 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdk.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdk.kt
@@ -7,19 +7,19 @@
         third: Long,
     ): Boolean
 
-    public fun echoBoolean(input: Boolean): Unit
+    public fun echoBoolean(input: Boolean)
 
-    public fun echoChar(input: Char): Unit
+    public fun echoChar(input: Char)
 
-    public fun echoDouble(input: Double): Unit
+    public fun echoDouble(input: Double)
 
-    public fun echoFloat(input: Float): Unit
+    public fun echoFloat(input: Float)
 
-    public fun echoInt(input: Int): Unit
+    public fun echoInt(input: Int)
 
-    public fun echoLong(input: Long): Unit
+    public fun echoLong(input: Long)
 
-    public fun echoString(input: String): Unit
+    public fun echoString(input: String)
 
     public suspend fun processBooleanList(x: List<Boolean>): List<Boolean>
 
@@ -39,13 +39,13 @@
 
     public suspend fun processStringList(x: List<String>): List<String>
 
-    public fun receiveAndReturnNothing(): Unit
+    public fun receiveAndReturnNothing()
 
-    public suspend fun receiveAndReturnNothingAsync(): Unit
+    public suspend fun receiveAndReturnNothingAsync()
 
     public fun receiveMultipleArguments(
         first: Int,
         second: String,
         third: Long,
-    ): Unit
+    )
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdkClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdkClientProxy.kt
index 329c0df..bc02194 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdkClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/TestSandboxSdkClientProxy.kt
@@ -1,6 +1,5 @@
 package com.mysdk
 
-import com.mysdk.PrivacySandboxThrowableParcelConverter
 import com.mysdk.PrivacySandboxThrowableParcelConverter.fromThrowableParcel
 import kotlin.coroutines.resumeWithException
 import kotlinx.coroutines.suspendCancellableCoroutine
@@ -34,31 +33,31 @@
         }
     }
 
-    public override fun echoBoolean(input: Boolean): Unit {
+    public override fun echoBoolean(input: Boolean) {
         remote.echoBoolean(input)
     }
 
-    public override fun echoChar(input: Char): Unit {
+    public override fun echoChar(input: Char) {
         remote.echoChar(input)
     }
 
-    public override fun echoDouble(input: Double): Unit {
+    public override fun echoDouble(input: Double) {
         remote.echoDouble(input)
     }
 
-    public override fun echoFloat(input: Float): Unit {
+    public override fun echoFloat(input: Float) {
         remote.echoFloat(input)
     }
 
-    public override fun echoInt(input: Int): Unit {
+    public override fun echoInt(input: Int) {
         remote.echoInt(input)
     }
 
-    public override fun echoLong(input: Long): Unit {
+    public override fun echoLong(input: Long) {
         remote.echoLong(input)
     }
 
-    public override fun echoString(input: String): Unit {
+    public override fun echoString(input: String) {
         remote.echoString(input)
     }
 
@@ -269,7 +268,7 @@
         }
     }
 
-    public override fun receiveAndReturnNothing(): Unit {
+    public override fun receiveAndReturnNothing() {
         remote.receiveAndReturnNothing()
     }
 
@@ -299,7 +298,7 @@
         first: Int,
         second: String,
         third: Long,
-    ): Unit {
+    ) {
         remote.receiveMultipleArguments(first, second, third)
     }
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterface.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterface.kt
index b7db6ef..a8ebad1 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterface.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterface.kt
@@ -1,5 +1,5 @@
 package com.sdkwithvalues
 
 public interface MyInterface {
-    public fun doStuff(): Unit
+    public fun doStuff()
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterfaceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterfaceClientProxy.kt
index 2fd68e4..781d720 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterfaceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyInterfaceClientProxy.kt
@@ -3,7 +3,7 @@
 public class MyInterfaceClientProxy(
     public val remote: IMyInterface,
 ) : MyInterface {
-    public override fun doStuff(): Unit {
+    public override fun doStuff() {
         remote.doStuff()
     }
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterface.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterface.kt
index 65cbc2b..4bf3412 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterface.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterface.kt
@@ -3,5 +3,5 @@
 import androidx.privacysandbox.ui.core.SandboxedUiAdapter
 
 public interface MyUiInterface : SandboxedUiAdapter {
-    public fun doUiStuff(): Unit
+    public fun doUiStuff()
 }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterfaceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterfaceClientProxy.kt
index bd43324..86709a8 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterfaceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/MyUiInterfaceClientProxy.kt
@@ -15,7 +15,7 @@
     public val sandboxedUiAdapter: SandboxedUiAdapter =
             SandboxedUiAdapterFactory.createFromCoreLibInfo(coreLibInfo)
 
-    public override fun doUiStuff(): Unit {
+    public override fun doUiStuff() {
         remote.doUiStuff()
     }
 
@@ -27,7 +27,7 @@
         isZOrderOnTop: Boolean,
         clientExecutor: Executor,
         client: SandboxedUiAdapter.SessionClient,
-    ): Unit {
+    ) {
         sandboxedUiAdapter.openSession(context, windowInputToken, initialWidth, initialHeight,
                 isZOrderOnTop, clientExecutor, client)
     }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/SdkInterfaceClientProxy.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/SdkInterfaceClientProxy.kt
index def4b57..6505a91 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/SdkInterfaceClientProxy.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/SdkInterfaceClientProxy.kt
@@ -1,10 +1,7 @@
 package com.sdkwithvalues
 
-import com.sdkwithvalues.PrivacySandboxThrowableParcelConverter
 import com.sdkwithvalues.PrivacySandboxThrowableParcelConverter.fromThrowableParcel
-import com.sdkwithvalues.SdkRequestConverter
 import com.sdkwithvalues.SdkRequestConverter.toParcelable
-import com.sdkwithvalues.SdkResponseConverter
 import com.sdkwithvalues.SdkResponseConverter.fromParcelable
 import kotlin.coroutines.resumeWithException
 import kotlinx.coroutines.suspendCancellableCoroutine
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ClientProxyTypeGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ClientProxyTypeGenerator.kt
index c562ae2..04c8db3 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ClientProxyTypeGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ClientProxyTypeGenerator.kt
@@ -107,6 +107,7 @@
 
     private fun toSuspendFunSpec(method: Method) =
         FunSpec.builder(method.name).build {
+            addModifiers(KModifier.PUBLIC)
             addModifiers(KModifier.OVERRIDE)
             addModifiers(KModifier.SUSPEND)
             addParameters(method.parameters.map { it.poetSpec() })
@@ -128,14 +129,14 @@
 
     private fun toNonSuspendFunSpec(method: Method) =
         FunSpec.builder(method.name).build {
-            addModifiers(KModifier.OVERRIDE)
+            addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
             addParameters(method.parameters.map { it.poetSpec() })
 
             addCode(generateRemoteCall(method))
         }
 
     private fun generateOpenSession() = FunSpec.builder("openSession").build {
-        addModifiers(KModifier.OVERRIDE)
+        addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
         addParameters(
             listOf(
                 ParameterSpec(contextPropertyName, contextClass),
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxCancellationExceptionFileGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxCancellationExceptionFileGenerator.kt
index dadcb7d5..a53dbe9 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxCancellationExceptionFileGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxCancellationExceptionFileGenerator.kt
@@ -36,11 +36,11 @@
                     PropertySpec.builder(
                         "message",
                         String::class.asTypeName().copy(nullable = true),
-                    ).addModifiers(KModifier.OVERRIDE).build(),
+                    ).addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE).build(),
                     PropertySpec.builder(
                         "cause",
                         Throwable::class.asTypeName().copy(nullable = true),
-                    ).addModifiers(KModifier.OVERRIDE).build()
+                    ).addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE).build()
                 )
             )
         }
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxExceptionFileGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxExceptionFileGenerator.kt
index fdb9242..c93a34f 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxExceptionFileGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/PrivacySandboxExceptionFileGenerator.kt
@@ -36,11 +36,11 @@
                     PropertySpec.builder(
                         "message",
                         String::class.asTypeName().copy(nullable = true),
-                    ).addModifiers(KModifier.OVERRIDE).build(),
+                    ).addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE).build(),
                     PropertySpec.builder(
                         "cause",
                         Throwable::class.asTypeName().copy(nullable = true),
-                    ).addModifiers(KModifier.OVERRIDE).build()
+                    ).addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE).build()
                 )
             )
         }
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
index 85f2dfa..7082174 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
@@ -102,7 +102,7 @@
 
     private fun toSuspendFunSpec(method: Method): FunSpec {
         return FunSpec.builder(method.name).build {
-            addModifiers(KModifier.OVERRIDE)
+            addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
             addParameters(getParameters(method))
             addCode {
                 addControlFlow(
@@ -145,7 +145,7 @@
     }
 
     private fun toNonSuspendFunSpec(method: Method) = FunSpec.builder(method.name).build {
-        addModifiers(KModifier.OVERRIDE)
+        addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
         addParameters(getParameters(method))
         addCode(CodeBlock.builder().build {
             addControlFlow("%L.%M", coroutineScopePropertyName, launchMethod) {
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/TransportCancellationGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/TransportCancellationGenerator.kt
index 8920889..cf8251b 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/TransportCancellationGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/TransportCancellationGenerator.kt
@@ -54,7 +54,7 @@
                 ).initializer("%T(false)", atomicBooleanClass).build()
             )
             addFunction(FunSpec.builder("cancel").build {
-                addModifiers(KModifier.OVERRIDE)
+                addModifiers(KModifier.PUBLIC, KModifier.OVERRIDE)
                 addCode {
                     addControlFlow("if (hasCancelled.compareAndSet(false, true))") {
                         addStatement("onCancel()")
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/MusicDao.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/MusicDao.kt
index a7ef64d..5753602 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/MusicDao.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/MusicDao.kt
@@ -20,6 +20,7 @@
 import androidx.collection.SparseArrayCompat
 import androidx.lifecycle.LiveData
 import androidx.room.Dao
+import androidx.room.Delete
 import androidx.room.Insert
 import androidx.room.MapInfo
 import androidx.room.Query
@@ -32,6 +33,9 @@
 import androidx.room.integration.kotlintestapp.vo.Artist
 import androidx.room.integration.kotlintestapp.vo.Image
 import androidx.room.integration.kotlintestapp.vo.ImageFormat
+import androidx.room.integration.kotlintestapp.vo.Playlist
+import androidx.room.integration.kotlintestapp.vo.PlaylistSongXRef
+import androidx.room.integration.kotlintestapp.vo.PlaylistWithSongs
 import androidx.room.integration.kotlintestapp.vo.ReleasedAlbum
 import androidx.room.integration.kotlintestapp.vo.Song
 import androidx.sqlite.db.SupportSQLiteQuery
@@ -41,6 +45,7 @@
 import io.reactivex.Flowable
 import java.nio.ByteBuffer
 import java.util.Date
+import kotlinx.coroutines.flow.Flow
 
 @JvmDefaultWithCompatibility
 @Dao
@@ -53,6 +58,16 @@
 
     @Insert
     fun addAlbums(vararg albums: Album)
+
+    @Insert
+    fun addPlaylists(vararg playlists: Playlist)
+
+    @Insert
+    fun addPlaylistSongRelations(vararg relations: PlaylistSongXRef)
+
+    @Delete
+    fun removePlaylistSongRelations(vararg relations: PlaylistSongXRef)
+
     @Insert
     fun addImages(vararg images: Image)
 
@@ -355,4 +370,8 @@
     @MapInfo(keyColumn = "mImageYear", valueColumn = "mTitle")
     @RewriteQueriesToDropUnusedColumns
     fun getNestedMapWithMapInfoKeyAndValue(): Map<Long, Map<Artist, Map<Album, List<String>>>>
+
+    @Transaction
+    @Query("SELECT * FROM Playlist WHERE mPlaylistId = :id")
+    fun getPlaylistsWithSongsFlow(id: Int): Flow<PlaylistWithSongs>
 }
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
index 4a23ca5..02d20ce 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
@@ -18,6 +18,10 @@
 
 import androidx.kruth.assertThat
 import androidx.room.integration.kotlintestapp.vo.Book
+import androidx.room.integration.kotlintestapp.vo.Playlist
+import androidx.room.integration.kotlintestapp.vo.PlaylistSongXRef
+import androidx.room.integration.kotlintestapp.vo.PlaylistWithSongs
+import androidx.room.integration.kotlintestapp.vo.Song
 import androidx.room.withTransaction
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -30,7 +34,6 @@
 import kotlinx.coroutines.cancelAndJoin
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.flow.buffer
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.produceIn
 import kotlinx.coroutines.flow.take
@@ -318,4 +321,73 @@
 
         job.cancelAndJoin()
     }
+
+    @Test
+    fun playlistSongs_async_update(): Unit = runBlocking {
+        val musicDao = database.musicDao()
+        val song1 = Song(
+            1,
+            "I Know Places",
+            "Taylor Swift",
+            "1989",
+            195,
+            2014
+        );
+        val song2 = Song(
+            2,
+            "Blank Space",
+            "Taylor Swift",
+            "1989",
+            241,
+            2014
+        )
+        musicDao.addSongs(song1, song2)
+        musicDao.addPlaylists(
+            Playlist(1),
+            Playlist(2)
+        )
+        musicDao.addPlaylistSongRelations(PlaylistSongXRef(1, 1))
+
+        val latches = Array(3) { CountDownLatch(1) }
+        val results = mutableListOf<PlaylistWithSongs>()
+        var collectCall = 0
+        val job = async(Dispatchers.IO) {
+            musicDao.getPlaylistsWithSongsFlow(1).collect {
+                if (collectCall >= latches.size) {
+                    fail("Should have only collected 3 results.")
+                }
+                results.add(it)
+                latches[collectCall].countDown()
+                collectCall++
+            }
+        }
+
+        latches[0].await()
+        assertThat(results.size).isEqualTo(1)
+        results[0].let { playlist ->
+            assertThat(playlist.songs.size).isEqualTo(1)
+            assertThat(playlist.songs[0]).isEqualTo(song1)
+        }
+
+        musicDao.addPlaylistSongRelations(PlaylistSongXRef(1, 2))
+
+        latches[1].await()
+        assertThat(results.size).isEqualTo(2)
+        results[1].let { playlist ->
+            assertThat(playlist.songs.size).isEqualTo(2)
+            assertThat(playlist.songs[0]).isEqualTo(song1)
+            assertThat(playlist.songs[1]).isEqualTo(song2)
+        }
+
+        musicDao.removePlaylistSongRelations(PlaylistSongXRef(1, 2))
+
+        latches[2].await()
+        assertThat(results.size).isEqualTo(3)
+        results[2].let { playlist ->
+            assertThat(playlist.songs.size).isEqualTo(1)
+            assertThat(playlist.songs[0]).isEqualTo(song1)
+        }
+
+        job.cancelAndJoin()
+    }
 }
diff --git a/room/room-compiler-processing-testing/build.gradle b/room/room-compiler-processing-testing/build.gradle
index e789fcd..5b2da1b 100644
--- a/room/room-compiler-processing-testing/build.gradle
+++ b/room/room-compiler-processing-testing/build.gradle
@@ -30,7 +30,6 @@
     implementation(libs.kotlinStdlibJdk8) // KSP defines older version as dependency, force update.
     implementation(libs.ksp)
     implementation(libs.googleCompileTesting)
-    implementation(project(":kruth:kruth"))
     // specify these to match the kotlin compiler version in AndroidX rather than what KSP or KCT
     // uses
     implementation(libs.kotlinCompilerEmbeddable)
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt
index e38371a..6642422 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt
@@ -16,16 +16,18 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.FailureMetadata
-import androidx.kruth.StringSubject
-import androidx.kruth.Subject
-import androidx.kruth.assertAbout
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.ExperimentalProcessingApi
 import androidx.room.compiler.processing.SyntheticJavacProcessor
 import androidx.room.compiler.processing.SyntheticProcessor
 import androidx.room.compiler.processing.util.compiler.TestCompilationResult
 import androidx.room.compiler.processing.util.runner.CompilationTestRunner
+import com.google.common.truth.Fact.fact
+import com.google.common.truth.Fact.simpleFact
+import com.google.common.truth.FailureMetadata
+import com.google.common.truth.StringSubject
+import com.google.common.truth.Subject
+import com.google.common.truth.Subject.Factory
+import com.google.common.truth.Truth
 import com.google.testing.compile.Compilation
 import java.util.regex.Pattern
 import javax.tools.Diagnostic
@@ -124,9 +126,8 @@
 class CompilationResultSubject internal constructor(
     failureMetadata: FailureMetadata,
     val compilationResult: CompilationResult,
-) : Subject<CompilationResult>(
-    actual = compilationResult,
-    metadata = failureMetadata,
+) : Subject<CompilationResultSubject, CompilationResult>(
+    failureMetadata, compilationResult
 ) {
     /**
      * set to true if any assertion on the subject requires it to fail (e.g. looking for errors)
@@ -149,7 +150,9 @@
     fun hasRawOutputContaining(expected: String) = apply {
         val found = compilationResult.rawOutput().contains(expected)
         if (!found) {
-            failWithActual("Did not find $expected in the output.")
+            failWithActual(
+                simpleFact("Did not find $expected in the output.")
+            )
         }
     }
 
@@ -171,7 +174,9 @@
     private fun hasDiagnosticCount(kind: Diagnostic.Kind, expected: Int) = apply {
         val actual = compilationResult.diagnosticsOfKind(kind).size
         if (actual != expected) {
-            failWithActual("expected $expected $kind messages, found $actual")
+            failWithActual(
+                simpleFact("expected $expected $kind messages, found $actual")
+            )
         }
     }
     /**
@@ -326,7 +331,9 @@
     fun hasError() = apply {
         shouldSucceed = false
         if (compilationResult.diagnosticsOfKind(Diagnostic.Kind.ERROR).isEmpty()) {
-            failWithActual("expected at least one failure message")
+            failWithActual(
+                simpleFact("expected at least one failure message")
+            )
         }
     }
 
@@ -337,9 +344,12 @@
      */
     fun generatedSourceFileWithPath(relativePath: String): StringSubject {
         val match = findGeneratedSource(relativePath)
-            ?: failWithActual("Didn't generate file with path: $relativePath")
-
-        return assertThat(match.contents)
+        if (match == null) {
+            failWithActual(
+                simpleFact("Didn't generate file with path: $relativePath")
+            )
+        }
+        return Truth.assertThat(match!!.contents)
     }
 
     private fun findGeneratedSource(relativePath: String) = compilationResult.generatedSources
@@ -358,14 +368,20 @@
     fun generatedSource(source: Source) = apply {
         val match = compilationResult.generatedSources.firstOrNull {
             it.relativePath == source.relativePath
-        } ?: failWithActual("Didn't generate $source")
+        }
+        if (match == null) {
+            failWithActual(
+                simpleFact("Didn't generate $source")
+            )
+            return@apply
+        }
         val mismatch = source.findMismatch(match)
         if (mismatch != null) {
             failWithActual(
-                "Generated code does not match expected",
-                "mismatch: $mismatch",
-                "expected: ${source.contents}",
-                "actual: ${match.contents}",
+                simpleFact("Generated code does not match expected"),
+                fact("mismatch", mismatch),
+                fact("expected", source.contents),
+                fact("actual", match.contents),
             )
         }
     }
@@ -377,8 +393,10 @@
     internal fun assertCompilationResult() {
         if (compilationResult.successfulCompilation != shouldSucceed) {
             failWithActual(
-                "expected compilation result to be: $shouldSucceed but was " +
-                    "${compilationResult.successfulCompilation}"
+                simpleFact(
+                    "expected compilation result to be: $shouldSucceed but was " +
+                        "${compilationResult.successfulCompilation}"
+                )
             )
         }
     }
@@ -389,7 +407,9 @@
      */
     internal fun assertAllExpectedRoundsAreCompleted() {
         if (compilationResult.processor.expectsAnotherRound()) {
-            failWithActual("Test runner requested another round but that didn't happen")
+            failWithActual(
+                simpleFact("Test runner requested another round but that didn't happen")
+            )
         }
     }
 
@@ -427,7 +447,7 @@
             }
         }
         if (matches.isEmpty()) {
-            failWithActual(buildErrorMessage())
+            failWithActual(simpleFact(buildErrorMessage()))
         }
         return DiagnosticMessagesSubject.assertThat(matches)
     }
@@ -449,7 +469,7 @@
             }
         }
         if (matches.isEmpty()) {
-            failWithActual(buildErrorMessage())
+            failWithActual(simpleFact(buildErrorMessage()))
         }
         return DiagnosticMessagesSubject.assertThat(matches)
     }
@@ -470,10 +490,18 @@
     }
 
     companion object {
+        private val FACTORY =
+            Factory<CompilationResultSubject, CompilationResult> { metadata, actual ->
+                CompilationResultSubject(metadata, actual)
+            }
+
         fun assertThat(
             compilationResult: CompilationResult
-        ): CompilationResultSubject =
-            assertAbout(::CompilationResultSubject).that(compilationResult)
+        ): CompilationResultSubject {
+            return Truth.assertAbout(FACTORY).that(
+                compilationResult
+            )
+        }
     }
 }
 
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/DiagnosticMessagesSubject.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/DiagnosticMessagesSubject.kt
index de1f737..213eea0 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/DiagnosticMessagesSubject.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/DiagnosticMessagesSubject.kt
@@ -16,9 +16,11 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.FailureMetadata
-import androidx.kruth.Subject
-import androidx.kruth.assertAbout
+import com.google.common.truth.Fact.simpleFact
+import com.google.common.truth.FailureMetadata
+import com.google.common.truth.Subject
+import com.google.common.truth.Subject.Factory
+import com.google.common.truth.Truth
 
 /**
  * Truth subject for diagnostic messages
@@ -26,8 +28,8 @@
 class DiagnosticMessagesSubject internal constructor(
     failureMetadata: FailureMetadata,
     private val diagnosticMessages: List<DiagnosticMessage>,
-) : Subject<List<DiagnosticMessage>>(
-    diagnosticMessages, failureMetadata
+) : Subject<DiagnosticMessagesSubject, List<DiagnosticMessage>>(
+    failureMetadata, diagnosticMessages
 ) {
 
     private val lineContents by lazy {
@@ -50,10 +52,15 @@
      * Note that if there are multiple messages, any match will be sufficient.
      */
     fun onLine(lineNumber: Int) = apply {
-        if (locations.none { it.line == lineNumber }) {
+        if (locations.none {
+            it.line == lineNumber
+        }
+        ) {
             failWithActual(
-                "expected line $lineNumber but it was " +
-                    locations.joinToString(",")
+                simpleFact(
+                    "expected line $lineNumber but it was " +
+                        locations.joinToString(",")
+                )
             )
         }
     }
@@ -64,7 +71,7 @@
     fun hasCount(expected: Int) = apply {
         if (diagnosticMessages.size != expected) {
             failWithActual(
-                "expected $expected messages, found ${diagnosticMessages.size}"
+                simpleFact("expected $expected messages, found ${diagnosticMessages.size}")
             )
         }
     }
@@ -75,7 +82,7 @@
     fun onLineContaining(content: String) = apply {
         if (lineContents.isEmpty()) {
             failWithActual(
-                "Cannot validate line content due to missing location information"
+                simpleFact("Cannot validate line content due to missing location information")
             )
         }
         if (lineContents.none {
@@ -83,8 +90,10 @@
         }
         ) {
             failWithActual(
-                "expected line content with $content but was " +
-                    lineContents.joinToString("\n")
+                simpleFact(
+                    "expected line content with $content but was " +
+                        lineContents.joinToString("\n")
+                )
             )
         }
     }
@@ -96,18 +105,28 @@
     fun onSource(source: Source) = apply {
         if (locations.none { it.source == source }) {
             failWithActual(
-                """
+                simpleFact(
+                    """
                     Expected diagnostic to be on $source but found it on
                     ${locations.joinToString(",")}
-                """.trimIndent()
+                    """.trimIndent()
+                )
             )
         }
     }
 
     companion object {
+        private val FACTORY =
+            Factory<DiagnosticMessagesSubject, List<DiagnosticMessage>> { metadata, actual ->
+                DiagnosticMessagesSubject(metadata, actual)
+            }
+
         fun assertThat(
             diagnosticMessages: List<DiagnosticMessage>
-        ): DiagnosticMessagesSubject =
-            assertAbout(::DiagnosticMessagesSubject).that(diagnosticMessages)
+        ): DiagnosticMessagesSubject {
+            return Truth.assertAbout(FACTORY).that(
+                diagnosticMessages
+            )
+        }
     }
 }
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt
index bcef38b..a0145e7 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.ExperimentalProcessingApi
 import androidx.room.compiler.processing.XProcessingEnvConfig
 import androidx.room.compiler.processing.XProcessingEnvironmentTestConfigProvider
@@ -32,6 +30,8 @@
 import androidx.room.compiler.processing.util.runner.KspCompilationTestRunner
 import androidx.room.compiler.processing.util.runner.TestCompilationParameters
 import com.google.common.io.Files
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.google.devtools.ksp.processing.SymbolProcessorProvider
 import java.io.File
 import java.util.jar.JarEntry
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/XTestInvocation.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/XTestInvocation.kt
index 959e75e..4e230a0 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/XTestInvocation.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/XTestInvocation.kt
@@ -16,10 +16,10 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.ExperimentalProcessingApi
 import androidx.room.compiler.processing.XProcessingEnv
 import androidx.room.compiler.processing.XRoundEnv
+import com.google.common.truth.Truth
 import kotlin.reflect.KClass
 
 /**
@@ -100,7 +100,7 @@
     }
 
     private fun assertNotDisposed() {
-        assertWithMessage("Cannot use a test invocation after it is disposed.")
+        Truth.assertWithMessage("Cannot use a test invocation after it is disposed.")
             .that(disposed)
             .isFalse()
     }
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticMessageCollectorTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticMessageCollectorTest.kt
index 1c5c650..66b21fa5 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticMessageCollectorTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticMessageCollectorTest.kt
@@ -16,10 +16,10 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.compiler.DiagnosticsMessageCollector
 import androidx.room.compiler.processing.util.compiler.steps.RawDiagnosticMessage
 import androidx.room.compiler.processing.util.compiler.steps.RawDiagnosticMessage.Location
+import com.google.common.truth.Truth.assertThat
 import javax.tools.Diagnostic
 import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
 import org.junit.Test
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt
index d211727..7829bd4 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.ExperimentalProcessingApi
+import com.google.common.truth.Truth.assertThat
 import javax.tools.Diagnostic
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt
index 7d71f16..ba43888 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt
@@ -16,11 +16,10 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.ExperimentalProcessingApi
 import androidx.room.compiler.processing.XElement
 import androidx.room.compiler.processing.compat.XConverters.toXProcessing
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.JavaFile
 import com.squareup.javapoet.TypeName
 import com.squareup.javapoet.TypeSpec
@@ -339,8 +338,7 @@
             }
         }
 
-        // Kruth doesn't support exceptions yet
-        Truth.assertThat(result.exceptionOrNull())
+        assertThat(result.exceptionOrNull())
             .hasCauseThat()
             .hasMessageThat()
             .contains(
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/LoadFromDefaultEnvironmentConfigurationProviderTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/LoadFromDefaultEnvironmentConfigurationProviderTest.kt
index 773c6cd..40bdb48 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/LoadFromDefaultEnvironmentConfigurationProviderTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/LoadFromDefaultEnvironmentConfigurationProviderTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class LoadFromDefaultEnvironmentConfigurationProviderTest {
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt
index f05bf87..7df4df1 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.JavaFile
 import com.squareup.javapoet.TypeSpec
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/SourceSetTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/SourceSetTest.kt
index 203f195..98fd644 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/SourceSetTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/SourceSetTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.compiler.SourceSet
+import com.google.common.truth.Truth.assertThat
 import org.jetbrains.kotlin.konan.file.File
 import org.junit.Rule
 import org.junit.Test
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestConfigTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestConfigTest.kt
index cde233d..7f731db 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestConfigTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestConfigTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.CompilationTestCapabilities.Config
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class TestConfigTest {
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt
index 10cf032..32fc356 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.ExperimentalProcessingApi
 import androidx.room.compiler.processing.SyntheticJavacProcessor
 import androidx.room.compiler.processing.SyntheticKspProcessor
@@ -29,7 +28,7 @@
 import androidx.room.compiler.processing.util.compiler.TestCompilationArguments
 import androidx.room.compiler.processing.util.compiler.compile
 import androidx.room.compiler.processing.util.compiler.steps.KaptCompilationStep
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
 import com.google.devtools.ksp.processing.SymbolProcessor
 import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
 import com.google.devtools.ksp.processing.SymbolProcessorProvider
@@ -144,8 +143,7 @@
             "c" to "d"
         )
         val handler: (XTestInvocation) -> Unit = {
-            // Kruth MapSubject doesn't support containsAtLeastEntriesIn yet
-            Truth.assertThat(it.processingEnv.options).containsAtLeastEntriesIn(testOptions)
+            assertThat(it.processingEnv.options).containsAtLeastEntriesIn(testOptions)
         }
         runJavaProcessorTest(
             sources = emptyList(),
@@ -425,7 +423,7 @@
             "org.jetbrains.kotlin.kapt3",
             listOf("-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true")
         ).let { options ->
-            assertThat(options).containsExactly("correctErrorTypes" to "true")
+            assertThat(options).containsExactly("correctErrorTypes", "true")
         }
 
         // zero args
@@ -441,7 +439,7 @@
             "org.jetbrains.kotlin.kapt3",
             listOf("-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true", "-verbose")
         ).let { options ->
-            assertThat(options).containsExactly("correctErrorTypes" to "true")
+            assertThat(options).containsExactly("correctErrorTypes", "true")
         }
 
         // illegal format (missing "=")
@@ -476,8 +474,8 @@
             )
         ).let { options ->
             assertThat(options).containsExactly(
-                "correctErrorTypes" to "true",
-                "sources" to "build/kapt/sources"
+                "correctErrorTypes", "true",
+                "sources", "build/kapt/sources"
             )
         }
     }
diff --git a/room/room-compiler-processing/build.gradle b/room/room-compiler-processing/build.gradle
index 0e71dd2..edd335d 100644
--- a/room/room-compiler-processing/build.gradle
+++ b/room/room-compiler-processing/build.gradle
@@ -84,9 +84,9 @@
     testImplementation(libs.jsr250)
     testImplementation(libs.ksp)
     testImplementation(libs.kotlinMetadataJvm)
+    testImplementation(libs.testParameterInjector)
     testImplementation(project(":room:room-compiler-processing-testing"))
     testImplementation(project(":internal-testutils-common"))
-    testImplementation(project(":kruth:kruth"))
 }
 
 tasks.withType(KotlinCompile).configureEach {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
index f4a145b..c76af83 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
@@ -38,10 +38,12 @@
 import com.squareup.kotlinpoet.javapoet.JClassName
 import com.squareup.kotlinpoet.javapoet.JParameterizedTypeName
 import com.squareup.kotlinpoet.javapoet.JTypeName
+import com.squareup.kotlinpoet.javapoet.JTypeVariableName
 import com.squareup.kotlinpoet.javapoet.JWildcardTypeName
 import com.squareup.kotlinpoet.javapoet.KClassName
 import com.squareup.kotlinpoet.javapoet.KParameterizedTypeName
 import com.squareup.kotlinpoet.javapoet.KTypeName
+import com.squareup.kotlinpoet.javapoet.KTypeVariableName
 import com.squareup.kotlinpoet.javapoet.KWildcardTypeName
 import kotlin.reflect.KClass
 
@@ -257,6 +259,16 @@
                 }
             )
         }
+
+        /**
+         * Creates a type variable named with bounds.
+         */
+        fun getTypeVariableName(name: String, bounds: List<XTypeName> = emptyList()): XTypeName {
+            return XTypeName(
+                java = JTypeVariableName.get(name, *bounds.map { it.java }.toTypedArray()),
+                kotlin = KTypeVariableName(name, bounds.map { it.kotlin })
+            )
+        }
     }
 }
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
index 13ace16..2012535 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
@@ -51,26 +51,27 @@
     }
 
     override val annotationValues: List<XAnnotationValue> by lazy {
-        // In KSP the annotation members may be represented by constructor parameters in kotlin
-        // source or by abstract methods in java source so we check both.
-        val declarationConstructors = typeElement.let {
-            // We access constructor using declaration since for compatibility with KAPT,
-            // XTypeElement.getConstructors() will return an empty list for annotation classes.
-            check(it is KspTypeElement)
-            it.declaration.getConstructors().map {
-                KspConstructorElement(
-                    env = env,
-                    declaration = it
-                )
+        // Whether the annotation value is being treated as property or abstract method depends on
+        // the actual usage of the annotation. If the annotation is being used on Java source, then
+        // the annotation value will have a corresponding method element, otherwise, it will become
+        // a kotlin property.
+        val typesByName =
+            buildMap {
+                typeElement.getDeclaredMethods()
+                    .filter {
+                        if ((typeElement as KspTypeElement).declaration
+                                .getConstructors()
+                                .single().parameters
+                                .isNotEmpty()) {
+                            it.isKotlinPropertyMethod()
+                        } else {
+                            it.isAbstract()
+                        }
+                    }.forEach {
+                        put(it.name, it.returnType)
+                        put(it.jvmName, it.returnType)
+                    }
             }
-        }
-        val typesByName = if (declarationConstructors.single().parameters.isNotEmpty()) {
-            declarationConstructors.single().parameters.associate { it.name to it.type }
-        } else {
-            typeElement.getDeclaredMethods()
-                .filter { it.isAbstract() }
-                .associate { it.name to it.returnType }
-        }
         // KSAnnotated.arguments isn't guaranteed to have the same ordering as declared in the
         // annotation declaration, so we order it manually using a map from name to index.
         val indexByName = typesByName.keys.mapIndexed { index, name -> name to index }.toMap()
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/codegen/XTypeNameTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/codegen/XTypeNameTest.kt
index e93dfd6..7ba9a46 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/codegen/XTypeNameTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/codegen/XTypeNameTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.codegen
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XNullability
+import com.google.common.truth.Truth.assertThat
 import com.squareup.kotlinpoet.INT
 import com.squareup.kotlinpoet.SHORT
 import com.squareup.kotlinpoet.javapoet.JClassName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt
index fd831e9..52f12fa 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt
@@ -16,12 +16,12 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class FallbackLocationInformationTest {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/InternalModifierTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/InternalModifierTest.kt
index 7a380e5..66f907f 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/InternalModifierTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/InternalModifierTest.kt
@@ -16,12 +16,12 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.CompilationTestCapabilities
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.runKaptTest
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class InternalModifierTest {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KotlinMetadataTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KotlinMetadataTest.kt
index 623aa71..ea65ac3 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KotlinMetadataTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KotlinMetadataTest.kt
@@ -16,13 +16,13 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.testcode.KotlinTestClass
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.asJTypeName
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.getParameter
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class KotlinMetadataTest {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KspClassFileUtilityTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KspClassFileUtilityTest.kt
index 88e08ca..d486317 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KspClassFileUtilityTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/KspClassFileUtilityTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.ksp.KspTypeElement
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
@@ -24,6 +23,7 @@
 import androidx.room.compiler.processing.util.getAllFieldNames
 import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.google.devtools.ksp.symbol.Origin
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MemoizedSequenceTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MemoizedSequenceTest.kt
index 704fd1d..2dc5ae9 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MemoizedSequenceTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MemoizedSequenceTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.MemoizedSequence
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class MemoizedSequenceTest {
@@ -74,7 +74,7 @@
         val result = kotlin.runCatching {
             memoized.iterator().next()
         }
-        assertThat(result.exceptionOrNull()).isInstanceOf<NoSuchElementException>()
+        assertThat(result.exceptionOrNull()).isInstanceOf(NoSuchElementException::class.java)
     }
 
     @Test
@@ -88,7 +88,7 @@
                 collected.add(iterator.next())
             }
         }
-        assertThat(result.exceptionOrNull()).isInstanceOf<NoSuchElementException>()
+        assertThat(result.exceptionOrNull()).isInstanceOf(NoSuchElementException::class.java)
         assertThat(collected).containsExactly(1, 2, 3)
     }
 }
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
index eee3dd6..95fc55e 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.javac.JavacMethodElement
 import androidx.room.compiler.processing.javac.JavacTypeElement
 import androidx.room.compiler.processing.util.Source
@@ -27,6 +26,7 @@
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.testutils.generateAllEnumerations
 import com.google.auto.common.MoreTypes
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.MethodSpec
 import com.squareup.javapoet.ParameterSpec
 import java.io.File
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt
index 0d4d22f..177ca7e 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt
@@ -16,13 +16,13 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.ksp.KSClassDeclarationAsOriginatingElement
 import androidx.room.compiler.processing.ksp.KSFileAsOriginatingElement
 import androidx.room.compiler.processing.ksp.KspTypeElement
 import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.TypeSpec
 import javax.lang.model.element.ExecutableElement
 import javax.lang.model.element.TypeElement
@@ -57,7 +57,7 @@
             assertThat(originatingElement).isNotNull()
 
             if (it.isKsp) {
-                assertThat(originatingElement).isInstanceOf<KSFileAsOriginatingElement>()
+                assertThat(originatingElement).isInstanceOf(KSFileAsOriginatingElement::class.java)
 
                 val originatingFile = (originatingElement as KSFileAsOriginatingElement).ksFile
                 assertThat(originatingFile)
@@ -65,7 +65,7 @@
                         (element as KspTypeElement).declaration.containingFile
                     )
             } else {
-                assertThat(originatingElement).isInstanceOf<TypeElement>()
+                assertThat(originatingElement).isInstanceOf(TypeElement::class.java)
                 assertThat((originatingElement as TypeElement).qualifiedName.toString())
                     .isEqualTo("foo.bar.Baz")
             }
@@ -83,7 +83,7 @@
 
             if (it.isKsp) {
                 assertThat(originatingElement)
-                    .isInstanceOf<KSClassDeclarationAsOriginatingElement>()
+                    .isInstanceOf(KSClassDeclarationAsOriginatingElement::class.java)
 
                 val ksClassDeclaration =
                     (originatingElement as KSClassDeclarationAsOriginatingElement)
@@ -93,7 +93,7 @@
                         (element as KspTypeElement).declaration
                     )
             } else {
-                assertThat(originatingElement).isInstanceOf<TypeElement>()
+                assertThat(originatingElement).isInstanceOf(TypeElement::class.java)
                 assertThat((originatingElement as TypeElement).qualifiedName.toString())
                     .isEqualTo("com.google.devtools.ksp.processing.SymbolProcessor")
             }
@@ -129,7 +129,7 @@
 
                 if (invocation.isKsp) {
                     assertThat(originatingElement)
-                        .isInstanceOf<KSFileAsOriginatingElement>()
+                        .isInstanceOf(KSFileAsOriginatingElement::class.java)
 
                     val originatingFile = (originatingElement as KSFileAsOriginatingElement).ksFile
                     assertThat(originatingFile)
@@ -138,7 +138,7 @@
                                 .field.declaration.containingFile
                         )
                 } else {
-                    assertThat(originatingElement).isInstanceOf<ExecutableElement>()
+                    assertThat(originatingElement).isInstanceOf(ExecutableElement::class.java)
                 }
             }
         }
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TopLevelMembersTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TopLevelMembersTest.kt
index 754142b..7e364c44 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TopLevelMembersTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TopLevelMembersTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.ksp.KspExecutableElement
 import androidx.room.compiler.processing.ksp.KspFieldElement
 import androidx.room.compiler.processing.util.Source
@@ -24,6 +23,7 @@
 import androidx.room.compiler.processing.util.kspProcessingEnv
 import androidx.room.compiler.processing.util.kspResolver
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertWithMessage
 import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.symbol.KSFunctionDeclaration
 import com.google.devtools.ksp.symbol.KSPropertyDeclaration
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt
index 9639527..517cbd6 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
 import androidx.room.compiler.processing.util.CONTINUATION_JCLASS_NAME
@@ -27,6 +26,7 @@
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.kotlinpoet.LONG
 import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
 import com.squareup.kotlinpoet.javapoet.JParameterizedTypeName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAssignmentTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAssignmentTest.kt
index 1fc6e3a..38444c6 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAssignmentTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAssignmentTest.kt
@@ -16,11 +16,11 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
index 79977bf..4c27a38 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
@@ -16,13 +16,13 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.getParameter
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationBoxTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationBoxTest.kt
index 102650d..7a761a0 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationBoxTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationBoxTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
 import androidx.room.compiler.processing.testcode.JavaAnnotationWithDefaults
@@ -39,7 +37,8 @@
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.compiler.processing.util.runProcessorTestWithoutKsp
 import androidx.room.compiler.processing.util.typeName
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.squareup.javapoet.ClassName
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -172,8 +171,7 @@
                     }
                 annotation.getAsAnnotationBoxArray<OtherAnnotation>("otherAnnotationArray")
                     .let { boxArray ->
-                        // Kruth doesn't support arrays yet
-                        Truth.assertThat(boxArray).hasLength(2)
+                        assertThat(boxArray).hasLength(2)
                         assertThat(boxArray[0].value.value).isEqualTo("other list 1")
                         assertThat(boxArray[1].value.value).isEqualTo("other list 2")
                     }
@@ -272,8 +270,7 @@
                     }
                 annotation.getAsAnnotationBoxArray<OtherAnnotation>("otherAnnotationArray")
                     .let { boxArray ->
-                        // Kruth doesn't support arrays yet
-                        Truth.assertThat(boxArray).hasLength(2)
+                        assertThat(boxArray).hasLength(2)
                         assertThat(boxArray[0].value.value).isEqualTo("other list 1")
                         assertThat(boxArray[1].value.value).isEqualTo("other list 2")
                     }
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
index b25e8f1..8698722 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
 import androidx.room.compiler.processing.compat.XConverters.toJavac
@@ -44,6 +42,8 @@
 import androidx.room.compiler.processing.util.getParameter
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.compiler.processing.util.runProcessorTestWithoutKsp
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.squareup.kotlinpoet.javapoet.JAnnotationSpec
 import com.squareup.kotlinpoet.javapoet.JClassName
 import org.junit.Test
@@ -153,6 +153,40 @@
     }
 
     @Test
+    fun testJvmNameAnnotationValue() {
+        val kotlinSrc = Source.kotlin(
+            "MyAnnotation.kt",
+            """
+            @Target(AnnotationTarget.CLASS)
+            annotation class MyAnnotation(
+                @get:JvmName("stringParameter")
+                val stringParam: String,
+                val intParam: Int,
+                @get:JvmName("longParameter")
+                val longParam: Long
+            )
+            """.trimIndent()
+        )
+        val javaSrc = Source.java(
+            "Foo",
+            """
+            @MyAnnotation(stringParameter = "1", intParam = 2, longParameter = 3)
+            public class Foo {}
+            """.trimIndent()
+        )
+        runTest(sources = listOf(javaSrc, kotlinSrc)) { invocation ->
+            val typeElement = invocation.processingEnv.requireTypeElement("Foo")
+            val annotation =
+                typeElement.getAllAnnotations().single { it.qualifiedName == "MyAnnotation" }
+            assertThat(
+                annotation.annotationValues.map { it.value }
+            ).containsExactly(
+                "1", 2, 3.toLong()
+            ).inOrder()
+        }
+    }
+
+    @Test
     fun readsAnnotationsDeclaredInSources() {
         val source = Source.kotlin(
             "MyClass.kt",
@@ -1389,7 +1423,7 @@
                             .that(type.getAllAnnotationTypeElements())
                             .isEmpty()
                     } else {
-                        assertWithMessage("$desc type: $type")
+                        assertWithMessage("%s type: %s", desc, type.toString())
                             .that(type.getAllAnnotationTypeElements())
                             .containsExactly(a, b)
                         assertWithMessage("$desc type-argument: ${type.typeArguments[0]}")
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt
index 656c3c5..f8b8666 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationValueTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.JArrayTypeName
 import androidx.room.compiler.processing.compat.XConverters.toJavac
 import androidx.room.compiler.processing.util.Source
@@ -25,6 +24,7 @@
 import androidx.room.compiler.processing.util.asKClassName
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.kotlinpoet.ARRAY
 import com.squareup.kotlinpoet.BOOLEAN
 import com.squareup.kotlinpoet.BOOLEAN_ARRAY
@@ -1161,8 +1161,8 @@
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
-            val myEnumJTypeName = JClassName.get("", "test.MyEnum")
-            val myEnumKTypeName = KClassName("", "test.MyEnum")
+            val myEnumJTypeName = JClassName.get("test", "MyEnum")
+            val myEnumKTypeName = KClassName("test", "MyEnum")
 
             fun checkSingleValue(annotationValue: XAnnotationValue, expectedValue: String) {
                 assertThat(annotationValue.valueType.asTypeName().java)
@@ -1517,8 +1517,8 @@
                 """.trimIndent()
             ) as Source.KotlinSource
         ) { invocation ->
-            val aJTypeName = JClassName.get("", "test.A")
-            val aKTypeName = KClassName("", "test.A")
+            val aJTypeName = JClassName.get("test", "A")
+            val aKTypeName = KClassName("test", "A")
 
             fun checkSingleValue(annotationValue: XAnnotationValue, expectedValue: String) {
                 assertThat(annotationValue.valueType.asTypeName().java)
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XArrayTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XArrayTypeTest.kt
index 11397a3..96a2bc9 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XArrayTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XArrayTypeTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.codegen.JArrayTypeName
 import androidx.room.compiler.processing.ksp.KspProcessingEnv
 import androidx.room.compiler.processing.ksp.createTypeReference
@@ -28,6 +26,8 @@
 import androidx.room.compiler.processing.util.kspResolver
 import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
 import com.squareup.kotlinpoet.javapoet.JTypeName
 import com.squareup.kotlinpoet.javapoet.KTypeName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
index 69ce06b..1e47fd0 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.Subject
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
 import androidx.room.compiler.processing.javac.JavacTypeElement
@@ -30,7 +28,6 @@
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.asJClassName
 import androidx.room.compiler.processing.util.compileFiles
-import androidx.room.compiler.processing.util.createXTypeVariableName
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.getParameter
@@ -38,6 +35,7 @@
 import androidx.room.compiler.processing.util.kspResolver
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.compiler.processing.util.runProcessorTestWithoutKsp
+import com.google.common.truth.Truth.assertThat
 import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.symbol.KSFunctionDeclaration
 import com.google.devtools.ksp.symbol.KSPropertyDeclaration
@@ -244,24 +242,24 @@
 
             validateMethodElement(
                 element = it.processingEnv.requireTypeElement("foo.bar.Base"),
-                tTypeName = createXTypeVariableName("T"),
-                rTypeName = createXTypeVariableName("R")
+                tTypeName = XTypeName.getTypeVariableName("T", listOf(XTypeName.ANY_OBJECT)),
+                rTypeName = XTypeName.getTypeVariableName("R", listOf(XTypeName.ANY_OBJECT))
             )
             validateMethodElement(
                 element = it.processingEnv.requireTypeElement("foo.bar.Child"),
-                tTypeName = createXTypeVariableName("T"),
-                rTypeName = createXTypeVariableName("R")
+                tTypeName = XTypeName.getTypeVariableName("T", listOf(XTypeName.ANY_OBJECT)),
+                rTypeName = XTypeName.getTypeVariableName("R", listOf(XTypeName.ANY_OBJECT))
             )
 
             validateMethodTypeAsMemberOf(
                 element = it.processingEnv.requireTypeElement("foo.bar.Base"),
-                tTypeName = createXTypeVariableName("T"),
-                rTypeName = createXTypeVariableName("R")
+                tTypeName = XTypeName.getTypeVariableName("T", listOf(XTypeName.ANY_OBJECT)),
+                rTypeName = XTypeName.getTypeVariableName("R", listOf(XTypeName.ANY_OBJECT))
             )
             validateMethodTypeAsMemberOf(
                 element = it.processingEnv.requireTypeElement("foo.bar.Child"),
                 tTypeName = String::class.asClassName(),
-                rTypeName = createXTypeVariableName("R")
+                rTypeName = XTypeName.getTypeVariableName("R", listOf(XTypeName.ANY_OBJECT))
             )
         }
     }
@@ -930,12 +928,13 @@
             if (inv.isKsp) {
                 getTopLevelFunctionOrPropertyElements(inv, "foo.bar").forEach {
                         elem ->
-                    assertThat(elem.enclosingElement).isFileContainer(precompiled)
+                    assertThat(elem.enclosingElement).isInstanceOf(
+                        getFileContainerClass(precompiled))
                 }
             } else {
                 inv.processingEnv.getTypeElementsFromPackage("foo.bar").forEach {
                         typeElement ->
-                    assertThat(typeElement).isInstanceOf<JavacTypeElement>()
+                    assertThat(typeElement).isInstanceOf(JavacTypeElement::class.java)
                     assertThat(typeElement.enclosingElement).isNull()
 
                     typeElement.getEnclosedElements().forEach { elem ->
@@ -1009,10 +1008,12 @@
         ) { invocation, precompiled ->
             if (invocation.isKsp) {
                 getTopLevelFunctionOrPropertyElements(invocation, "foo.bar").forEach { elem ->
-                    assertThat(elem.closestMemberContainer).isFileContainer(precompiled)
+                    assertThat(elem.closestMemberContainer).isInstanceOf(
+                        getFileContainerClass(precompiled))
                     if (elem is XExecutableElement) {
                         elem.parameters.forEach { p ->
-                            assertThat(p.closestMemberContainer).isFileContainer(precompiled)
+                            assertThat(p.closestMemberContainer).isInstanceOf(
+                                getFileContainerClass(precompiled))
                         }
                     }
                 }
@@ -1130,13 +1131,12 @@
         }
         .filterNotNull()
 
-    private fun Subject<XElement>.isFileContainer(precompiled: Boolean) {
+    private fun getFileContainerClass(precompiled: Boolean) =
         if (precompiled) {
-            isInstanceOf<KspSyntheticFileMemberContainer>()
+            KspSyntheticFileMemberContainer::class.java
         } else {
-            isInstanceOf<KspFileMemberContainer>()
+            KspFileMemberContainer::class.java
         }
-    }
 
     private fun runProcessorTestHelper(
         sources: List<Source>,
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
index a5d61f1..df1e04b 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
 import androidx.room.compiler.processing.util.CONTINUATION_JCLASS_NAME
@@ -25,12 +23,15 @@
 import androidx.room.compiler.processing.util.UNIT_JCLASS_NAME
 import androidx.room.compiler.processing.util.className
 import androidx.room.compiler.processing.util.compileFiles
-import androidx.room.compiler.processing.util.createXTypeVariableName
 import androidx.room.compiler.processing.util.getDeclaredMethodByJvmName
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.getParameter
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.compiler.processing.util.typeName
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import com.google.testing.junit.testparameterinjector.TestParameter
+import com.google.testing.junit.testparameterinjector.TestParameterInjector
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeName
@@ -47,9 +48,8 @@
 import java.io.IOException
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
-@RunWith(JUnit4::class)
+@RunWith(TestParameterInjector::class)
 class XExecutableElementTest {
     @Test
     fun basic() {
@@ -1047,7 +1047,7 @@
                 }
                 element.getDeclaredMethodByJvmName("ext5").let { method ->
                     assertThat(method.parameters[0].type.asTypeName())
-                        .isEqualTo(createXTypeVariableName("T"))
+                        .isEqualTo(XTypeName.getTypeVariableName("T"))
                 }
                 element.getDeclaredMethodByJvmName("ext6").let { method ->
                     assertThat(method.isSuspendFunction()).isTrue()
@@ -1068,7 +1068,7 @@
                     assertThat(method.isAbstract()).isTrue()
                     assertThat(method.isExtensionFunction()).isTrue()
                     assertThat(method.parameters[0].type.asTypeName())
-                        .isEqualTo(createXTypeVariableName("T"))
+                        .isEqualTo(XTypeName.getTypeVariableName("T"))
 
                     val fooImpl = it.processingEnv.requireTypeElement("$pkg.FooImpl")
                     assertThat(method.parameters[0].asMemberOf(fooImpl.type).asTypeName())
@@ -1348,4 +1348,85 @@
             }
         }
     }
+
+    @Test
+    fun parameterNames(
+        @TestParameter isJava: Boolean,
+        @TestParameter isPrecompiled: Boolean,
+        @TestParameter hasParametersFlag: Boolean,
+        @TestParameter hasDebugFlag: Boolean
+    ) {
+        val javaSource = Source.java(
+            "foo.bar.Baz",
+            """
+            package foo.bar;
+            public class Baz {
+                private Baz(String param1) {}
+            }
+            """.trimIndent())
+        val kotlinSource = Source.kotlin(
+            "foo.bar.Baz.kt",
+            """
+            package foo.bar
+            class Baz private constructor(param1: String)
+            """.trimIndent())
+
+        val sources: List<Source> =
+            if (isPrecompiled) {
+                emptyList()
+            } else {
+                if (isJava) {
+                    listOf(javaSource)
+                } else {
+                    listOf(kotlinSource)
+                }
+            }
+        val javacArgs = buildList {
+            if (hasParametersFlag) {
+                // This is used to generate `MethodParameters` in class files
+                add("-parameters")
+            }
+            if (hasDebugFlag) {
+                // This is used to generate `LocalVariableTable` in class files
+                add("-g:vars")
+            }
+        }
+        val classes: List<File> =
+            if (isPrecompiled) {
+                if (isJava) {
+                    compileFiles(listOf(javaSource), javacArguments = javacArgs)
+                } else {
+                    compileFiles(listOf(kotlinSource), javacArguments = javacArgs)
+                }
+            } else {
+                emptyList()
+            }
+        runProcessorTest(sources = sources, classpath = classes) {
+            val element = it.processingEnv.requireTypeElement("foo.bar.Baz")
+            assertThat(element.getConstructors().single().parameters.single().name)
+                .isEqualTo(
+                    if (isJava) {
+                        if (isPrecompiled) {
+                            if (hasParametersFlag) {
+                                "param1"
+                            } else {
+                                if (it.isKsp) {
+                                    "p0"
+                                } else { // Javac/KAPT
+                                    if (hasDebugFlag) {
+                                        "param1"
+                                    } else {
+                                        "arg0"
+                                    }
+                                }
+                            }
+                        } else { // Java sources
+                            "param1"
+                        }
+                    } else { // Kotlin sources or classes
+                        "param1"
+                    }
+                )
+        }
+    }
 }
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableTypeTest.kt
index 95adf50..4c88042 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableTypeTest.kt
@@ -16,14 +16,13 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.CONTINUATION_JCLASS_NAME
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.UNIT_JCLASS_NAME
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.compiler.processing.util.typeName
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeName
@@ -100,7 +99,7 @@
                 vararg subjects: XTypeElement,
                 callback: (XMethodType) -> Unit
             ) {
-                Truth.assertThat(subjects).isNotEmpty() // Kruth doesn't support arrays yet
+                assertThat(subjects).isNotEmpty()
                 subjects.forEach {
                     callback(myInterface.getMethodByJvmName(methodName).asMemberOf(it.type))
                     callback(it.getMethodByJvmName(methodName).asMemberOf(it.type))
@@ -441,7 +440,7 @@
                 vararg subjects: XTypeElement,
                 callback: (XMethodType) -> Unit
             ) {
-                Truth.assertThat(subjects).isNotEmpty() // Kruth doesn't support arrays yet
+                assertThat(subjects).isNotEmpty()
                 subjects.forEach {
                     callback(myInterface.getMethodByJvmName(methodName).asMemberOf(it.type))
                     callback(it.getMethodByJvmName(methodName).asMemberOf(it.type))
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XFilerTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XFilerTest.kt
index 8029095..209d88e 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XFilerTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XFilerTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import kotlin.io.path.Path
 import org.junit.Assert.fail
 import org.junit.Test
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt
index b2556ad..7574266 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import javax.tools.Diagnostic
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XNullabilityTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XNullabilityTest.kt
index 165deab..313e735c 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XNullabilityTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XNullabilityTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XNullability.NONNULL
 import androidx.room.compiler.processing.XNullability.NULLABLE
 import androidx.room.compiler.processing.XNullability.UNKNOWN
@@ -26,6 +25,7 @@
 import androidx.room.compiler.processing.util.getParameter
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.compiler.processing.util.runProcessorTestWithoutKsp
+import com.google.common.truth.Truth.assertThat
 import com.squareup.kotlinpoet.INT
 import com.squareup.kotlinpoet.UNIT
 import com.squareup.kotlinpoet.javapoet.JTypeName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvConfigTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvConfigTest.kt
index 65972b9..037b239 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvConfigTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvConfigTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class XProcessingEnvConfigTest {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
index d2452bd..33ff8fc 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
@@ -16,12 +16,12 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.JavaFile
 import com.squareup.javapoet.TypeName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
index d956499..5e4141e 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor
 import androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor
 import androidx.room.compiler.processing.ksp.KspElement
@@ -31,6 +30,7 @@
 import androidx.room.compiler.processing.util.compiler.compile
 import androidx.room.compiler.processing.util.runProcessorTest
 import com.google.common.truth.Truth.assertAbout
+import com.google.common.truth.Truth.assertThat
 import com.google.devtools.ksp.processing.SymbolProcessor
 import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
 import com.google.devtools.ksp.processing.SymbolProcessorProvider
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRawTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRawTypeTest.kt
index f507ee8..6d6ca5b 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRawTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRawTypeTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeVariableName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt
index ac2658a..eb733a0 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.processing.testcode.OtherAnnotation
@@ -25,6 +23,8 @@
 import androidx.room.compiler.processing.util.getDeclaredMethodByJvmName
 import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.squareup.kotlinpoet.INT
 import com.squareup.kotlinpoet.UNIT
 import com.squareup.kotlinpoet.javapoet.JTypeName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
index 42465dc..e6d31ce 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
@@ -27,12 +25,13 @@
 import androidx.room.compiler.processing.util.asKClassName
 import androidx.room.compiler.processing.util.asMutableKClassName
 import androidx.room.compiler.processing.util.compileFiles
-import androidx.room.compiler.processing.util.createXTypeVariableName
 import androidx.room.compiler.processing.util.getAllFieldNames
 import androidx.room.compiler.processing.util.getDeclaredField
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.squareup.kotlinpoet.INT
 import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
 import com.squareup.kotlinpoet.javapoet.JClassName
@@ -539,7 +538,7 @@
             }
 
             baseClass.getField("genericProp").let { field ->
-                assertThat(field.type.asTypeName()).isEqualTo(createXTypeVariableName("T"))
+                assertThat(field.type.asTypeName()).isEqualTo(XTypeName.getTypeVariableName("T"))
             }
 
             subClass.getField("genericProp").let { field ->
@@ -1910,26 +1909,26 @@
                     method = method,
                     name = "method",
                     enclosingElement = abstractClass,
-                    returnType = createXTypeVariableName("T2"),
+                    returnType = XTypeName.getTypeVariableName("T2"),
                     parameterTypes = arrayOf(
-                        createXTypeVariableName("T1"),
-                        createXTypeVariableName("T2")
+                        XTypeName.getTypeVariableName("T1"),
+                        XTypeName.getTypeVariableName("T2")
                     )
                 )
                 checkMethodType(
                     methodType = method.executableType,
-                    returnType = createXTypeVariableName("T2"),
+                    returnType = XTypeName.getTypeVariableName("T2"),
                     parameterTypes = arrayOf(
-                        createXTypeVariableName("T1"),
-                        createXTypeVariableName("T2")
+                        XTypeName.getTypeVariableName("T1"),
+                        XTypeName.getTypeVariableName("T2")
                     )
                 )
                 checkMethodType(
                     methodType = method.asMemberOf(abstractClass.type),
-                    returnType = createXTypeVariableName("T2"),
+                    returnType = XTypeName.getTypeVariableName("T2"),
                     parameterTypes = arrayOf(
-                        createXTypeVariableName("T1"),
-                        createXTypeVariableName("T2")
+                        XTypeName.getTypeVariableName("T1"),
+                        XTypeName.getTypeVariableName("T2")
                     )
                 )
                 checkMethodType(
@@ -1982,26 +1981,26 @@
                 method = abstractClassMethod,
                 name = "method",
                 enclosingElement = abstractClass,
-                returnType = createXTypeVariableName("T2"),
+                returnType = XTypeName.getTypeVariableName("T2"),
                 parameterTypes = arrayOf(
-                    createXTypeVariableName("T1"),
-                    createXTypeVariableName("T2")
+                    XTypeName.getTypeVariableName("T1"),
+                    XTypeName.getTypeVariableName("T2")
                 )
             )
             checkMethodType(
                 methodType = abstractClassMethod.executableType,
-                returnType = createXTypeVariableName("T2"),
+                returnType = XTypeName.getTypeVariableName("T2"),
                 parameterTypes = arrayOf(
-                    createXTypeVariableName("T1"),
-                    createXTypeVariableName("T2")
+                    XTypeName.getTypeVariableName("T1"),
+                    XTypeName.getTypeVariableName("T2")
                 )
             )
             checkMethodType(
                 methodType = abstractClassMethod.asMemberOf(abstractClass.type),
-                returnType = createXTypeVariableName("T2"),
+                returnType = XTypeName.getTypeVariableName("T2"),
                 parameterTypes = arrayOf(
-                    createXTypeVariableName("T1"),
-                    createXTypeVariableName("T2"),
+                    XTypeName.getTypeVariableName("T1"),
+                    XTypeName.getTypeVariableName("T2"),
                 )
             )
             checkMethodType(
@@ -2089,7 +2088,7 @@
             checkConstructorParameters(
                 typeElement = abstractClass,
                 expectedParameters = arrayOf(
-                    createXTypeVariableName("T")
+                    XTypeName.getTypeVariableName("T")
                 )
             )
             checkConstructorParameters(
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeParameterElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeParameterElementTest.kt
index d14fea3..48a219f 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeParameterElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeParameterElementTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
index 840d390..719fb84 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName.Companion.ANY_OBJECT
 import androidx.room.compiler.codegen.XTypeName.Companion.UNAVAILABLE_KTYPE_NAME
@@ -38,6 +36,8 @@
 import androidx.room.compiler.processing.util.kspResolver
 import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.google.devtools.ksp.getClassDeclarationByName
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
@@ -89,7 +89,12 @@
             if (it.isKsp) {
                 assertThat(type.asTypeName().kotlin).isEqualTo(
                     KClassName("foo.bar", "Parent")
-                        .parameterizedBy(KClassName("", "InputStreamType"))
+                        .parameterizedBy(
+                            KTypeVariableName(
+                                "InputStreamType",
+                                KClassName("java.io", "InputStream")
+                            )
+                        )
                 )
             }
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/compat/XConvertersTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/compat/XConvertersTest.kt
index d229610..a287249 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/compat/XConvertersTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/compat/XConvertersTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.compat
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.compat.XConverters.getProcessingEnv
 import androidx.room.compiler.processing.compat.XConverters.toJavac
@@ -34,6 +33,7 @@
 import androidx.room.compiler.processing.util.runProcessorTest
 import com.google.auto.common.MoreElements
 import com.google.auto.common.MoreTypes
+import com.google.common.truth.Truth.assertThat
 import com.google.devtools.ksp.getDeclaredFunctions
 import com.google.devtools.ksp.processing.impl.KSNameImpl
 import com.squareup.javapoet.ClassName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt
index 86d3822..15156c4 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.room.compiler.processing.javac.kotlin
 
-import androidx.kruth.assertThat
 import com.google.auto.common.MoreElements
 import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
 import com.google.testing.compile.JavaFileObjects
 import com.google.testing.compile.JavaSourcesSubjectFactory
 import com.squareup.javapoet.ArrayTypeName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/KotlinMetadataElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/KotlinMetadataElementTest.kt
index eb676b6..3db463b 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/KotlinMetadataElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/KotlinMetadataElementTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing.javac.kotlin
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.XNullability
 import androidx.room.compiler.processing.XProcessingEnvConfig
 import androidx.room.compiler.processing.javac.JavacProcessingEnv
@@ -27,6 +25,8 @@
 import androidx.room.compiler.processing.util.runJavaProcessorTest
 import androidx.room.compiler.processing.util.runKaptTest
 import androidx.room.compiler.processing.util.sanitizeAsJavaParameterName
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import javax.annotation.processing.ProcessingEnvironment
 import javax.lang.model.element.ExecutableElement
 import javax.lang.model.element.TypeElement
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
index a6e1551..8f9a50a 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XNullability
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.className
@@ -24,6 +23,7 @@
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeExtTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeExtTest.kt
index 05c5504..61eee03 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeExtTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeExtTest.kt
@@ -16,13 +16,13 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.className
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.kspResolver
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.google.devtools.ksp.getDeclaredProperties
 import com.google.devtools.ksp.symbol.KSClassDeclaration
 import com.squareup.javapoet.ClassName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt
index 3053d5e..595d75c 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XMethodType
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.util.Source
@@ -24,6 +23,7 @@
 import androidx.room.compiler.processing.util.getDeclaredMethodByJvmName
 import androidx.room.compiler.processing.util.runKaptTest
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt
index 7e2b275..688c746 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.XFieldElement
 import androidx.room.compiler.processing.ksp.KspFieldElementTest.TestModifier.FINAL
 import androidx.room.compiler.processing.ksp.KspFieldElementTest.TestModifier.PRIVATE
@@ -30,6 +28,8 @@
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.compiler.processing.util.typeName
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeName
 import com.squareup.javapoet.TypeVariableName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFilerTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFilerTest.kt
index 73af6bc..62c1489 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFilerTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFilerTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XAnnotation
 import androidx.room.compiler.processing.XAnnotationValue
 import androidx.room.compiler.processing.XElement
@@ -24,6 +23,7 @@
 import androidx.room.compiler.processing.addOriginatingElement
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
 import com.google.devtools.ksp.processing.CodeGenerator
 import com.google.devtools.ksp.processing.Dependencies
 import com.google.devtools.ksp.symbol.KSClassDeclaration
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt
index a0781bf..2e74202 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XElement
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.isConstructor
@@ -27,6 +26,7 @@
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspProcessingEnvTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspProcessingEnvTest.kt
index eefdb4b..417c63b 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspProcessingEnvTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspProcessingEnvTest.kt
@@ -16,10 +16,10 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.XNullability
 import androidx.room.compiler.processing.util.kspResolver
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.TypeName
 import org.junit.Test
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt
index c4e1e87..be5dea0 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.TypeName
 import kotlin.reflect.KClass
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
index a97fc52..68f7b5f5 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
@@ -16,8 +16,6 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.XExecutableElement
 import androidx.room.compiler.processing.XMethodElement
 import androidx.room.compiler.processing.util.CompilationTestCapabilities
@@ -26,6 +24,8 @@
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.runKaptTest
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.squareup.javapoet.TypeName
 import org.junit.Test
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt
index 1808bb1..9c69e84 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.asClassName
@@ -35,6 +34,7 @@
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import com.squareup.kotlinpoet.TypeVariableName
 import com.squareup.kotlinpoet.UNIT
 import com.squareup.kotlinpoet.javapoet.JClassName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticFileMemberContainerTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticFileMemberContainerTest.kt
index 134aed5..86ea00f 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticFileMemberContainerTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticFileMemberContainerTest.kt
@@ -16,14 +16,14 @@
 
 package androidx.room.compiler.processing.ksp.synthetic
 
-import androidx.kruth.assertThat
-import androidx.kruth.assertWithMessage
 import androidx.room.compiler.processing.ksp.KspFieldElement
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.kspResolver
 import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.symbol.KSPropertyDeclaration
 import org.junit.Test
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/util/PoetTestExt.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/util/PoetTestExt.kt
index 86942af..7de5edb 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/util/PoetTestExt.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/util/PoetTestExt.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.compiler.processing.util
 
-import androidx.room.compiler.codegen.XTypeName
 import com.squareup.kotlinpoet.MUTABLE_COLLECTION
 import com.squareup.kotlinpoet.MUTABLE_ITERABLE
 import com.squareup.kotlinpoet.MUTABLE_LIST
@@ -73,14 +72,6 @@
     else -> this.asKClassName()
 }
 
-// Creates a simple XTypeName wrapping JTypeVariableName and KTypeVariableName without bounds.
-fun createXTypeVariableName(name: String): XTypeName {
-    return XTypeName(
-        java = JTypeVariableName.get(name),
-        kotlin = KTypeVariableName(name)
-    )
-}
-
 /**
  * Dumps the typename with its bounds in a given depth, making tests more readable.
  */
diff --git a/room/room-compiler/build.gradle b/room/room-compiler/build.gradle
index 6d06fe8..6c70d6b 100644
--- a/room/room-compiler/build.gradle
+++ b/room/room-compiler/build.gradle
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 import androidx.build.BuildOnServerKt
 import androidx.build.LibraryType
 import androidx.build.SdkHelperKt
@@ -29,12 +28,6 @@
     id("com.github.johnrengelman.shadow")
 }
 
-def antlrOut = "$buildDir/generated/antlr/grammar-gen/"
-sourceSets {
-    main.java.srcDirs += "src/main/grammar-gen"
-    main.java.srcDirs += antlrOut
-}
-
 configurations {
     /**
      * shadowed is used for dependencies which we jarjar into the library jar instead of adding it
@@ -103,7 +96,6 @@
     implementation(libs.apacheCommonsCodec)
     implementation(libs.intellijAnnotations)
     testImplementation(libs.truth)
-    testImplementation(project(":kruth:kruth"))
     testImplementation(libs.testParameterInjector)
     testImplementation(libs.autoValue) // to access the processor in tests
     testImplementation(libs.autoServiceAnnotations)
@@ -121,23 +113,27 @@
     testImplementation(project(":internal-testutils-common"))
 }
 
-def generateAntlrTask = task("generateAntlrGrammar", type: GenerateAntlrGrammar) {
-    sqliteFile = file("$projectDir/SQLite.g4")
-    antlrClasspath = configurations.compileClasspath
-    outputDirectory = file(antlrOut)
+def generateAntlrTask = tasks.register("generateAntlrGrammar", GenerateAntlrGrammar) { task ->
+    task.getSqliteFile().set(layout.projectDirectory.file("SQLite.g4"))
+    task.getAntlrClasspath().from(configurations.compileClasspath)
+    task.getOutputDirectory().set(layout.buildDirectory.dir("generated/antlr/grammar-gen/"))
+}
+
+sourceSets {
+    main.java.srcDirs += generateAntlrTask.map { it.outputDirectory }
 }
 
 @CacheableTask
 abstract class GenerateAntlrGrammar extends DefaultTask {
     @PathSensitive(PathSensitivity.NONE)
     @InputFile
-    File sqliteFile
+    abstract RegularFileProperty getSqliteFile()
 
     @Classpath
-    FileCollection antlrClasspath
+    abstract ConfigurableFileCollection getAntlrClasspath()
 
     @OutputDirectory
-    File outputDirectory
+    abstract DirectoryProperty getOutputDirectory()
 
     @Inject
     abstract ExecOperations getExecOperations()
@@ -152,10 +148,10 @@
     void generateAntlrGrammar() {
         execOperations.javaexec {
             mainClass.set("org.antlr.v4.Tool")
-            classpath = antlrClasspath
-            args "SQLite.g4",
+            classpath = getAntlrClasspath()
+            args getSqliteFile().asFile.get().absolutePath,
                  "-visitor",
-                 "-o", new File(outputDirectory, "androidx/room/parser").path,
+                 "-o", new File(getOutputDirectory().asFile.get(), "androidx/room/parser").path,
                  "-package", "androidx.room.parser"
         }
     }
@@ -165,23 +161,23 @@
  * Room compiler jarjars some dependencies. This task validates the published artifacts of room
  * compiler to ensure dependencies are properly jarjarred.
  */
-class CheckArtifactTask extends DefaultTask {
+abstract class CheckArtifactTask extends DefaultTask {
     @InputFiles
-    FileCollection artifactInputs = project.objects.fileCollection()
+    abstract ConfigurableFileCollection getArtifactInputs()
     @InputFile
-    File pomFile
+    abstract RegularFileProperty getPomFile()
     @OutputFile
-    File result = new File(project.buildDir, "checkArtifactOutput.txt")
+    abstract RegularFileProperty getResult()
     /**
      * Checks the publish task's artifacts to make sure the classes.jar does include jarjarred
      * antlr classes.
      */
-    def validatePublishTaskOutputs() {
-        if (artifactInputs.files.isEmpty()) {
+    void validatePublishTaskOutputs() {
+        if (getArtifactInputs().files.isEmpty()) {
             throw new GradleException("Couldn't find the classes.jar for the room-compiler " +
                     "artifact. Ensure that publish is setup properly.")
         }
-        artifactInputs.forEach {
+        getArtifactInputs().forEach {
             validateJarContents(it)
         }
     }
@@ -190,7 +186,7 @@
      * Traverses the given jar file, looks for the classes that should be jarjarred and validates
      * their location.
      */
-    def validateJarContents(File jarFile) {
+    static void validateJarContents(File jarFile) {
         Boolean found = false
         ZipFile zip = new ZipFile(jarFile)
         try {
@@ -223,11 +219,12 @@
      * Checks the generated pom file to ensure it does not depend on any jarjarred dependencies
      * but still depends on others.
      */
-    def validatePomTaskOutputs() {
-        if (!pomFile.canRead()) {
+    void validatePomTaskOutputs() {
+        File pom = getPomFile().asFile.get()
+        if (!pom.canRead()) {
             throw new GradleException("Cannot find the pom file for room-compiler")
         }
-        def pomContents = pomFile.newReader().text
+        def pomContents = pom.newReader().text
         if (pomContents.contains("antlr")) {
             throw new GradleException("Room-compiler pom file should not depend on antlr.\n" +
                     "Pom Contents:\n $pomContents")
@@ -239,24 +236,29 @@
     }
 
     @TaskAction
-    def validate() {
-        result.write("fail\n")
+    void validate() {
+        getResult().asFile.get().write("fail\n")
         validatePublishTaskOutputs()
         validatePomTaskOutputs()
         // have a no-op output to make gradle happy w/ input/output checking.
-        result.write("ok\n")
+        getResult().asFile.get().write("ok\n")
     }
 }
 
-def checkArtifactContentsTask = tasks.register("checkArtifactTask", CheckArtifactTask) {
-    def pomTask = (GenerateMavenPom) project.tasks.named("generatePomFileForMavenPublication").get()
-    it.pomFile = pomTask.destination
+def checkArtifactContentsTask = tasks.register("checkArtifact", CheckArtifactTask) { task ->
+    task.getResult().set(layout.buildDirectory.file("checkArtifactOutput.txt"))
+    def pomTask = (TaskProvider<GenerateMavenPom>) project.tasks.named("generatePomFileForMavenPublication")
+    task.getPomFile().set(
+            project.objects.fileProperty().fileProvider(
+                    pomTask.map {  it.destination }
+            )
+    )
 }
 
 afterEvaluate {
     def publishTaskProvider = project.tasks.named("publishMavenPublicationToMavenRepository")
-    checkArtifactContentsTask.configure {
-        it.artifactInputs.from {
+    checkArtifactContentsTask.configure { checkArtifactTask ->
+        checkArtifactTask.getArtifactInputs().from {
             publishTaskProvider.map {
                 ((PublishToMavenRepository) it).getPublication().artifacts.matching {
                     it.classifier == null
@@ -271,11 +273,6 @@
 // make sure we validate published artifacts on the build server.
 BuildOnServerKt.addToBuildOnServer(project, checkArtifactContentsTask)
 
-def tasksThatDependOnAntlr = ["compileKotlin", "sourceJar", "kotlinSourcesJar", "generateKmpDocs"]
-tasks.matching { tasksThatDependOnAntlr.contains(it.name) }.configureEach {
-    it.dependsOn(generateAntlrTask)
-}
-
 tasks.withType(KotlinCompile).configureEach {
     kotlinOptions {
         freeCompilerArgs += [
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
index 1c19e7f..5f216dc 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.ext
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.processing.XMethodElement
@@ -24,6 +23,7 @@
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.compileFiles
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
index 0db9225..346c9fe 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
@@ -16,11 +16,11 @@
 
 package androidx.room.parser
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.processing.XNullability
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class SQLTypeAffinityTest {
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/parser/SqlParserTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/parser/SqlParserTest.kt
index b3e20de..9d07223 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/parser/SqlParserTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/parser/SqlParserTest.kt
@@ -15,7 +15,7 @@
  */
 package androidx.room.parser
 
-import androidx.kruth.assertThat
+import com.google.common.truth.Truth
 import org.hamcrest.CoreMatchers.`is`
 import org.hamcrest.CoreMatchers.not
 import org.hamcrest.MatcherAssert.assertThat
@@ -277,31 +277,31 @@
     @Test
     fun hasTopStarProjection() {
         SqlParser.parse("SELECT * FROM Foo").let {
-            assertThat(it.hasTopStarProjection).isTrue()
+            Truth.assertThat(it.hasTopStarProjection).isTrue()
         }
         SqlParser.parse("SELECT Foo.* FROM Foo").let {
-            assertThat(it.hasTopStarProjection).isTrue()
+            Truth.assertThat(it.hasTopStarProjection).isTrue()
         }
         SqlParser.parse("SELECT 0 as new, Foo.* FROM Foo").let {
-            assertThat(it.hasTopStarProjection).isTrue()
+            Truth.assertThat(it.hasTopStarProjection).isTrue()
         }
         SqlParser.parse("SELECT f.* FROM Foo f").let {
-            assertThat(it.hasTopStarProjection).isTrue()
+            Truth.assertThat(it.hasTopStarProjection).isTrue()
         }
         SqlParser.parse("SELECT id FROM Foo").let {
-            assertThat(it.hasTopStarProjection).isFalse()
+            Truth.assertThat(it.hasTopStarProjection).isFalse()
         }
         SqlParser.parse("SELECT id FROM (SELECT * FROM Foo)").let {
-            assertThat(it.hasTopStarProjection).isFalse()
+            Truth.assertThat(it.hasTopStarProjection).isFalse()
         }
         SqlParser.parse("SELECT COUNT(*) FROM Foo").let {
-            assertThat(it.hasTopStarProjection).isFalse()
+            Truth.assertThat(it.hasTopStarProjection).isFalse()
         }
         SqlParser.parse("SELECT (SELECT * FROM Foo LIMIT 1) == 1 as uno FROM Foo").let {
-            assertThat(it.hasTopStarProjection).isFalse()
+            Truth.assertThat(it.hasTopStarProjection).isFalse()
         }
         SqlParser.parse("INSERT INTO Foo VALUES (:param)").let {
-            assertThat(it.hasTopStarProjection).isNull()
+            Truth.assertThat(it.hasTopStarProjection).isNull()
         }
     }
 
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/CustomConverterProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/CustomConverterProcessorTest.kt
index b3a46be..a4da24b 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/CustomConverterProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/CustomConverterProcessorTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.processor
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.codegen.VisibilityModifier
 import androidx.room.compiler.codegen.XAnnotationSpec
@@ -39,6 +38,7 @@
 import androidx.room.processor.ProcessorErrors.TYPE_CONVERTER_UNBOUND_GENERIC
 import androidx.room.testing.context
 import androidx.room.vo.CustomTypeConverter
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.TypeVariableName
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt
index dd5133d..076ccf0 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.processor
 
 import COMMON
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.isTypeElement
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
@@ -31,6 +30,7 @@
 import androidx.room.vo.Dao
 import androidx.room.vo.ReadQueryMethod
 import androidx.room.vo.Warning
+import com.google.common.truth.Truth
 import createVerifierFromEntitiesAndViews
 import java.io.File
 import org.hamcrest.CoreMatchers.`is`
@@ -277,7 +277,7 @@
             val dbType = invocation.context.processingEnv.requireType(ROOM_DB)
             val daoProcessor =
                 DaoProcessor(invocation.context, dao, dbType, null)
-            assertThat(daoProcessor.context.logger.suppressedWarnings)
+            Truth.assertThat(daoProcessor.context.logger.suppressedWarnings)
                 .containsExactly(Warning.CURSOR_MISMATCH)
         }
     }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt
index c8ce1d7..a4c6126 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.processor
 
 import COMMON
-import androidx.kruth.assertThat
 import androidx.room.DatabaseProcessingStep
 import androidx.room.RoomProcessor
 import androidx.room.compiler.codegen.CodeLanguage
@@ -42,6 +41,7 @@
 import androidx.room.vo.ReadQueryMethod
 import androidx.room.vo.Warning
 import com.google.auto.service.processor.AutoServiceProcessor
+import com.google.common.truth.Truth.assertThat
 import java.io.File
 import java.io.FileOutputStream
 import java.net.URL
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt
index a3f9328..93870ff 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.processor
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.runProcessorTest
@@ -25,6 +24,7 @@
 import androidx.room.testing.context
 import androidx.room.verifier.ColumnInfo
 import androidx.room.vo.DatabaseView
+import com.google.common.truth.Truth.assertThat
 import createVerifierFromEntitiesAndViews
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt
index 32f453f..7f7e12a 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt
@@ -376,7 +376,7 @@
             assertThat(
                 param.type.asTypeName(),
                 `is`(
-                    XClassName.get("foo.bar", "MyClass.MyList").parametrizedBy(
+                    XClassName.get("foo.bar", "MyClass", "MyList").parametrizedBy(
                         CommonTypeNames.STRING, COMMON.USER_TYPE_NAME
                     )
                 )
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
index 6781bb3..c71cc23 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.processor
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.parser.SQLTypeAffinity
@@ -24,6 +23,7 @@
 import androidx.room.vo.Field
 import androidx.room.vo.FieldGetter
 import androidx.room.vo.FieldSetter
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertOrUpsertShortcutMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertOrUpsertShortcutMethodProcessorTest.kt
index fb756e4..d00d449 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertOrUpsertShortcutMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertOrUpsertShortcutMethodProcessorTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.processor
 
 import COMMON
-import androidx.kruth.assertThat
 import androidx.room.Dao
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.codegen.XClassName
@@ -39,6 +38,7 @@
 import androidx.room.solver.shortcut.result.InsertOrUpsertMethodAdapter
 import androidx.room.testing.context
 import androidx.room.vo.InsertOrUpsertShortcutMethod
+import com.google.common.truth.Truth.assertThat
 import kotlin.reflect.KClass
 import org.junit.Test
 
@@ -400,7 +400,7 @@
             val param = insertionUpsertion.parameters.first()
             assertThat(param.type.asTypeName())
                 .isEqualTo(
-                    XClassName.get("foo.bar", "MyClass.MyList").parametrizedBy(
+                    XClassName.get("foo.bar", "MyClass", "MyList").parametrizedBy(
                         CommonTypeNames.STRING, USER_TYPE_NAME
                     )
                 )
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
index 3550ce5..55f7026 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.processor
 
-import androidx.kruth.assertThat
 import androidx.room.Insert
 import androidx.room.OnConflictStrategy
 import androidx.room.compiler.processing.XMethodElement
@@ -26,6 +25,7 @@
 import androidx.room.processor.ProcessorErrors.INSERT_MULTI_PARAM_SINGLE_RETURN_MISMATCH
 import androidx.room.processor.ProcessorErrors.INSERT_SINGLE_PARAM_MULTI_RETURN_MISMATCH
 import androidx.room.vo.InsertionMethod
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
index ec56bef..723aea9 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.processor
 
 import COMMON
-import androidx.kruth.assertThat
 import androidx.room.Embedded
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.processing.XFieldElement
@@ -42,6 +41,7 @@
 import androidx.room.vo.FieldSetter
 import androidx.room.vo.Pojo
 import androidx.room.vo.RelationCollector
+import com.google.common.truth.Truth
 import java.io.File
 import org.hamcrest.CoreMatchers.instanceOf
 import org.hamcrest.CoreMatchers.`is`
@@ -212,7 +212,7 @@
             assertThat(parent.field.name, `is`("myPoint"))
             assertThat(
                 parent.pojo.typeName,
-                `is`(XClassName.get("foo.bar.MyPojo", "Point"))
+                `is`(XClassName.get("foo.bar", "MyPojo", "Point"))
             )
         }
     }
@@ -2092,7 +2092,7 @@
                 it.name
             }
             val stringType = invocation.context.COMMON_TYPES.STRING
-            assertThat(
+            Truth.assertThat(
                 fields["isbn"]?.getter
             ).isEqualTo(
                 FieldGetter(
@@ -2102,7 +2102,7 @@
                     callType = CallType.SYNTHETIC_METHOD
                 )
             )
-            assertThat(
+            Truth.assertThat(
                 fields["isbn"]?.setter
             ).isEqualTo(
                 FieldSetter(
@@ -2113,7 +2113,7 @@
                 )
             )
 
-            assertThat(
+            Truth.assertThat(
                 fields["isbn2"]?.getter
             ).isEqualTo(
                 FieldGetter(
@@ -2123,7 +2123,7 @@
                     callType = CallType.SYNTHETIC_METHOD
                 )
             )
-            assertThat(
+            Truth.assertThat(
                 fields["isbn2"]?.setter
             ).isEqualTo(
                 FieldSetter(
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
index cbb26a4..2fde4d7 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.processor
 
 import COMMON
-import androidx.kruth.assertThat
 import androidx.room.Dao
 import androidx.room.Query
 import androidx.room.compiler.codegen.CodeLanguage
@@ -58,6 +57,7 @@
 import androidx.room.vo.ReadQueryMethod
 import androidx.room.vo.Warning
 import androidx.room.vo.WriteQueryMethod
+import com.google.common.truth.Truth.assertThat
 import createVerifierFromEntitiesAndViews
 import mockElementAndType
 import org.hamcrest.CoreMatchers.hasItem
@@ -335,7 +335,7 @@
                 """
         ) { parsedQuery, invocation ->
             val expected = MUTABLE_LIST.parametrizedBy(
-                XClassName.get("", "T")
+                XTypeName.getTypeVariableName("T", listOf(XTypeName.ANY_OBJECT))
             )
             assertThat(parsedQuery.returnType.asTypeName(), `is`(expected))
             invocation.assertCompilationResult {
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
index e943139..291267e 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
@@ -179,7 +179,7 @@
 
     @Test
     fun pojo() {
-        val pojo = XClassName.get("foo.bar.MyClass", "MyPojo")
+        val pojo = XClassName.get("foo.bar", "MyClass", "MyPojo")
         singleQueryMethod(
             """
                 public class MyPojo {
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
index a5a8112..e7d8207 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.processor
 
 import COMMON
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.codegen.XTypeName.Companion.PRIMITIVE_LONG
@@ -35,6 +34,7 @@
 import androidx.room.vo.Index
 import androidx.room.vo.Pojo
 import androidx.room.vo.columnNames
+import com.google.common.truth.Truth.assertThat
 import org.hamcrest.CoreMatchers.hasItems
 import org.hamcrest.CoreMatchers.`is`
 import org.hamcrest.MatcherAssert.assertThat
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/NullabilityAwareTypeConverterStoreTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/NullabilityAwareTypeConverterStoreTest.kt
index 997f6d3..cfd3ada 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/NullabilityAwareTypeConverterStoreTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/NullabilityAwareTypeConverterStoreTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.solver
 
-import androidx.kruth.assertThat
 import androidx.room.RoomKspProcessor
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.processing.XType
@@ -34,6 +33,7 @@
 import androidx.room.testing.context
 import androidx.room.vo.BuiltInConverterFlags
 import androidx.room.writer.DaoWriter
+import com.google.common.truth.Truth.assertThat
 import javax.tools.Diagnostic
 import org.junit.Rule
 import org.junit.Test
@@ -800,7 +800,7 @@
             )
         ) { invocation ->
             val store = invocation.createStore(*selectedConverters)
-            assertThat(store).isInstanceOf<NullAwareTypeConverterStore>()
+            assertThat(store).isInstanceOf(NullAwareTypeConverterStore::class.java)
             val myClassTypeElement = invocation.processingEnv.requireTypeElement(
                 "MyClass"
             )
@@ -860,7 +860,7 @@
             )
         ) { invocation ->
             val store = invocation.createStore(*selectedConverters)
-            assertThat(store).isInstanceOf<NullAwareTypeConverterStore>()
+            assertThat(store).isInstanceOf(NullAwareTypeConverterStore::class.java)
             val myClassTypeElement = invocation.processingEnv.requireTypeElement(
                 "MyClass"
             )
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
index 53c6258..f5c3ac3 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.solver
 
 import COMMON
-import androidx.kruth.assertThat
 import androidx.paging.DataSource
 import androidx.paging.PagingSource
 import androidx.room.Dao
@@ -77,6 +76,7 @@
 import androidx.room.testing.context
 import androidx.room.vo.BuiltInConverterFlags
 import androidx.room.vo.ReadQueryMethod
+import com.google.common.truth.Truth.assertThat
 import org.hamcrest.CoreMatchers.instanceOf
 import org.hamcrest.CoreMatchers.`is`
 import org.hamcrest.CoreMatchers.notNullValue
@@ -351,7 +351,7 @@
             )
 
             assertThat(adapter).isNotNull()
-            assertThat(adapter).isInstanceOf<UuidColumnTypeAdapter>()
+            assertThat(adapter).isInstanceOf(UuidColumnTypeAdapter::class.java)
         }
     }
 
@@ -1556,7 +1556,7 @@
                     isMultipleParameter = true
                 )
                 assertThat(adapter).isNotNull()
-                assertThat(adapter).isInstanceOf<CollectionQueryParameterAdapter>()
+                assertThat(adapter).isInstanceOf(CollectionQueryParameterAdapter::class.java)
             }
         }
     }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterCostTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterCostTest.kt
index 7029a46..0443054 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterCostTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterCostTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.room.solver
 
-import androidx.kruth.assertThat
 import androidx.room.solver.types.TypeConverter.Cost
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
 class TypeConverterCostTest {
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
index d2fc717..df7480e 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.solver
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runProcessorTest
@@ -26,6 +25,7 @@
 import androidx.room.solver.types.TypeConverter
 import androidx.room.testing.context
 import androidx.room.vo.BuiltInConverterFlags
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/query/QueryWriterTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/query/QueryWriterTest.kt
index 650b393..e334883 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/query/QueryWriterTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/query/QueryWriterTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.solver.query
 
-import androidx.kruth.assertThat
 import androidx.room.Dao
 import androidx.room.Query
 import androidx.room.compiler.codegen.CodeLanguage
@@ -28,6 +27,7 @@
 import androidx.room.processor.QueryMethodProcessor
 import androidx.room.testing.context
 import androidx.room.writer.QueryWriter
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/testing/InProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/testing/InProcessorTest.kt
index b9251a5..e886664 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/testing/InProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/testing/InProcessorTest.kt
@@ -16,10 +16,10 @@
 
 package androidx.room.testing
 
-import androidx.kruth.assertThat
 import androidx.room.compiler.processing.util.CompilationTestCapabilities
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.runProcessorTest
+import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/util/SchemaDifferTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/util/SchemaDifferTest.kt
index 5c766ef..bec007f 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/util/SchemaDifferTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/util/SchemaDifferTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.util
 
-import androidx.kruth.assertThat
 import androidx.room.migration.bundle.DatabaseBundle
 import androidx.room.migration.bundle.EntityBundle
 import androidx.room.migration.bundle.FieldBundle
@@ -27,6 +26,7 @@
 import androidx.room.migration.bundle.TABLE_NAME_PLACEHOLDER
 import androidx.room.processor.ProcessorErrors
 import androidx.room.vo.AutoMigration
+import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.fail
 import org.junit.Test
 
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/util/SimpleJavaVersionTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/util/SimpleJavaVersionTest.kt
index 7c76004..4a2e2f7 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/util/SimpleJavaVersionTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/util/SimpleJavaVersionTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.room.util
 
-import androidx.kruth.assertThat
+import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.fail
 import org.junit.Test
 
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt
index 3ee50134..6d6fcc7 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/DefaultsInDaoTest.kt
@@ -17,7 +17,6 @@
 package androidx.room.writer
 
 import COMMON
-import androidx.kruth.StringSubject
 import androidx.room.compiler.codegen.CodeLanguage
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.util.Source
@@ -25,6 +24,7 @@
 import androidx.room.ext.RoomTypeNames.ROOM_DB
 import androidx.room.processor.DaoProcessor
 import androidx.room.testing.context
+import com.google.common.truth.StringSubject
 import createVerifierFromEntitiesAndViews
 import org.jetbrains.kotlin.config.JvmDefaultMode
 import org.junit.Test
diff --git a/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/AutoMigrationWithProvidedSpec.kt b/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/AutoMigrationWithProvidedSpec.kt
index 647be54..90577fc 100644
--- a/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/AutoMigrationWithProvidedSpec.kt
+++ b/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/AutoMigrationWithProvidedSpec.kt
@@ -5,7 +5,6 @@
 import androidx.sqlite.db.SupportSQLiteDatabase
 import javax.`annotation`.processing.Generated
 import kotlin.Suppress
-import kotlin.Unit
 
 @Generated(value = ["androidx.room.RoomProcessor"])
 @Suppress(names = ["UNCHECKED_CAST", "DEPRECATION", "REDUNDANT_PROJECTION"])
@@ -16,7 +15,7 @@
         this.callback = callback
     }
 
-    public override fun migrate(db: SupportSQLiteDatabase): Unit {
+    public override fun migrate(db: SupportSQLiteDatabase) {
         db.execSQL("ALTER TABLE `Song` ADD COLUMN `artistId` INTEGER DEFAULT NULL")
         callback.onPostMigrate(db)
     }
diff --git a/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithDefault.kt b/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithDefault.kt
index 6b4d52e6..31f43d7 100644
--- a/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithDefault.kt
+++ b/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithDefault.kt
@@ -5,7 +5,6 @@
 import androidx.sqlite.db.SupportSQLiteDatabase
 import javax.`annotation`.processing.Generated
 import kotlin.Suppress
-import kotlin.Unit
 
 @Generated(value = ["androidx.room.RoomProcessor"])
 @Suppress(names = ["UNCHECKED_CAST", "DEPRECATION", "REDUNDANT_PROJECTION"])
@@ -14,7 +13,7 @@
 
     public constructor() : super(1, 2)
 
-    public override fun migrate(db: SupportSQLiteDatabase): Unit {
+    public override fun migrate(db: SupportSQLiteDatabase) {
         db.execSQL("ALTER TABLE `Song` ADD COLUMN `artistId` INTEGER NOT NULL DEFAULT 0")
         callback.onPostMigrate(db)
     }
diff --git a/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithoutDefault.kt b/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithoutDefault.kt
index 93eab8f..f0ffd3a 100644
--- a/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithoutDefault.kt
+++ b/room/room-compiler/src/test/test-data/autoMigrationWriter/output/kotlin/ValidAutoMigrationWithoutDefault.kt
@@ -5,7 +5,6 @@
 import androidx.sqlite.db.SupportSQLiteDatabase
 import javax.`annotation`.processing.Generated
 import kotlin.Suppress
-import kotlin.Unit
 
 @Generated(value = ["androidx.room.RoomProcessor"])
 @Suppress(names = ["UNCHECKED_CAST", "DEPRECATION", "REDUNDANT_PROJECTION"])
@@ -14,7 +13,7 @@
 
     public constructor() : super(1, 2)
 
-    public override fun migrate(db: SupportSQLiteDatabase): Unit {
+    public override fun migrate(db: SupportSQLiteDatabase) {
         db.execSQL("ALTER TABLE `Song` ADD COLUMN `artistId` INTEGER DEFAULT NULL")
         callback.onPostMigrate(db)
     }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx2.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx2.kt
index 32595b7..fd018379 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx2.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx2.kt
@@ -19,7 +19,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -73,7 +72,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -119,7 +118,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -168,7 +167,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -214,7 +213,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -260,7 +259,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -306,7 +305,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -355,7 +354,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -401,7 +400,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx3.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx3.kt
index 07fbdeb5..48492a3 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx3.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/callableQuery_rx3.kt
@@ -19,7 +19,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -73,7 +72,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -119,7 +118,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -168,7 +167,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -214,7 +213,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -260,7 +259,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -306,7 +305,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -355,7 +354,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -401,7 +400,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/coroutines.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/coroutines.kt
index d99e339..3cf1b4c 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/coroutines.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/coroutines.kt
@@ -18,7 +18,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.MutableList
 import kotlin.jvm.JvmStatic
@@ -74,7 +73,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -121,7 +120,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt
index 585f176..442641a 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt
@@ -18,7 +18,6 @@
 import kotlin.Lazy
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.Map
 import kotlin.collections.MutableList
@@ -35,13 +34,13 @@
     protected override fun createOpenHelper(config: DatabaseConfiguration): SupportSQLiteOpenHelper {
         val _openCallback: SupportSQLiteOpenHelper.Callback = RoomOpenHelper(config, object :
             RoomOpenHelper.Delegate(1) {
-            public override fun createAllTables(db: SupportSQLiteDatabase): Unit {
+            public override fun createAllTables(db: SupportSQLiteDatabase) {
                 db.execSQL("CREATE TABLE IF NOT EXISTS `MyEntity` (`pk` INTEGER NOT NULL, PRIMARY KEY(`pk`))")
                 db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)")
                 db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '195d7974660177325bd1a32d2c7b8b8c')")
             }
 
-            public override fun dropAllTables(db: SupportSQLiteDatabase): Unit {
+            public override fun dropAllTables(db: SupportSQLiteDatabase) {
                 db.execSQL("DROP TABLE IF EXISTS `MyEntity`")
                 val _callbacks: List<RoomDatabase.Callback>? = mCallbacks
                 if (_callbacks != null) {
@@ -51,7 +50,7 @@
                 }
             }
 
-            public override fun onCreate(db: SupportSQLiteDatabase): Unit {
+            public override fun onCreate(db: SupportSQLiteDatabase) {
                 val _callbacks: List<RoomDatabase.Callback>? = mCallbacks
                 if (_callbacks != null) {
                     for (_callback: RoomDatabase.Callback in _callbacks) {
@@ -60,7 +59,7 @@
                 }
             }
 
-            public override fun onOpen(db: SupportSQLiteDatabase): Unit {
+            public override fun onOpen(db: SupportSQLiteDatabase) {
                 mDatabase = db
                 internalInitInvalidationTracker(db)
                 val _callbacks: List<RoomDatabase.Callback>? = mCallbacks
@@ -71,11 +70,11 @@
                 }
             }
 
-            public override fun onPreMigrate(db: SupportSQLiteDatabase): Unit {
+            public override fun onPreMigrate(db: SupportSQLiteDatabase) {
                 dropFtsSyncTriggers(db)
             }
 
-            public override fun onPostMigrate(db: SupportSQLiteDatabase): Unit {
+            public override fun onPostMigrate(db: SupportSQLiteDatabase) {
             }
 
             public override fun onValidateSchema(db: SupportSQLiteDatabase):
@@ -113,7 +112,7 @@
         return InvalidationTracker(this, _shadowTablesMap, _viewTables, "MyEntity")
     }
 
-    public override fun clearAllTables(): Unit {
+    public override fun clearAllTables() {
         super.assertNotMainThread()
         val _db: SupportSQLiteDatabase = super.openHelper.writableDatabase
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt
index 6209c74..50eb478 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt
@@ -18,7 +18,6 @@
 import kotlin.Lazy
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.Map
 import kotlin.collections.MutableList
@@ -34,13 +33,13 @@
     protected override fun createOpenHelper(config: DatabaseConfiguration): SupportSQLiteOpenHelper {
         val _openCallback: SupportSQLiteOpenHelper.Callback = RoomOpenHelper(config, object :
             RoomOpenHelper.Delegate(1) {
-            public override fun createAllTables(db: SupportSQLiteDatabase): Unit {
+            public override fun createAllTables(db: SupportSQLiteDatabase) {
                 db.execSQL("CREATE TABLE IF NOT EXISTS `MyEntity` (`pk` INTEGER NOT NULL, PRIMARY KEY(`pk`))")
                 db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)")
                 db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '195d7974660177325bd1a32d2c7b8b8c')")
             }
 
-            public override fun dropAllTables(db: SupportSQLiteDatabase): Unit {
+            public override fun dropAllTables(db: SupportSQLiteDatabase) {
                 db.execSQL("DROP TABLE IF EXISTS `MyEntity`")
                 val _callbacks: List<RoomDatabase.Callback>? = mCallbacks
                 if (_callbacks != null) {
@@ -50,7 +49,7 @@
                 }
             }
 
-            public override fun onCreate(db: SupportSQLiteDatabase): Unit {
+            public override fun onCreate(db: SupportSQLiteDatabase) {
                 val _callbacks: List<RoomDatabase.Callback>? = mCallbacks
                 if (_callbacks != null) {
                     for (_callback: RoomDatabase.Callback in _callbacks) {
@@ -59,7 +58,7 @@
                 }
             }
 
-            public override fun onOpen(db: SupportSQLiteDatabase): Unit {
+            public override fun onOpen(db: SupportSQLiteDatabase) {
                 mDatabase = db
                 internalInitInvalidationTracker(db)
                 val _callbacks: List<RoomDatabase.Callback>? = mCallbacks
@@ -70,11 +69,11 @@
                 }
             }
 
-            public override fun onPreMigrate(db: SupportSQLiteDatabase): Unit {
+            public override fun onPreMigrate(db: SupportSQLiteDatabase) {
                 dropFtsSyncTriggers(db)
             }
 
-            public override fun onPostMigrate(db: SupportSQLiteDatabase): Unit {
+            public override fun onPostMigrate(db: SupportSQLiteDatabase) {
             }
 
             public override fun onValidateSchema(db: SupportSQLiteDatabase):
@@ -112,7 +111,7 @@
         return InvalidationTracker(this, _shadowTablesMap, _viewTables, "MyEntity")
     }
 
-    public override fun clearAllTables(): Unit {
+    public override fun clearAllTables() {
         super.assertNotMainThread()
         val _db: SupportSQLiteDatabase = super.openHelper.writableDatabase
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt
index 8ab3bb8..2ec181a 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt
@@ -6,7 +6,6 @@
 import androidx.room.migration.Migration
 import androidx.room.util.FtsTableInfo
 import androidx.room.util.TableInfo
-import androidx.room.util.TableInfo.Companion.read
 import androidx.room.util.ViewInfo
 import androidx.room.util.dropFtsSyncTriggers
 import androidx.sqlite.db.SupportSQLiteDatabase
@@ -21,11 +20,13 @@
 import kotlin.Lazy
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.Map
 import kotlin.collections.MutableList
 import kotlin.collections.Set
+import androidx.room.util.FtsTableInfo.Companion.read as ftsTableInfoRead
+import androidx.room.util.TableInfo.Companion.read as tableInfoRead
+import androidx.room.util.ViewInfo.Companion.read as viewInfoRead
 
 @Generated(value = ["androidx.room.RoomProcessor"])
 @Suppress(names = ["UNCHECKED_CAST", "DEPRECATION", "REDUNDANT_PROJECTION"])
@@ -34,10 +35,11 @@
         MyDao_Impl(this)
     }
 
+
     protected override fun createOpenHelper(config: DatabaseConfiguration): SupportSQLiteOpenHelper {
         val _openCallback: SupportSQLiteOpenHelper.Callback = RoomOpenHelper(config, object :
             RoomOpenHelper.Delegate(1) {
-            public override fun createAllTables(db: SupportSQLiteDatabase): Unit {
+            public override fun createAllTables(db: SupportSQLiteDatabase) {
                 db.execSQL("CREATE TABLE IF NOT EXISTS `MyParentEntity` (`parentKey` INTEGER NOT NULL, PRIMARY KEY(`parentKey`))")
                 db.execSQL("CREATE TABLE IF NOT EXISTS `MyEntity` (`pk` INTEGER NOT NULL, `indexedCol` TEXT NOT NULL, PRIMARY KEY(`pk`), FOREIGN KEY(`indexedCol`) REFERENCES `MyParentEntity`(`parentKey`) ON UPDATE NO ACTION ON DELETE CASCADE )")
                 db.execSQL("CREATE INDEX IF NOT EXISTS `index_MyEntity_indexedCol` ON `MyEntity` (`indexedCol`)")
@@ -47,7 +49,7 @@
                 db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '89ba16fb8b062b50acf0eb06c853efcb')")
             }
 
-            public override fun dropAllTables(db: SupportSQLiteDatabase): Unit {
+            public override fun dropAllTables(db: SupportSQLiteDatabase) {
                 db.execSQL("DROP TABLE IF EXISTS `MyParentEntity`")
                 db.execSQL("DROP TABLE IF EXISTS `MyEntity`")
                 db.execSQL("DROP TABLE IF EXISTS `MyFtsEntity`")
@@ -60,7 +62,7 @@
                 }
             }
 
-            public override fun onCreate(db: SupportSQLiteDatabase): Unit {
+            public override fun onCreate(db: SupportSQLiteDatabase) {
                 val _callbacks: List<RoomDatabase.Callback>? = mCallbacks
                 if (_callbacks != null) {
                     for (_callback: RoomDatabase.Callback in _callbacks) {
@@ -69,7 +71,7 @@
                 }
             }
 
-            public override fun onOpen(db: SupportSQLiteDatabase): Unit {
+            public override fun onOpen(db: SupportSQLiteDatabase) {
                 mDatabase = db
                 db.execSQL("PRAGMA foreign_keys = ON")
                 internalInitInvalidationTracker(db)
@@ -81,11 +83,11 @@
                 }
             }
 
-            public override fun onPreMigrate(db: SupportSQLiteDatabase): Unit {
+            public override fun onPreMigrate(db: SupportSQLiteDatabase) {
                 dropFtsSyncTriggers(db)
             }
 
-            public override fun onPostMigrate(db: SupportSQLiteDatabase): Unit {
+            public override fun onPostMigrate(db: SupportSQLiteDatabase) {
             }
 
             public override fun onValidateSchema(db: SupportSQLiteDatabase):
@@ -99,15 +101,15 @@
                 val _indicesMyParentEntity: HashSet<TableInfo.Index> = HashSet<TableInfo.Index>(0)
                 val _infoMyParentEntity: TableInfo = TableInfo("MyParentEntity", _columnsMyParentEntity,
                     _foreignKeysMyParentEntity, _indicesMyParentEntity)
-                val _existingMyParentEntity: TableInfo = read(db, "MyParentEntity")
+                val _existingMyParentEntity: TableInfo = tableInfoRead(db, "MyParentEntity")
                 if (!_infoMyParentEntity.equals(_existingMyParentEntity)) {
                     return RoomOpenHelper.ValidationResult(false, """
-                  |MyParentEntity(MyParentEntity).
-                  | Expected:
-                  |""".trimMargin() + _infoMyParentEntity + """
-                  |
-                  | Found:
-                  |""".trimMargin() + _existingMyParentEntity)
+              |MyParentEntity(MyParentEntity).
+              | Expected:
+              |""".trimMargin() + _infoMyParentEntity + """
+              |
+              | Found:
+              |""".trimMargin() + _existingMyParentEntity)
                 }
                 val _columnsMyEntity: HashMap<String, TableInfo.Column> =
                     HashMap<String, TableInfo.Column>(2)
@@ -123,41 +125,41 @@
                     listOf("indexedCol"), listOf("ASC")))
                 val _infoMyEntity: TableInfo = TableInfo("MyEntity", _columnsMyEntity, _foreignKeysMyEntity,
                     _indicesMyEntity)
-                val _existingMyEntity: TableInfo = read(db, "MyEntity")
+                val _existingMyEntity: TableInfo = tableInfoRead(db, "MyEntity")
                 if (!_infoMyEntity.equals(_existingMyEntity)) {
                     return RoomOpenHelper.ValidationResult(false, """
-                  |MyEntity(MyEntity).
-                  | Expected:
-                  |""".trimMargin() + _infoMyEntity + """
-                  |
-                  | Found:
-                  |""".trimMargin() + _existingMyEntity)
+              |MyEntity(MyEntity).
+              | Expected:
+              |""".trimMargin() + _infoMyEntity + """
+              |
+              | Found:
+              |""".trimMargin() + _existingMyEntity)
                 }
                 val _columnsMyFtsEntity: HashSet<String> = HashSet<String>(2)
                 _columnsMyFtsEntity.add("text")
                 val _infoMyFtsEntity: FtsTableInfo = FtsTableInfo("MyFtsEntity", _columnsMyFtsEntity,
                     "CREATE VIRTUAL TABLE IF NOT EXISTS `MyFtsEntity` USING FTS4(`text` TEXT NOT NULL)")
-                val _existingMyFtsEntity: FtsTableInfo = FtsTableInfo.Companion.read(db, "MyFtsEntity")
+                val _existingMyFtsEntity: FtsTableInfo = ftsTableInfoRead(db, "MyFtsEntity")
                 if (!_infoMyFtsEntity.equals(_existingMyFtsEntity)) {
                     return RoomOpenHelper.ValidationResult(false, """
-                  |MyFtsEntity(MyFtsEntity).
-                  | Expected:
-                  |""".trimMargin() + _infoMyFtsEntity + """
-                  |
-                  | Found:
-                  |""".trimMargin() + _existingMyFtsEntity)
+              |MyFtsEntity(MyFtsEntity).
+              | Expected:
+              |""".trimMargin() + _infoMyFtsEntity + """
+              |
+              | Found:
+              |""".trimMargin() + _existingMyFtsEntity)
                 }
                 val _infoMyView: ViewInfo = ViewInfo("MyView",
                     "CREATE VIEW `MyView` AS SELECT text FROM MyFtsEntity")
-                val _existingMyView: ViewInfo = ViewInfo.Companion.read(db, "MyView")
+                val _existingMyView: ViewInfo = viewInfoRead(db, "MyView")
                 if (!_infoMyView.equals(_existingMyView)) {
                     return RoomOpenHelper.ValidationResult(false, """
-                  |MyView(MyView).
-                  | Expected:
-                  |""".trimMargin() + _infoMyView + """
-                  |
-                  | Found:
-                  |""".trimMargin() + _existingMyView)
+              |MyView(MyView).
+              | Expected:
+              |""".trimMargin() + _infoMyView + """
+              |
+              | Found:
+              |""".trimMargin() + _existingMyView)
                 }
                 return RoomOpenHelper.ValidationResult(true, null)
             }
@@ -179,7 +181,7 @@
             "MyParentEntity","MyEntity","MyFtsEntity")
     }
 
-    public override fun clearAllTables(): Unit {
+    public override fun clearAllTables() {
         super.assertNotMainThread()
         val _db: SupportSQLiteDatabase = super.openHelper.writableDatabase
         val _supportsDeferForeignKeys: Boolean = android.os.Build.VERSION.SDK_INT >=
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/deleteOrUpdateMethodAdapter.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/deleteOrUpdateMethodAdapter.kt
index 1166ce2..233b23a 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/deleteOrUpdateMethodAdapter.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/deleteOrUpdateMethodAdapter.kt
@@ -6,7 +6,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -25,7 +24,7 @@
         this.__deletionAdapterOfMyEntity = object : EntityDeletionOrUpdateAdapter<MyEntity>(__db) {
             public override fun createQuery(): String = "DELETE FROM `MyEntity` WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk)
             }
         }
@@ -33,7 +32,7 @@
             public override fun createQuery(): String =
                 "UPDATE OR ABORT `MyEntity` SET `pk` = ?,`data` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk)
                 statement.bindString(2, entity.data)
                 statement.bindLong(3, entity.pk)
@@ -41,7 +40,7 @@
         }
     }
 
-    public override fun deleteEntity(item: MyEntity): Unit {
+    public override fun deleteEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
@@ -65,7 +64,7 @@
         }
     }
 
-    public override fun updateEntity(item: MyEntity): Unit {
+    public override fun updateEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt
index e823e0a..d00f043 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt
@@ -13,7 +13,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -31,7 +30,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`valuePrimitive`,`valueBoolean`,`valueString`,`valueNullableString`,`variablePrimitive`,`variableNullableBoolean`,`variableString`,`variableNullableString`) VALUES (?,?,?,?,?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.valuePrimitive)
                 val _tmp: Int = if (entity.valueBoolean) 1 else 0
                 statement.bindLong(2, _tmp.toLong())
@@ -61,7 +60,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable.kt
index 7a118e5..3d51fc4 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable.kt
@@ -22,7 +22,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -46,7 +45,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -54,7 +53,7 @@
         this.__deletionAdapterOfMyEntity = object : EntityDeletionOrUpdateAdapter<MyEntity>(__db) {
             public override fun createQuery(): String = "DELETE FROM `MyEntity` WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
             }
         }
@@ -62,7 +61,7 @@
             public override fun createQuery(): String =
                 "UPDATE OR ABORT `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
@@ -73,7 +72,7 @@
             public override fun createQuery(): String =
                 "INSERT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -81,7 +80,7 @@
             public override fun createQuery(): String =
                 "UPDATE `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/insertOrUpsertMethodAdapter.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/insertOrUpsertMethodAdapter.kt
index 9f9874c..246af07 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/insertOrUpsertMethodAdapter.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/insertOrUpsertMethodAdapter.kt
@@ -9,7 +9,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -29,7 +28,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`data`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk)
                 statement.bindString(2, entity.data)
             }
@@ -39,7 +38,7 @@
             public override fun createQuery(): String =
                 "INSERT INTO `MyEntity` (`pk`,`data`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk)
                 statement.bindString(2, entity.data)
             }
@@ -47,7 +46,7 @@
             public override fun createQuery(): String =
                 "UPDATE `MyEntity` SET `pk` = ?,`data` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk)
                 statement.bindString(2, entity.data)
                 statement.bindLong(3, entity.pk)
@@ -55,7 +54,7 @@
         })
     }
 
-    public override fun insertEntity(item: MyEntity): Unit {
+    public override fun insertEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
@@ -90,7 +89,7 @@
         }
     }
 
-    public override fun upsertEntity(item: MyEntity): Unit {
+    public override fun upsertEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/liveDataCallable.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/liveDataCallable.kt
index aad53d7..ed6eb98 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/liveDataCallable.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/liveDataCallable.kt
@@ -14,7 +14,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -69,7 +68,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
@@ -116,7 +115,7 @@
                 }
             }
 
-            protected fun finalize(): Unit {
+            protected fun finalize() {
                 _statement.release()
             }
         })
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/multiTypedPagingSourceResultBinder.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/multiTypedPagingSourceResultBinder.kt
index 921b262..70659ef 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/multiTypedPagingSourceResultBinder.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/multiTypedPagingSourceResultBinder.kt
@@ -1,13 +1,11 @@
 import android.database.Cursor
 import androidx.paging.ListenableFuturePagingSource
 import androidx.paging.PagingSource
-import androidx.paging.rxjava2.RxPagingSource
 import androidx.room.RoomDatabase
 import androidx.room.RoomSQLiteQuery
 import androidx.room.RoomSQLiteQuery.Companion.acquire
 import androidx.room.paging.LimitOffsetPagingSource
 import androidx.room.paging.guava.LimitOffsetListenableFuturePagingSource
-import androidx.room.paging.rxjava2.LimitOffsetRxPagingSource
 import java.lang.Class
 import java.util.ArrayList
 import javax.`annotation`.processing.Generated
@@ -17,6 +15,10 @@
 import kotlin.collections.List
 import kotlin.collections.MutableList
 import kotlin.jvm.JvmStatic
+import androidx.paging.rxjava2.RxPagingSource as Rxjava2RxPagingSource
+import androidx.paging.rxjava3.RxPagingSource as Rxjava3RxPagingSource
+import androidx.room.paging.rxjava2.LimitOffsetRxPagingSource as Rxjava2LimitOffsetRxPagingSource
+import androidx.room.paging.rxjava3.LimitOffsetRxPagingSource as Rxjava3LimitOffsetRxPagingSource
 
 @Generated(value = ["androidx.room.RoomProcessor"])
 @Suppress(names = ["UNCHECKED_CAST", "DEPRECATION", "REDUNDANT_PROJECTION"])
@@ -47,10 +49,10 @@
         }
     }
 
-    public override fun getAllIdsRx2(): RxPagingSource<Int, MyEntity> {
+    public override fun getAllIdsRx2(): Rxjava2RxPagingSource<Int, MyEntity> {
         val _sql: String = "SELECT pk FROM MyEntity"
         val _statement: RoomSQLiteQuery = acquire(_sql, 0)
-        return object : LimitOffsetRxPagingSource<MyEntity>(_statement, __db, "MyEntity") {
+        return object : Rxjava2LimitOffsetRxPagingSource<MyEntity>(_statement, __db, "MyEntity") {
             protected override fun convertRows(cursor: Cursor): List<MyEntity> {
                 val _cursorIndexOfPk: Int = 0
                 val _result: MutableList<MyEntity> = ArrayList<MyEntity>(cursor.getCount())
@@ -66,11 +68,10 @@
         }
     }
 
-    public override fun getAllIdsRx3(): androidx.paging.rxjava3.RxPagingSource<Int, MyEntity> {
+    public override fun getAllIdsRx3(): Rxjava3RxPagingSource<Int, MyEntity> {
         val _sql: String = "SELECT pk FROM MyEntity"
         val _statement: RoomSQLiteQuery = acquire(_sql, 0)
-        return object : androidx.room.paging.rxjava3.LimitOffsetRxPagingSource<MyEntity>(_statement,
-            __db, "MyEntity") {
+        return object : Rxjava3LimitOffsetRxPagingSource<MyEntity>(_statement, __db, "MyEntity") {
             protected override fun convertRows(cursor: Cursor): List<MyEntity> {
                 val _cursorIndexOfPk: Int = 0
                 val _result: MutableList<MyEntity> = ArrayList<MyEntity>(cursor.getCount())
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt
index e4aa4f3..0c57f0e 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt
@@ -12,7 +12,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -30,7 +29,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`boolean`,`nullableBoolean`) VALUES (?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: Int = if (entity.boolean) 1 else 0
                 statement.bindLong(2, _tmp.toLong())
@@ -45,7 +44,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt
index 284798e..f369507 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt
@@ -12,7 +12,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -30,7 +29,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`byteArray`,`nullableByteArray`) VALUES (?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindBlob(2, entity.byteArray)
                 val _tmpNullableByteArray: ByteArray? = entity.nullableByteArray
@@ -43,7 +42,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter.kt
index 709f270..6e7794e 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter.kt
@@ -11,7 +11,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -31,7 +30,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`foo`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: String = __fooConverter.toString(entity.foo)
                 statement.bindString(2, _tmp)
@@ -39,7 +38,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_composite.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_composite.kt
index 71d915e..96566e6 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_composite.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_composite.kt
@@ -11,7 +11,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -29,7 +28,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`bar`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: Foo = FooBarConverter.toFoo(entity.bar)
                 val _tmp_1: String = FooBarConverter.toString(_tmp)
@@ -38,7 +37,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_internalVisibility.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_internalVisibility.kt
index 9376fc3..0ba6f82 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_internalVisibility.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_internalVisibility.kt
@@ -11,7 +11,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -31,7 +30,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`foo`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: String = __fooConverter.toString(entity.foo)
                 statement.bindString(2, _tmp)
@@ -39,7 +38,7 @@
         }
     }
 
-    internal override fun addEntity(item: MyEntity): Unit {
+    internal override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_nullAware.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_nullAware.kt
index a52bf88..0ea0420 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_nullAware.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_nullAware.kt
@@ -11,7 +11,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -29,7 +28,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`foo`,`bar`) VALUES (?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: String? = FooBarConverter.toString(entity.foo)
                 if (_tmp == null) {
@@ -48,7 +47,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_provided.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_provided.kt
index a464f74..3895395 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_provided.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_provided.kt
@@ -12,7 +12,6 @@
 import kotlin.Lazy
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -35,7 +34,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`foo`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: String = __fooConverter().toString(entity.foo)
                 statement.bindString(2, _tmp)
@@ -43,7 +42,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_upcast.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_upcast.kt
index 56fb164..e9eebbc 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_upcast.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_customTypeConverter_upcast.kt
@@ -11,7 +11,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -29,7 +28,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`foo`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: String = FooConverter.nullableFooToString(entity.foo)
                 if (_tmp == null) {
@@ -41,7 +40,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_embedded.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_embedded.kt
index 7986fc1..b9a01bc 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_embedded.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_embedded.kt
@@ -12,7 +12,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -30,7 +29,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`numberData`,`stringData`,`nullablenumberData`,`nullablestringData`) VALUES (?,?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmpFoo: Foo = entity.foo
                 statement.bindLong(2, _tmpFoo.numberData)
@@ -47,7 +46,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt
index 25aa37e..a6f83a7 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt
@@ -12,7 +12,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -30,7 +29,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`enum`,`nullableEnum`) VALUES (?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, __Fruit_enumToString(entity.enum))
                 val _tmpNullableEnum: Fruit? = entity.nullableEnum
@@ -43,7 +42,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_internalVisibility.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_internalVisibility.kt
index a81a93e..db1f98c 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_internalVisibility.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_internalVisibility.kt
@@ -12,7 +12,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -30,7 +29,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`internalVal`,`internalVar`,`internalSetterVar`) VALUES (?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindLong(2, entity.internalVal)
                 statement.bindLong(3, entity.internalVar)
@@ -39,7 +38,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_otherModule.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_otherModule.kt
index 8b4945d..320a33b 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_otherModule.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_otherModule.kt
@@ -12,7 +12,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -30,7 +29,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`primitive`,`string`,`nullableString`,`fieldString`,`nullableFieldString`,`variablePrimitive`,`variableString`,`variableNullableString`,`variableFieldString`,`variableNullableFieldString`) VALUES (?,?,?,?,?,?,?,?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindLong(2, entity.primitive)
                 statement.bindString(3, entity.string)
@@ -66,7 +65,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives.kt
index 28ed7ee..520ecbb 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives.kt
@@ -17,7 +17,6 @@
 import kotlin.Short
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -35,7 +34,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`int`,`short`,`byte`,`long`,`char`,`float`,`double`) VALUES (?,?,?,?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.int.toLong())
                 statement.bindLong(2, entity.short.toLong())
                 statement.bindLong(3, entity.byte.toLong())
@@ -47,7 +46,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt
index 3ec68d0..109df70 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt
@@ -17,7 +17,6 @@
 import kotlin.Short
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -35,7 +34,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`int`,`short`,`byte`,`long`,`char`,`float`,`double`) VALUES (?,?,?,?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 val _tmpInt: Int? = entity.int
                 if (_tmpInt == null) {
                     statement.bindNull(1)
@@ -82,7 +81,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt
index 0a4b23b..213539a 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt
@@ -11,7 +11,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -29,7 +28,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`string`,`nullableString`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindString(1, entity.string)
                 val _tmpNullableString: String? = entity.nullableString
                 if (_tmpNullableString == null) {
@@ -41,7 +40,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt
index dd7f1df..a4770df 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt
@@ -14,7 +14,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -32,7 +31,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`uuid`,`nullableUuid`) VALUES (?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindBlob(2, convertUUIDToByte(entity.uuid))
                 val _tmpNullableUuid: UUID? = entity.nullableUuid
@@ -45,7 +44,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_valueClassConverter.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_valueClassConverter.kt
index 501c3ed..6ea9026 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_valueClassConverter.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_valueClassConverter.kt
@@ -15,7 +15,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -33,7 +32,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`uuidData`,`nullableUuidData`,`nullableLongData`,`doubleNullableLongData`,`genericData`) VALUES (?,?,?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 val _data: Long = checkNotNull(entity.pk.data) {
                     "Cannot bind nullable value of inline class to a NOT NULL column." }
                 statement.bindLong(1, _data)
@@ -64,7 +63,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty.kt
index ea44a4f..6276d06 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty.kt
@@ -11,7 +11,6 @@
 import kotlin.Int
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -29,7 +28,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`variablePrimitive`,`variableString`,`variableNullableString`) VALUES (?,?,?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindLong(2, entity.variablePrimitive)
                 statement.bindString(3, entity.variableString)
@@ -43,7 +42,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt
index 9ffae96..127eb24 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt
@@ -12,7 +12,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -30,7 +29,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`mValue`,`mNullableValue`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.getValue())
                 val _tmpMNullableValue: String? = entity.getNullableValue()
                 if (_tmpMNullableValue == null) {
@@ -42,7 +41,7 @@
         }
     }
 
-    public override fun addEntity(item: MyEntity): Unit {
+    public override fun addEntity(item: MyEntity) {
         __db.assertNotSuspendingTransaction()
         __db.beginTransaction()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/preparedQueryAdapter.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/preparedQueryAdapter.kt
index 8ce5067..687bc16 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/preparedQueryAdapter.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/preparedQueryAdapter.kt
@@ -7,7 +7,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -53,7 +52,7 @@
         }
     }
 
-    public override fun insertEntity(id: Long): Unit {
+    public override fun insertEntity(id: Long) {
         __db.assertNotSuspendingTransaction()
         val _stmt: SupportSQLiteStatement = __preparedStmtOfInsertEntity.acquire()
         var _argIndex: Int = 1
@@ -90,7 +89,7 @@
         }
     }
 
-    public override fun updateEntity(text: String): Unit {
+    public override fun updateEntity(text: String) {
         __db.assertNotSuspendingTransaction()
         val _stmt: SupportSQLiteStatement = __preparedStmtOfUpdateEntity.acquire()
         var _argIndex: Int = 1
@@ -129,7 +128,7 @@
         }
     }
 
-    public override fun deleteEntity(): Unit {
+    public override fun deleteEntity() {
         __db.assertNotSuspendingTransaction()
         val _stmt: SupportSQLiteStatement = __preparedStmtOfDeleteEntity.acquire()
         try {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations.kt
index e2a614c..cf8c543 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations.kt
@@ -17,7 +17,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.Set
 import kotlin.jvm.JvmStatic
@@ -150,7 +149,7 @@
         }
     }
 
-    private fun __fetchRelationshipArtistAsArtist(_map: HashMap<Long, Artist?>): Unit {
+    private fun __fetchRelationshipArtistAsArtist(_map: HashMap<Long, Artist?>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
@@ -197,7 +196,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong(_map: HashMap<Long, ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong(_map: HashMap<Long, ArrayList<Song>>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
@@ -248,7 +247,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong_1(_map: HashMap<Long, ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong_1(_map: HashMap<Long, ArrayList<Song>>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_arrayMap.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_arrayMap.kt
index e4c901e..7d2189f 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_arrayMap.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_arrayMap.kt
@@ -17,7 +17,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.Set
 import kotlin.jvm.JvmStatic
@@ -150,7 +149,7 @@
         }
     }
 
-    private fun __fetchRelationshipArtistAsArtist(_map: ArrayMap<Long, Artist?>): Unit {
+    private fun __fetchRelationshipArtistAsArtist(_map: ArrayMap<Long, Artist?>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
@@ -197,7 +196,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong(_map: ArrayMap<Long, ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong(_map: ArrayMap<Long, ArrayList<Song>>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
@@ -248,7 +247,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong_1(_map: ArrayMap<Long, ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong_1(_map: ArrayMap<Long, ArrayList<Song>>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_byteBufferKey.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_byteBufferKey.kt
index 576dfdc..c8e642f 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_byteBufferKey.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_byteBufferKey.kt
@@ -18,7 +18,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.Set
 import kotlin.jvm.JvmStatic
@@ -75,7 +74,7 @@
         }
     }
 
-    private fun __fetchRelationshipArtistAsArtist(_map: HashMap<ByteBuffer, Artist?>): Unit {
+    private fun __fetchRelationshipArtistAsArtist(_map: HashMap<ByteBuffer, Artist?>) {
         val __mapKeySet: Set<ByteBuffer> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_longSparseArray.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_longSparseArray.kt
index 3100619..0a73c03 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_longSparseArray.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_longSparseArray.kt
@@ -17,7 +17,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -149,7 +148,7 @@
         }
     }
 
-    private fun __fetchRelationshipArtistAsArtist(_map: LongSparseArray<Artist?>): Unit {
+    private fun __fetchRelationshipArtistAsArtist(_map: LongSparseArray<Artist?>) {
         if (_map.isEmpty()) {
             return
         }
@@ -196,7 +195,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong(_map: LongSparseArray<ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong(_map: LongSparseArray<ArrayList<Song>>) {
         if (_map.isEmpty()) {
             return
         }
@@ -247,7 +246,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong_1(_map: LongSparseArray<ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong_1(_map: LongSparseArray<ArrayList<Song>>) {
         if (_map.isEmpty()) {
             return
         }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_nullable.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_nullable.kt
index 5ab786c..4618226 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_nullable.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/relations_nullable.kt
@@ -17,7 +17,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.collections.Set
 import kotlin.jvm.JvmStatic
@@ -165,7 +164,7 @@
         }
     }
 
-    private fun __fetchRelationshipArtistAsArtist(_map: HashMap<Long, Artist?>): Unit {
+    private fun __fetchRelationshipArtistAsArtist(_map: HashMap<Long, Artist?>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
@@ -212,7 +211,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong(_map: HashMap<Long, ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong(_map: HashMap<Long, ArrayList<Song>>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
@@ -273,7 +272,7 @@
         }
     }
 
-    private fun __fetchRelationshipSongAsSong_1(_map: HashMap<Long, ArrayList<Song>>): Unit {
+    private fun __fetchRelationshipSongAsSong_1(_map: HashMap<Long, ArrayList<Song>>) {
         val __mapKeySet: Set<Long> = _map.keys
         if (__mapKeySet.isEmpty()) {
             return
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx2.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx2.kt
index 57294c6..dd1a9ca 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx2.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx2.kt
@@ -13,7 +13,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -37,7 +36,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -45,7 +44,7 @@
         this.__deletionAdapterOfMyEntity = object : EntityDeletionOrUpdateAdapter<MyEntity>(__db) {
             public override fun createQuery(): String = "DELETE FROM `MyEntity` WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
             }
         }
@@ -53,7 +52,7 @@
             public override fun createQuery(): String =
                 "UPDATE OR ABORT `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
@@ -64,7 +63,7 @@
             public override fun createQuery(): String =
                 "INSERT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -72,7 +71,7 @@
             public override fun createQuery(): String =
                 "UPDATE `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx3.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx3.kt
index 614e7de..bbab573 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx3.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_rx3.kt
@@ -13,7 +13,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -37,7 +36,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -45,7 +44,7 @@
         this.__deletionAdapterOfMyEntity = object : EntityDeletionOrUpdateAdapter<MyEntity>(__db) {
             public override fun createQuery(): String = "DELETE FROM `MyEntity` WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
             }
         }
@@ -53,7 +52,7 @@
             public override fun createQuery(): String =
                 "UPDATE OR ABORT `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
@@ -64,7 +63,7 @@
             public override fun createQuery(): String =
                 "INSERT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -72,7 +71,7 @@
             public override fun createQuery(): String =
                 "UPDATE `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_suspend.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_suspend.kt
index 01c90ca..3658985 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_suspend.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/shortcutMethods_suspend.kt
@@ -11,7 +11,6 @@
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -35,7 +34,7 @@
             public override fun createQuery(): String =
                 "INSERT OR ABORT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -43,7 +42,7 @@
         this.__deletionAdapterOfMyEntity = object : EntityDeletionOrUpdateAdapter<MyEntity>(__db) {
             public override fun createQuery(): String = "DELETE FROM `MyEntity` WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
             }
         }
@@ -51,7 +50,7 @@
             public override fun createQuery(): String =
                 "UPDATE OR ABORT `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
@@ -62,7 +61,7 @@
             public override fun createQuery(): String =
                 "INSERT INTO `MyEntity` (`pk`,`other`) VALUES (?,?)"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
             }
@@ -70,7 +69,7 @@
             public override fun createQuery(): String =
                 "UPDATE `MyEntity` SET `pk` = ?,`other` = ? WHERE `pk` = ?"
 
-            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity) {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, entity.other)
                 statement.bindLong(3, entity.pk.toLong())
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_abstractClass.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_abstractClass.kt
index 361a336..4093cf2 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_abstractClass.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_abstractClass.kt
@@ -4,7 +4,6 @@
 import javax.`annotation`.processing.Generated
 import kotlin.Long
 import kotlin.Suppress
-import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -18,7 +17,7 @@
         this.__db = __db
     }
 
-    public override fun baseConcrete(): Unit {
+    public override fun baseConcrete() {
         __db.beginTransaction()
         try {
             super@MyDao_Impl.baseConcrete()
@@ -28,13 +27,13 @@
         }
     }
 
-    public override suspend fun baseSuspendConcrete(): Unit {
+    public override suspend fun baseSuspendConcrete() {
         __db.withTransaction {
             super@MyDao_Impl.baseSuspendConcrete()
         }
     }
 
-    public override fun concrete(): Unit {
+    public override fun concrete() {
         __db.beginTransaction()
         try {
             super@MyDao_Impl.concrete()
@@ -44,7 +43,7 @@
         }
     }
 
-    internal override fun concreteInternal(): Unit {
+    internal override fun concreteInternal() {
         __db.beginTransaction()
         try {
             super@MyDao_Impl.concreteInternal()
@@ -54,13 +53,13 @@
         }
     }
 
-    public override suspend fun suspendConcrete(): Unit {
+    public override suspend fun suspendConcrete() {
         __db.withTransaction {
             super@MyDao_Impl.suspendConcrete()
         }
     }
 
-    public override fun concreteWithVararg(vararg arr: Long): Unit {
+    public override fun concreteWithVararg(vararg arr: Long) {
         __db.beginTransaction()
         try {
             super@MyDao_Impl.concreteWithVararg(*arr)
@@ -70,7 +69,7 @@
         }
     }
 
-    public override suspend fun suspendConcreteWithVararg(vararg arr: Long): Unit {
+    public override suspend fun suspendConcreteWithVararg(vararg arr: Long) {
         __db.withTransaction {
             super@MyDao_Impl.suspendConcreteWithVararg(*arr)
         }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_interface.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_interface.kt
index 0fec3af..9716d56 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_interface.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/transactionMethodAdapter_interface.kt
@@ -21,7 +21,7 @@
         this.__db = __db
     }
 
-    public override fun baseConcrete(): Unit {
+    public override fun baseConcrete() {
         __db.beginTransaction()
         try {
             super@MyDao_Impl.baseConcrete()
@@ -31,13 +31,13 @@
         }
     }
 
-    public override suspend fun baseSuspendConcrete(): Unit {
+    public override suspend fun baseSuspendConcrete() {
         __db.withTransaction {
             super@MyDao_Impl.baseSuspendConcrete()
         }
     }
 
-    public override fun concrete(): Unit {
+    public override fun concrete() {
         __db.beginTransaction()
         try {
             super@MyDao_Impl.concrete()
@@ -71,7 +71,7 @@
         }
     }
 
-    public override fun concreteWithFunctionalParam(block: Function0<Unit>): Unit {
+    public override fun concreteWithFunctionalParam(block: Function0<Unit>) {
         __db.beginTransaction()
         try {
             super@MyDao_Impl.concreteWithFunctionalParam(block)
@@ -81,7 +81,7 @@
         }
     }
 
-    public override suspend fun suspendConcrete(): Unit {
+    public override suspend fun suspendConcrete() {
         __db.withTransaction {
             super@MyDao_Impl.suspendConcrete()
         }
@@ -92,7 +92,7 @@
     }
 
     public override suspend
-    fun suspendConcreteWithSuspendFunctionalParam(block: SuspendFunction0<Unit>): Unit {
+    fun suspendConcreteWithSuspendFunctionalParam(block: SuspendFunction0<Unit>) {
         __db.withTransaction {
             super@MyDao_Impl.suspendConcreteWithSuspendFunctionalParam(block)
         }
diff --git a/slidingpanelayout/slidingpanelayout-testapp/build.gradle b/slidingpanelayout/slidingpanelayout-testapp/build.gradle
index 526716e..7d5ebec 100644
--- a/slidingpanelayout/slidingpanelayout-testapp/build.gradle
+++ b/slidingpanelayout/slidingpanelayout-testapp/build.gradle
@@ -26,6 +26,7 @@
     api(libs.kotlinStdlib)
     // Add dependencies here
     implementation(project(":slidingpanelayout:slidingpanelayout"))
+    implementation("androidx.recyclerview:recyclerview:1.2.1")
 }
 
 android {
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/AndroidManifest.xml b/slidingpanelayout/slidingpanelayout-testapp/src/main/AndroidManifest.xml
index 74faaea..e026b28 100644
--- a/slidingpanelayout/slidingpanelayout-testapp/src/main/AndroidManifest.xml
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/AndroidManifest.xml
@@ -20,13 +20,16 @@
         android:allowBackup="true"
         android:label="SlidingPaneLayout Demo"
         android:supportsRtl="true">
-        
-        <activity android:name="androidx.slidingpanelayout.SlidingPaneLayoutSample"
+
+        <activity android:name="androidx.slidingpanelayout.SlidingPaneLayoutDemos"
             android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
+        <activity android:name="androidx.slidingpanelayout.SlidingPaneLayoutSample"
+            android:exported="true" />
     </application>
 </manifest>
\ No newline at end of file
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/DemoItem.kt b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/DemoItem.kt
new file mode 100644
index 0000000..5415371
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/DemoItem.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.slidingpanelayout
+
+import android.app.Activity
+
+class DemoItem<T : Activity>(
+    val clazz: Class<T>,
+    val title: String,
+    val description: String
+)
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/ItemAdapter.kt b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/ItemAdapter.kt
new file mode 100644
index 0000000..93fac85
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/ItemAdapter.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.slidingpanelayout
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import androidx.slidingpanelayout.demo.R
+
+class ItemAdapter(private val items: List<DemoItem<*>>) : RecyclerView.Adapter<ItemViewHolder>() {
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
+        val inflater = LayoutInflater.from(parent.context)
+        val rootView = inflater.inflate(R.layout.item_viewholder, parent, false)
+        return ItemViewHolder(rootView)
+    }
+
+    override fun getItemCount(): Int {
+        return items.size
+    }
+
+    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
+        holder.bind(items[position])
+    }
+}
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/ItemViewHolder.kt b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/ItemViewHolder.kt
new file mode 100644
index 0000000..2c48ee1
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/ItemViewHolder.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.slidingpanelayout
+
+import android.content.Intent
+import android.view.View
+import android.widget.Button
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import androidx.slidingpanelayout.demo.R
+
+class ItemViewHolder(rootView: View) : RecyclerView.ViewHolder(rootView) {
+
+    private val titleTextView = rootView.findViewById<TextView>(R.id.title_textview)
+    private val descriptionTextView = rootView.findViewById<TextView>(R.id.description_textview)
+    private val launchButton = rootView.findViewById<Button>(R.id.button_launch)
+
+    fun bind(item: DemoItem<*>) {
+        titleTextView.text = item.title
+        descriptionTextView.text = item.description
+        launchButton.setOnClickListener { view ->
+            val context = view.context
+            val intent = Intent(context, item.clazz)
+            context.startActivity(intent)
+        }
+    }
+}
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/SlidingPaneLayoutDemos.kt b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/SlidingPaneLayoutDemos.kt
new file mode 100644
index 0000000..b6d4a1e1
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/java/androidx/slidingpanelayout/SlidingPaneLayoutDemos.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.slidingpanelayout
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.recyclerview.widget.RecyclerView
+import androidx.slidingpanelayout.demo.R
+
+class SlidingPaneLayoutDemos : Activity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_slidingpanelayout_demos)
+        val recyclerView = findViewById<RecyclerView>(R.id.demo_recyclerview)
+
+        recyclerView.adapter = ItemAdapter(
+            listOf(
+                DemoItem(
+                    SlidingPaneLayoutSample::class.java,
+                    "SlidingPaneLayoutSample",
+                    "Basic SlidingPaneLayoutSample"
+                )
+            )
+        )
+    }
+}
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/res/layout/activity_slidingpanelayout_demos.xml b/slidingpanelayout/slidingpanelayout-testapp/src/main/res/layout/activity_slidingpanelayout_demos.xml
new file mode 100644
index 0000000..58bbd7b
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/res/layout/activity_slidingpanelayout_demos.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:id="@+id/demo_recyclerview"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
+
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/res/layout/item_viewholder.xml b/slidingpanelayout/slidingpanelayout-testapp/src/main/res/layout/item_viewholder.xml
new file mode 100644
index 0000000..631c063
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/res/layout/item_viewholder.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:id="@+id/title_textview"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
+    <TextView
+        android:id="@+id/description_textview"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <Button
+        android:id="@+id/button_launch"
+        android:text="@string/launch"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/slidingpanelayout/slidingpanelayout-testapp/src/main/res/values/strings.xml b/slidingpanelayout/slidingpanelayout-testapp/src/main/res/values/strings.xml
new file mode 100644
index 0000000..cbe5256
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout-testapp/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <string name="launch">Launch</string>
+</resources>
\ No newline at end of file
diff --git a/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/StableAidlTasks.kt b/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/StableAidlTasks.kt
index a8c07759..93bcbf8 100644
--- a/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/StableAidlTasks.kt
+++ b/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/StableAidlTasks.kt
@@ -24,7 +24,6 @@
 import com.android.build.api.variant.SourceDirectories
 import com.android.build.api.variant.Variant
 import com.android.utils.usLocaleCapitalize
-import java.io.File
 import org.gradle.api.Action
 import org.gradle.api.DomainObjectCollection
 import org.gradle.api.Project
@@ -36,6 +35,7 @@
 import org.gradle.api.file.FileCollection
 import org.gradle.api.file.RegularFile
 import org.gradle.api.provider.Provider
+import org.gradle.api.tasks.TaskOutputFilePropertyBuilder
 import org.gradle.api.tasks.TaskProvider
 
 // Gradle task group used to identify Stable AIDL tasks.
@@ -68,7 +68,6 @@
     }
 }
 
-@Suppress("UnstableApiUsage") // SourceDirectories.Flat
 fun registerCompileAidlApi(
     project: Project,
     variant: Variant,
@@ -277,18 +276,16 @@
 /**
  * Tells Gradle to skip running this task, even if this task declares no output files.
  */
-private fun Task.cacheEvenIfNoOutputs() {
-    this.outputs.file(this.getPlaceholderOutput())
-}
+private fun Task.cacheEvenIfNoOutputs(): TaskOutputFilePropertyBuilder =
+    outputs.file(getPlaceholderOutput())
 
 /**
  * Returns an unused output path that we can pass to Gradle to prevent Gradle from thinking that we
  * forgot to declare outputs of this task, and instead to skip this task if its inputs are
  * unchanged.
  */
-private fun Task.getPlaceholderOutput(): File {
-    return File(this.project.buildDir, "placeholderOutput/" + this.name.replace(":", "-"))
-}
+private fun Task.getPlaceholderOutput(): Provider<RegularFile> =
+    project.layout.buildDirectory.file("placeholderOutput/${name.replace(':', '-')}")
 
 private fun computeTaskName(prefix: String, variant: Variant, suffix: String) =
     "$prefix${variant.name.usLocaleCapitalize()}$suffix"
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/Configurator.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/Configurator.java
index 6b7931d..ad68c56 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/Configurator.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/Configurator.java
@@ -224,6 +224,11 @@
     /**
      * Sets the current tool type to use for motion events.
      * @see MotionEvent#getToolType(int)
+     * @see MotionEvent#TOOL_TYPE_FINGER
+     * @see MotionEvent#TOOL_TYPE_STYLUS
+     * @see MotionEvent#TOOL_TYPE_MOUSE
+     * @see MotionEvent#TOOL_TYPE_ERASER
+     * @see MotionEvent#TOOL_TYPE_UNKNOWN
      */
     public @NonNull Configurator setToolType(final int toolType) {
         mToolType = toolType;
diff --git a/testutils/testutils-common/src/main/java/androidx/testutils/ParameterizedHelper.kt b/testutils/testutils-common/src/main/java/androidx/testutils/ParameterizedHelper.kt
index 236b362..844f968 100644
--- a/testutils/testutils-common/src/main/java/androidx/testutils/ParameterizedHelper.kt
+++ b/testutils/testutils-common/src/main/java/androidx/testutils/ParameterizedHelper.kt
@@ -33,6 +33,7 @@
  *
  * See [ParameterizedHelperTest] for more examples.
  */
+// TODO(kuanyingchou): Remove and replace with TestParameterInjector"
 fun generateAllEnumerations(vararg args: List<Any>): List<Array<Any>> =
     generateAllEnumerationsIteratively(args.toList()).map { it.toTypedArray() }
 
diff --git a/transition/transition/api/current.txt b/transition/transition/api/current.txt
index 8b6b763..b6bf3ae 100644
--- a/transition/transition/api/current.txt
+++ b/transition/transition/api/current.txt
@@ -209,10 +209,10 @@
     method public static void beginDelayedTransition(android.view.ViewGroup);
     method public static void beginDelayedTransition(android.view.ViewGroup, androidx.transition.Transition?);
     method public static androidx.transition.TransitionSeekController? controlDelayedTransition(android.view.ViewGroup, androidx.transition.Transition);
+    method public static androidx.transition.TransitionSeekController? createSeekController(androidx.transition.Scene, androidx.transition.Transition);
     method public static void endTransitions(android.view.ViewGroup?);
     method public static void go(androidx.transition.Scene);
     method public static void go(androidx.transition.Scene, androidx.transition.Transition?);
-    method public static androidx.transition.TransitionSeekController? seekTo(androidx.transition.Scene, androidx.transition.Transition);
     method public void setTransition(androidx.transition.Scene, androidx.transition.Scene, androidx.transition.Transition?);
     method public void setTransition(androidx.transition.Scene, androidx.transition.Transition?);
     method public void transitionTo(androidx.transition.Scene);
diff --git a/transition/transition/api/restricted_current.txt b/transition/transition/api/restricted_current.txt
index bd19de1..3f44ab2 100644
--- a/transition/transition/api/restricted_current.txt
+++ b/transition/transition/api/restricted_current.txt
@@ -242,10 +242,10 @@
     method public static void beginDelayedTransition(android.view.ViewGroup);
     method public static void beginDelayedTransition(android.view.ViewGroup, androidx.transition.Transition?);
     method public static androidx.transition.TransitionSeekController? controlDelayedTransition(android.view.ViewGroup, androidx.transition.Transition);
+    method public static androidx.transition.TransitionSeekController? createSeekController(androidx.transition.Scene, androidx.transition.Transition);
     method public static void endTransitions(android.view.ViewGroup?);
     method public static void go(androidx.transition.Scene);
     method public static void go(androidx.transition.Scene, androidx.transition.Transition?);
-    method public static androidx.transition.TransitionSeekController? seekTo(androidx.transition.Scene, androidx.transition.Transition);
     method public void setTransition(androidx.transition.Scene, androidx.transition.Scene, androidx.transition.Transition?);
     method public void setTransition(androidx.transition.Scene, androidx.transition.Transition?);
     method public void transitionTo(androidx.transition.Scene);
diff --git a/transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt b/transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt
index 852db4e..fd55d1a 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt
+++ b/transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt
@@ -1060,7 +1060,7 @@
         }
 
         rule.runOnUiThread {
-            val controller = TransitionManager.seekTo(scene2, Fade())
+            val controller = TransitionManager.createSeekController(scene2, Fade())
             assertThat(controller).isNotNull()
             seekController = controller!!
         }
@@ -1096,7 +1096,7 @@
         }
 
         rule.runOnUiThread {
-            TransitionManager.seekTo(scene2, NoSeekingTransition())
+            TransitionManager.createSeekController(scene2, NoSeekingTransition())
         }
     }
 
@@ -1111,7 +1111,7 @@
 
         rule.runOnUiThread {
             TransitionManager.go(scene2, Fade())
-            assertThat(TransitionManager.seekTo(scene1, Fade())).isNull()
+            assertThat(TransitionManager.createSeekController(scene1, Fade())).isNull()
         }
     }
 }
diff --git a/transition/transition/src/main/java/androidx/transition/TransitionManager.java b/transition/transition/src/main/java/androidx/transition/TransitionManager.java
index 2fdb6d5..261738f4 100644
--- a/transition/transition/src/main/java/androidx/transition/TransitionManager.java
+++ b/transition/transition/src/main/java/androidx/transition/TransitionManager.java
@@ -365,7 +365,7 @@
      * {@link Transition#isSeekingSupported()}.
      */
     @Nullable
-    public static TransitionSeekController seekTo(
+    public static TransitionSeekController createSeekController(
             @NonNull Scene scene,
             @NonNull Transition transition
     ) {
diff --git a/transition/transition/src/main/java/androidx/transition/TransitionSeekController.java b/transition/transition/src/main/java/androidx/transition/TransitionSeekController.java
index f9b00c5..9e4f228 100644
--- a/transition/transition/src/main/java/androidx/transition/TransitionSeekController.java
+++ b/transition/transition/src/main/java/androidx/transition/TransitionSeekController.java
@@ -44,7 +44,7 @@
     long getCurrentPlayTimeMillis();
 
     /**
-     * @return The fraction, between 0 and 1, of the progress of the transition.
+     * @return The fraction, between 0 and 1, inclusive, of the progress of the transition.
      * @see #getCurrentPlayTimeMillis()
      */
     @FloatRange(from = 0.0, to = 1.0)
@@ -132,7 +132,7 @@
     void addOnProgressChangedListener(@NonNull Consumer<TransitionSeekController> consumer);
 
     /**
-     * Remove a listener previously added in {@link #addOnProgressChangedListener(Consumer)}\
+     * Remove a listener previously added in {@link #addOnProgressChangedListener(Consumer)}
      * @param consumer The listener to be removed.
      */
     void removeOnProgressChangedListener(@NonNull Consumer<TransitionSeekController> consumer);
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt
index c0832bb..2546e1c 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt
@@ -645,7 +645,7 @@
 @get:ExperimentalTvMaterial3Api
 val LocalAbsoluteTonalElevation = compositionLocalOf { 0.dp }
 
-private val AcceptableKeys = hashSetOf(
+private val AcceptableKeys = intArrayOf(
     NativeKeyEvent.KEYCODE_DPAD_CENTER,
     NativeKeyEvent.KEYCODE_ENTER,
     NativeKeyEvent.KEYCODE_NUMPAD_ENTER
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt
index e389f5c..9284438 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt
@@ -34,6 +34,8 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.Dp
 
 /**
@@ -80,14 +82,16 @@
             .clickable(
                 onClick = onClick,
                 enabled = enabled,
-                role = Role.Button,
+                role = null, // provide the role via Modifier.semantics
                 interactionSource = interactionSource,
                 indication = rememberRipple(),
             )
             .then(
                 // Make sure modifier ordering is clip > clickable > padding > size,
                 // so that the ripple applies to the entire button shape and size.
+                // Then, apply semantics to apply the default semantic role (can be overridden)
                 modifier
+                    .semantics { role = Role.Button }
             )
             .size(buttonSize)
             .clip(shape) // Clip for the painted background area after size has been applied.
diff --git a/wear/compose/compose-material/src/androidTest/kotlin/androidx/wear/compose/material/ToggleButtonTest.kt b/wear/compose/compose-material/src/androidTest/kotlin/androidx/wear/compose/material/ToggleButtonTest.kt
index 84db9176..ae4e264 100644
--- a/wear/compose/compose-material/src/androidTest/kotlin/androidx/wear/compose/material/ToggleButtonTest.kt
+++ b/wear/compose/compose-material/src/androidTest/kotlin/androidx/wear/compose/material/ToggleButtonTest.kt
@@ -767,11 +767,14 @@
     setContentWithTheme {
         background = MaterialTheme.colors.surface
         buttonColor = MaterialTheme.colors.primary
-        content(
-            Modifier
-                .testTag(TEST_TAG)
-                .padding(padding)
-                .background(background))
+        Box(Modifier.background(background)) {
+            content(
+                Modifier
+                    .testTag(TEST_TAG)
+                    .padding(padding)
+                    .background(background)
+            )
+        }
     }
 
     onNodeWithTag(TEST_TAG)
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt
index 812ac3d..4a208e3 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt
@@ -15,28 +15,22 @@
  */
 package androidx.wear.compose.material
 
-import androidx.compose.foundation.background
 import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.defaultMinSize
-import androidx.compose.foundation.selection.toggleable
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.State
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
 
 /**
@@ -219,36 +213,24 @@
     role: Role = ToggleButtonDefaults.DefaultRole,
     content: @Composable BoxScope.() -> Unit,
 ) {
-    Box(
-        contentAlignment = Alignment.Center,
-        modifier = modifier
-            .defaultMinSize(
-                minWidth = ToggleButtonDefaults.DefaultToggleButtonSize,
-                minHeight = ToggleButtonDefaults.DefaultToggleButtonSize
-            )
-            .clip(shape)
-            .toggleable(
-                value = checked,
-                onValueChange = onCheckedChange,
-                enabled = enabled,
-                role = role,
-                interactionSource = interactionSource,
-                indication = rememberRipple()
-            )
-            .background(
-                color = colors.backgroundColor(enabled = enabled, checked = checked).value,
-                shape = shape
-            )
-    ) {
-        val contentColor = colors.contentColor(enabled = enabled, checked = checked).value
-        CompositionLocalProvider(
-            LocalContentColor provides contentColor,
-            LocalContentAlpha provides contentColor.alpha,
-            LocalTextStyle provides MaterialTheme.typography.button,
-        ) {
-            content()
-        }
-    }
+    androidx.wear.compose.materialcore.ToggleButton(
+        checked = checked,
+        onCheckedChange = onCheckedChange,
+        modifier = modifier.semantics { this.role = role },
+        enabled = enabled,
+        backgroundColor = { isEnabled, isChecked ->
+            colors.backgroundColor(enabled = isEnabled, checked = isChecked)
+        },
+        border = { _, _ -> null },
+        toggleButtonSize = ToggleButtonDefaults.DefaultToggleButtonSize,
+        interactionSource = interactionSource,
+        shape = shape,
+        content = provideScopeContent(
+            colors.contentColor(enabled = enabled, checked = checked),
+            MaterialTheme.typography.button,
+            content
+        )
+    )
 }
 /**
  * Represents the background and content colors used in a toggle button in different states.
diff --git a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ButtonDemo.kt b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ButtonDemo.kt
index 76cddf8..d2c396f 100644
--- a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ButtonDemo.kt
+++ b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/ButtonDemo.kt
@@ -29,6 +29,7 @@
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
 import androidx.wear.compose.material3.Button
+import androidx.wear.compose.material3.ButtonColors
 import androidx.wear.compose.material3.ButtonDefaults
 import androidx.wear.compose.material3.ChildButton
 import androidx.wear.compose.material3.FilledTonalButton
@@ -310,13 +311,17 @@
 @Composable
 private fun AvatarButton(enabled: Boolean) =
     MultilineButton(
-        enabled = enabled, icon = { AvatarIcon() }, label = { Text("Primary text") }
+        enabled = enabled,
+        colors = ButtonDefaults.filledTonalButtonColors(),
+        icon = { AvatarIcon() },
+        label = { Text("Primary text") }
     )
 
 @Composable
 private fun Avatar3SlotButton(enabled: Boolean) =
     Multiline3SlotButton(
         enabled = enabled,
+        colors = ButtonDefaults.filledTonalButtonColors(),
         icon = { AvatarIcon() },
         label = { Text("Primary text") },
         secondaryLabel = { Text("Secondary label") }
@@ -325,6 +330,7 @@
 @Composable
 private fun MultilineButton(
     enabled: Boolean,
+    colors: ButtonColors = ButtonDefaults.filledButtonColors(),
     icon: (@Composable BoxScope.() -> Unit)? = null,
     label: @Composable RowScope.() -> Unit = {
         Text(
@@ -338,13 +344,15 @@
         onClick = { /* Do something */ },
         icon = icon,
         label = label,
-        enabled = enabled
+        enabled = enabled,
+        colors = colors,
     )
 }
 
 @Composable
 private fun Multiline3SlotButton(
     enabled: Boolean,
+    colors: ButtonColors = ButtonDefaults.filledButtonColors(),
     icon: (@Composable BoxScope.() -> Unit)? = null,
     label: @Composable RowScope.() -> Unit = {
         Text(
@@ -366,7 +374,8 @@
         icon = icon,
         label = label,
         secondaryLabel = secondaryLabel,
-        enabled = enabled
+        enabled = enabled,
+        colors = colors,
     )
 }
 
diff --git a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
index eb4b7c0..a5da87e 100644
--- a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
+++ b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
@@ -386,7 +386,7 @@
             status = Status.Disabled,
             colors = { ButtonDefaults.filledButtonColors() },
             expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
+                alpha = DisabledContainerAlpha
             ) },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
@@ -412,7 +412,7 @@
             status = Status.Disabled,
             colors = { ButtonDefaults.filledTonalButtonColors() },
             expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
+                alpha = DisabledContainerAlpha
             ) },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
@@ -461,9 +461,7 @@
         rule.verifyButtonColors(
             status = Status.Disabled,
             colors = { ButtonDefaults.childButtonColors() },
-            expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
-            ) },
+            expectedContainerColor = { Color.Transparent },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
             ) },
@@ -563,7 +561,9 @@
     fun gives_disabled_outlined_button_correct_border_colors() {
         val status = Status.Disabled
         rule.verifyButtonBorderColor(
-            expectedBorderColor = { MaterialTheme.colorScheme.onSurface.copy(alpha = 0.12f) },
+            expectedBorderColor = {
+                MaterialTheme.colorScheme.onSurface.copy(alpha = DisabledBorderAlpha)
+            },
             content = { modifier: Modifier ->
                 OutlinedButton(
                     onClick = {},
diff --git a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonScreenshotTest.kt b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonScreenshotTest.kt
index e1bcf92..07d2ceb 100644
--- a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonScreenshotTest.kt
+++ b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonScreenshotTest.kt
@@ -70,7 +70,7 @@
     }
 
     @Test
-    fun filled_icon_button_disabled() = verifyScreenshot("icon_button_disabled") {
+    fun filled_icon_button_disabled() = verifyScreenshot {
         sampleFilledIconButton(enabled = false, isCompact = false)
     }
 
@@ -80,7 +80,7 @@
     }
 
     @Test
-    fun filled_tonal_icon_button_disabled() = verifyScreenshot("icon_button_disabled") {
+    fun filled_tonal_icon_button_disabled() = verifyScreenshot {
         sampleFilledTonalIconButton(enabled = false, isCompact = false)
     }
 
@@ -110,7 +110,7 @@
     }
 
     @Test
-    fun filled_compact_icon_button_disabled() = verifyScreenshot("compact_icon_button_disabled") {
+    fun filled_compact_icon_button_disabled() = verifyScreenshot {
         sampleFilledIconButton(enabled = false, isCompact = true)
     }
 
@@ -121,7 +121,7 @@
 
     @Test
     fun filled_tonal_compact_icon_button_disabled() =
-        verifyScreenshot("compact_icon_button_disabled") {
+        verifyScreenshot {
             sampleFilledTonalIconButton(enabled = false, isCompact = true)
         }
 
diff --git a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonTest.kt b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonTest.kt
index d12eb43..f6f9e3b 100644
--- a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonTest.kt
+++ b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/IconButtonTest.kt
@@ -31,6 +31,8 @@
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.assert
 import androidx.compose.ui.test.assertHasClickAction
@@ -191,6 +193,27 @@
     }
 
     @Test
+    fun allows_custom_role() {
+        val overrideRole = Role.Checkbox
+
+        rule.setContentWithTheme {
+            IconButton(
+                onClick = {},
+                modifier = Modifier.testTag(TEST_TAG).semantics { role = overrideRole }
+            ) {
+                TestImage()
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG).assert(
+            SemanticsMatcher.expectValue(
+                SemanticsProperties.Role,
+                overrideRole
+            )
+        )
+    }
+
+    @Test
     fun gives_default_button_correct_tap_size() {
         rule.verifyTapSize(DefaultButtonSize) { modifier ->
             IconButton(
@@ -317,7 +340,7 @@
             status = Status.Disabled,
             colors = { IconButtonDefaults.filledIconButtonColors() },
             expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
+                alpha = DisabledContainerAlpha
             ) },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
@@ -343,7 +366,7 @@
             status = Status.Disabled,
             colors = { IconButtonDefaults.filledTonalIconButtonColors() },
             expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
+                alpha = DisabledContainerAlpha
             ) },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
@@ -397,7 +420,7 @@
         val status = Status.Disabled
         rule.verifyButtonBorderColor(
             expectedBorderColor = {
-                MaterialTheme.colorScheme.onSurface.copy(alpha = DisabledBorderAndContainerAlpha)
+                MaterialTheme.colorScheme.onSurface.copy(alpha = DisabledBorderAlpha)
             },
             content = { modifier: Modifier ->
                 OutlinedIconButton(
diff --git a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonScreenshotTest.kt b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonScreenshotTest.kt
index 967714f3..11b0b55 100644
--- a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonScreenshotTest.kt
+++ b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonScreenshotTest.kt
@@ -66,7 +66,7 @@
 
     @Test
     fun filled_text_button_disabled() =
-        verifyScreenshot("text_button_disabled") {
+        verifyScreenshot {
             sampleFilledTextButton(enabled = false, isCompact = false)
         }
 
@@ -77,7 +77,7 @@
 
     @Test
     fun filled_tonal_text_button_disabled() =
-        verifyScreenshot("text_button_disabled") {
+        verifyScreenshot {
             sampleFilledTonalTextButton(enabled = false, isCompact = false)
         }
 
@@ -108,7 +108,7 @@
 
     @Test
     fun filled_compact_text_button_disabled() =
-        verifyScreenshot("compact_text_button_disabled") {
+        verifyScreenshot {
             sampleFilledTextButton(enabled = false, isCompact = true)
         }
 
@@ -119,7 +119,7 @@
 
     @Test
     fun filled_tonal_compact_text_button_disabled() =
-        verifyScreenshot("compact_text_button_disabled") {
+        verifyScreenshot {
             sampleFilledTonalTextButton(enabled = false, isCompact = true)
         }
 
diff --git a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonTest.kt b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonTest.kt
index a37ef7b..f6a0b7b 100644
--- a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonTest.kt
+++ b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/TextButtonTest.kt
@@ -31,6 +31,8 @@
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.assert
 import androidx.compose.ui.test.assertHasClickAction
@@ -222,6 +224,27 @@
     }
 
     @Test
+    fun allows_custom_role() {
+        val overrideRole = Role.Checkbox
+
+        rule.setContentWithTheme {
+            TextButton(
+                onClick = {},
+                modifier = Modifier.testTag(TEST_TAG).semantics { role = overrideRole }
+            ) {
+                Text("Test")
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG).assert(
+            SemanticsMatcher.expectValue(
+                SemanticsProperties.Role,
+                overrideRole
+            )
+        )
+    }
+
+    @Test
     fun sets_correct_font() {
         var actualTextStyle = TextStyle.Default
         var expectedTextStyle = TextStyle.Default
@@ -365,7 +388,7 @@
             status = Status.Disabled,
             colors = { TextButtonDefaults.filledTextButtonColors() },
             expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
+                alpha = DisabledContainerAlpha
             ) },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
@@ -391,7 +414,7 @@
             status = Status.Disabled,
             colors = { TextButtonDefaults.filledTonalTextButtonColors() },
             expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
+                alpha = DisabledContainerAlpha
             ) },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
@@ -416,9 +439,7 @@
         rule.verifyTextButtonColors(
             status = Status.Disabled,
             colors = { TextButtonDefaults.outlinedTextButtonColors() },
-            expectedContainerColor = { MaterialTheme.colorScheme.onSurface.copy(
-                alpha = DisabledBorderAndContainerAlpha
-            ) },
+            expectedContainerColor = { Color.Transparent },
             expectedContentColor = { MaterialTheme.colorScheme.onSurface.copy(
                 alpha = ContentAlpha.disabled
             ) }
@@ -449,7 +470,7 @@
         val status = Status.Disabled
         rule.verifyButtonBorderColor(
             expectedBorderColor = {
-                MaterialTheme.colorScheme.onSurface.copy(alpha = DisabledBorderAndContainerAlpha)
+                MaterialTheme.colorScheme.onSurface.copy(alpha = DisabledBorderAlpha)
             },
             content = { modifier: Modifier ->
                 TextButton(
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
index 6c8de9eb59..e608707 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
@@ -715,7 +715,7 @@
         containerColor: Color = MaterialTheme.colorScheme.surface,
         contentColor: Color = MaterialTheme.colorScheme.onSurface,
         secondaryContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
-        iconColor: Color = MaterialTheme.colorScheme.onSurface
+        iconColor: Color = MaterialTheme.colorScheme.primary,
     ): ButtonColors {
         return buttonColors(
             containerColor = containerColor,
@@ -742,13 +742,14 @@
     fun outlinedButtonColors(
         contentColor: Color = MaterialTheme.colorScheme.onSurface,
         secondaryContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
-        iconColor: Color = MaterialTheme.colorScheme.onSurface
+        iconColor: Color = MaterialTheme.colorScheme.primary,
     ): ButtonColors {
         return buttonColors(
             containerColor = Color.Transparent,
             contentColor = contentColor,
             secondaryContentColor = secondaryContentColor,
-            iconColor = iconColor
+            iconColor = iconColor,
+            disabledContainerColor = Color.Transparent,
         )
     }
 
@@ -769,13 +770,14 @@
     fun childButtonColors(
         contentColor: Color = MaterialTheme.colorScheme.onSurface,
         secondaryContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
-        iconColor: Color = MaterialTheme.colorScheme.onSurface
+        iconColor: Color = MaterialTheme.colorScheme.primary
     ): ButtonColors {
         return buttonColors(
             containerColor = Color.Transparent,
             contentColor = contentColor,
             secondaryContentColor = secondaryContentColor,
-            iconColor = iconColor
+            iconColor = iconColor,
+            disabledContainerColor = Color.Transparent,
         )
     }
 
@@ -851,7 +853,7 @@
         enabled: Boolean,
         borderColor: Color = MaterialTheme.colorScheme.outline,
         disabledBorderColor: Color = MaterialTheme.colorScheme.onSurface.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledBorderAlpha
         ),
         borderWidth: Dp = 1.dp
     ): BorderStroke {
@@ -901,7 +903,7 @@
         secondaryContentColor: Color = contentColor,
         iconColor: Color = contentColor,
         disabledContainerColor: Color = MaterialTheme.colorScheme.onSurface.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledContainerAlpha
         ),
         disabledContentColor: Color = MaterialTheme.colorScheme.onSurface.toDisabledColor(),
         disabledSecondaryContentColor: Color =
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ContentAlpha.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ContentAlpha.kt
index 8471524..b978a2b 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ContentAlpha.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ContentAlpha.kt
@@ -33,18 +33,18 @@
  * body text.
  *
  */
-public val LocalContentAlpha: ProvidableCompositionLocal<Float> = compositionLocalOf { 1f }
+val LocalContentAlpha: ProvidableCompositionLocal<Float> = compositionLocalOf { 1f }
 
 /**
  * Default alpha levels used by Material components.
  *
  * See [LocalContentAlpha].
  */
-public object ContentAlpha {
+object ContentAlpha {
     /**
      * A high level of content alpha, used to represent high emphasis text.
      */
-    public val high: Float
+    val high: Float
         @Composable
         get() = contentAlpha(
             highContrastAlpha = HighContrastContentAlpha.high,
@@ -55,7 +55,7 @@
      * A medium level of content alpha, used to represent medium emphasis text such as
      * placeholder text.
      */
-    public val medium: Float
+    val medium: Float
         @Composable
         get() = contentAlpha(
             highContrastAlpha = HighContrastContentAlpha.medium,
@@ -66,7 +66,7 @@
      * A low level of content alpha used to represent disabled components, such as text in a
      * disabled Button.
      */
-    public val disabled: Float
+    val disabled: Float
         @Composable
         get() = contentAlpha(
             highContrastAlpha = HighContrastContentAlpha.disabled,
@@ -123,4 +123,5 @@
     const val disabled: Float = 0.38f
 }
 
-internal const val DisabledBorderAndContainerAlpha = 0.12f
+internal const val DisabledContainerAlpha = 0.12f
+internal const val DisabledBorderAlpha = 0.20f
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt
index 042f777..ff669b8 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt
@@ -358,7 +358,10 @@
     ): IconButtonColors {
         return iconButtonColors(
             containerColor = containerColor,
-            contentColor = contentColor
+            contentColor = contentColor,
+            disabledContainerColor = MaterialTheme.colorScheme.onSurface.toDisabledColor(
+                disabledAlpha = DisabledContainerAlpha
+            ),
         )
     }
 
@@ -378,7 +381,10 @@
     ): IconButtonColors {
         return iconButtonColors(
             containerColor = containerColor,
-            contentColor = contentColor
+            contentColor = contentColor,
+            disabledContainerColor = MaterialTheme.colorScheme.onSurface.toDisabledColor(
+                disabledAlpha = DisabledContainerAlpha
+            ),
         )
     }
 
@@ -396,7 +402,7 @@
     ): IconButtonColors {
         return iconButtonColors(
             containerColor = Color.Transparent,
-            contentColor = contentColor
+            contentColor = contentColor,
         )
     }
 
@@ -415,9 +421,7 @@
     fun iconButtonColors(
         containerColor: Color = Color.Transparent,
         contentColor: Color = MaterialTheme.colorScheme.onBackground,
-        disabledContainerColor: Color = MaterialTheme.colorScheme.onSurface.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
-        ),
+        disabledContainerColor: Color = Color.Transparent,
         disabledContentColor: Color = MaterialTheme.colorScheme.onSurface.toDisabledColor()
     ): IconButtonColors = IconButtonColors(
         containerColor = containerColor,
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt
index adf549b..128b9a5 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt
@@ -491,11 +491,11 @@
         uncheckedBoxColor = uncheckedBoxColor,
         uncheckedCheckmarkColor = uncheckedCheckmarkColor,
         disabledCheckedBoxColor = checkedBoxColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledContainerAlpha
         ),
         disabledCheckedCheckmarkColor = checkedCheckmarkColor.toDisabledColor(),
         disabledUncheckedBoxColor = uncheckedBoxColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledContainerAlpha
         ),
         disabledUncheckedCheckmarkColor = uncheckedCheckmarkColor.toDisabledColor()
     )
@@ -539,18 +539,18 @@
         disabledCheckedThumbColor = checkedThumbColor.toDisabledColor(),
         disabledCheckedThumbIconColor = checkedThumbIconColor.toDisabledColor(),
         disabledCheckedTrackColor = checkedTrackColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledContainerAlpha
         ),
         disabledCheckedTrackBorderColor = checkedTrackStrokeColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledBorderAlpha
         ),
         disabledUncheckedThumbColor = uncheckedThumbColor.toDisabledColor(),
         disabledUncheckedThumbIconColor = uncheckedThumbIconColor.toDisabledColor(),
         disabledUncheckedTrackColor = uncheckedTrackColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledContainerAlpha
         ),
         disabledUncheckedTrackBorderColor = uncheckedTrackStrokeColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledBorderAlpha
         )
     )
 }
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt
index d6a155f..9563288 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt
@@ -328,13 +328,13 @@
         unselectedBarColor: Color = MaterialTheme.colorScheme.background.copy(alpha = 0.3f),
         barSeparatorColor: Color = MaterialTheme.colorScheme.primaryDim,
         disabledContainerColor: Color = containerColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledContainerAlpha
         ),
         disabledButtonIconColor: Color = buttonIconColor.toDisabledColor(),
         disabledSelectedBarColor: Color = selectedBarColor.toDisabledColor(),
         disabledUnselectedBarColor: Color = unselectedBarColor.toDisabledColor(),
         disabledBarSeparatorColor: Color = barSeparatorColor.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
+            disabledAlpha = DisabledContainerAlpha
         )
     ): InlineSliderColors = InlineSliderColors(
         containerColor = containerColor,
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt
index f3d2722..e0349a1 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt
@@ -135,7 +135,7 @@
  * @param content The text to be drawn inside the toggle button.
  */
 @Composable
-public fun TextToggleButton(
+fun TextToggleButton(
     checked: Boolean,
     onCheckedChange: (Boolean) -> Unit,
     modifier: Modifier = Modifier,
@@ -194,7 +194,10 @@
     ): TextButtonColors {
         return textButtonColors(
             containerColor = containerColor,
-            contentColor = contentColor
+            contentColor = contentColor,
+            disabledContainerColor = MaterialTheme.colorScheme.onSurface.toDisabledColor(
+                disabledAlpha = DisabledContainerAlpha
+            ),
         )
     }
 
@@ -217,7 +220,10 @@
     ): TextButtonColors {
         return textButtonColors(
             containerColor = containerColor,
-            contentColor = contentColor
+            contentColor = contentColor,
+            disabledContainerColor = MaterialTheme.colorScheme.onSurface.toDisabledColor(
+                disabledAlpha = DisabledContainerAlpha
+            ),
         )
     }
 
@@ -256,9 +262,7 @@
     fun textButtonColors(
         containerColor: Color = Color.Transparent,
         contentColor: Color = MaterialTheme.colorScheme.onBackground,
-        disabledContainerColor: Color = MaterialTheme.colorScheme.onSurface.toDisabledColor(
-            disabledAlpha = DisabledBorderAndContainerAlpha
-        ),
+        disabledContainerColor: Color = Color.Transparent,
         disabledContentColor: Color = MaterialTheme.colorScheme.onSurface.toDisabledColor()
     ): TextButtonColors = TextButtonColors(
         containerColor = containerColor,
@@ -291,7 +295,7 @@
      * unchecked and not enabled
      */
     @Composable
-    public fun textToggleButtonColors(
+    fun textToggleButtonColors(
         checkedContainerColor: Color = MaterialTheme.colorScheme.primary,
         checkedContentColor: Color = MaterialTheme.colorScheme.onPrimary,
         uncheckedContainerColor: Color = MaterialTheme.colorScheme.surface,