Merge "Disable running lint as it is failing in androidx-studio-integration branch" into androidx-main
diff --git a/activity/activity-lint/src/test/java/androidx/activity/lint/ApiLintVersionsTest.kt b/activity/activity-lint/src/test/java/androidx/activity/lint/ApiLintVersionsTest.kt
index 6e3e54a..212284f 100644
--- a/activity/activity-lint/src/test/java/androidx/activity/lint/ApiLintVersionsTest.kt
+++ b/activity/activity-lint/src/test/java/androidx/activity/lint/ApiLintVersionsTest.kt
@@ -35,6 +35,6 @@
         assertThat(registry.api).isEqualTo(CURRENT_API)
         // Intentionally fails in IDE, because we use different API version in
         // studio and command line
-        assertThat(registry.minApi).isEqualTo(3)
+        assertThat(registry.minApi).isEqualTo(8)
     }
 }
diff --git a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
index b194f01..dd3a0ac 100644
--- a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
+++ b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
@@ -115,7 +115,7 @@
         if (!hasOrUsesAnnotation(context, usage, useAnnotation, useAnnotationNames)) {
             val level = annotation.extractAttribute(context, "level") ?: "ERROR"
             report(
-                context, usage,
+                context, usage, useAnnotation,
                 """
                     This declaration is opt-in and its usage should be marked with
                     '@$useAnnotation' or '@OptIn(markerClass = $useAnnotation.class)'
@@ -178,9 +178,9 @@
     private fun report(
         context: JavaContext,
         usage: UElement,
+        annotation: String,
         message: String,
-        level: String
-
+        level: String,
     ) {
         val issue = when (level) {
             "ERROR" -> ISSUE_ERROR
@@ -190,8 +190,11 @@
                     "of: ERROR, WARNING"
             )
         }
+
         try {
-            context.report(issue, usage, context.getNameLocation(usage), message.trimIndent())
+            if (context.configuration.getOption(issue, "opt-in")?.contains(annotation) != true) {
+                context.report(issue, usage, context.getNameLocation(usage), message.trimIndent())
+            }
         } catch (e: UnsupportedOperationException) {
             if ("Method not implemented" == e.message) {
                 // Workaround for b/191286558 where lint attempts to read annotations from a
diff --git a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ApiLintVersionsTest.kt b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ApiLintVersionsTest.kt
index 50585ec..e2cc0bd 100644
--- a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ApiLintVersionsTest.kt
+++ b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ApiLintVersionsTest.kt
@@ -36,6 +36,6 @@
         // We hardcode version registry.api to the version that is used to run tests.
         assertEquals("registry.api matches version used to run tests", CURRENT_API, registry.api)
         // Intentionally fails in IDE, because we use different API version in Studio and CLI.
-        assertEquals("registry.minApi is set to minimum level of 3", 3, registry.minApi)
+        assertEquals("registry.minApi is set to minimum level of 8", 8, registry.minApi)
     }
 }
diff --git a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
index 5d9ddcf..f557f3139 100644
--- a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
+++ b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
@@ -22,6 +22,7 @@
 import com.android.tools.lint.checks.infrastructure.TestFiles.base64gzip
 import com.android.tools.lint.checks.infrastructure.TestFiles.java
 import com.android.tools.lint.checks.infrastructure.TestFiles.kotlin
+import com.android.tools.lint.checks.infrastructure.TestFiles.xml
 import com.android.tools.lint.checks.infrastructure.TestLintResult
 import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
 import org.junit.Test
@@ -78,6 +79,44 @@
     }
 
     @Test
+    fun useJavaExperimentalFromJavaWithOptions() {
+        val lintConfig = xml(
+            "lint.xml",
+            """
+<lint>
+    <issue id="UnsafeOptInUsageError">
+        <option name="opt-in" value="sample.experimental.ExperimentalDateTime" />
+    </issue>
+</lint>
+            """.trimIndent()
+        )
+        val input = arrayOf(
+            javaSample("sample.experimental.DateProvider"),
+            javaSample("sample.experimental.ExperimentalDateTime"),
+            javaSample("sample.experimental.ExperimentalLocation"),
+            javaSample("sample.experimental.LocationProvider"),
+            javaSample("sample.experimental.UseJavaExperimentalFromJava"),
+            lintConfig
+        )
+
+        /* ktlint-disable max-line-length */
+        val expected = """
+src/sample/experimental/UseJavaExperimentalFromJava.java:53: Error: This declaration is opt-in and its usage should be marked with
+'@sample.experimental.ExperimentalLocation' or '@OptIn(markerClass = sample.experimental.ExperimentalLocation.class)' [UnsafeOptInUsageError]
+        LocationProvider locationProvider = new LocationProvider();
+                                            ~~~~~~~~~~~~~~~~~~~~~~
+src/sample/experimental/UseJavaExperimentalFromJava.java:54: Error: This declaration is opt-in and its usage should be marked with
+'@sample.experimental.ExperimentalLocation' or '@OptIn(markerClass = sample.experimental.ExperimentalLocation.class)' [UnsafeOptInUsageError]
+        return dateProvider.getDate() + locationProvider.getLocation();
+                                                         ~~~~~~~~~~~
+2 errors, 0 warnings
+        """.trimIndent()
+        /* ktlint-enable max-line-length */
+
+        check(*input).expect(expected)
+    }
+
+    @Test
     fun useJavaExperimentalFromKt() {
         val input = arrayOf(
             javaSample("sample.experimental.DateProvider"),
diff --git a/development/referenceDocs/stageReferenceDocsWithDackka.sh b/development/referenceDocs/stageReferenceDocsWithDackka.sh
index b69bb6c..d3e12d7 100755
--- a/development/referenceDocs/stageReferenceDocsWithDackka.sh
+++ b/development/referenceDocs/stageReferenceDocsWithDackka.sh
@@ -27,6 +27,7 @@
 #  "collection"
   "navigation"
   "paging"
+  "wear"
   "window"
 )
 readonly kotlinLibraryDirs=(
@@ -35,6 +36,7 @@
 #  "collection"
   "navigation"
   "paging"
+  "wear"
   "window"
 )
 
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index 5e27f26..587c7cc 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -11,11 +11,11 @@
     docs("androidx.ads:ads-identifier:1.0.0-alpha04")
     docs("androidx.ads:ads-identifier-provider:1.0.0-alpha04")
     docs("androidx.annotation:annotation:1.3.0-alpha01")
-    docs("androidx.annotation:annotation-experimental:1.1.0")
-    docs("androidx.appcompat:appcompat:1.4.0-alpha02")
-    docs("androidx.appcompat:appcompat-resources:1.4.0-alpha02")
-    docs("androidx.appsearch:appsearch:1.0.0-alpha01")
-    docs("androidx.appsearch:appsearch-local-storage:1.0.0-alpha01")
+    docs("androidx.annotation:annotation-experimental:1.2.0-alpha01")
+    docs("androidx.appcompat:appcompat:1.4.0-alpha03")
+    docs("androidx.appcompat:appcompat-resources:1.4.0-alpha03")
+    docs("androidx.appsearch:appsearch:1.0.0-alpha02")
+    docs("androidx.appsearch:appsearch-local-storage:1.0.0-alpha02")
     docs("androidx.arch.core:core-common:2.1.0")
     docs("androidx.arch.core:core-runtime:2.1.0")
     docs("androidx.arch.core:core-testing:2.1.0")
@@ -29,12 +29,12 @@
     docs("androidx.biometric:biometric-ktx:1.2.0-alpha03")
     samples("androidx.biometric:biometric-ktx-samples:1.2.0-alpha03")
     docs("androidx.browser:browser:1.3.0")
-    docs("androidx.camera:camera-camera2:1.1.0-alpha05")
-    docs("androidx.camera:camera-core:1.1.0-alpha05")
-    docs("androidx.camera:camera-extensions:1.0.0-alpha25")
+    docs("androidx.camera:camera-camera2:1.1.0-alpha06")
+    docs("androidx.camera:camera-core:1.1.0-alpha06")
+    docs("androidx.camera:camera-extensions:1.0.0-alpha26")
     stubs(fileTree(dir: "../camera/camera-extensions-stub", include: ["camera-extensions-stub.jar"]))
-    docs("androidx.camera:camera-lifecycle:1.1.0-alpha05")
-    docs("androidx.camera:camera-view:1.0.0-alpha25")
+    docs("androidx.camera:camera-lifecycle:1.1.0-alpha06")
+    docs("androidx.camera:camera-view:1.0.0-alpha26")
     docs("androidx.car.app:app:1.1.0-alpha01")
     docs("androidx.car.app:app-automotive:1.1.0-alpha01")
     docs("androidx.car.app:app-testing:1.1.0-alpha01")
@@ -85,38 +85,40 @@
     docs("androidx.concurrent:concurrent-futures-ktx:1.1.0")
     docs("androidx.contentpager:contentpager:1.0.0")
     docs("androidx.coordinatorlayout:coordinatorlayout:1.1.0")
-    docs("androidx.core:core-google-shortcuts:1.0.0-rc01")
+    docs("androidx.core:core-google-shortcuts:1.0.0")
     docs("androidx.core:core-role:1.1.0-alpha02")
     docs("androidx.core:core-animation:1.0.0-alpha02")
     docs("androidx.core:core-animation-testing:1.0.0-alpha02")
-    docs("androidx.core:core:1.6.0-rc01")
-    docs("androidx.core:core-ktx:1.6.0-rc01")
+    docs("androidx.core:core:1.7.0-alpha01")
+    docs("androidx.core:core-ktx:1.7.0-alpha01")
+    docs("androidx.core:core-splashscreen:1.0.0-alpha01")
     docs("androidx.cursoradapter:cursoradapter:1.0.0")
     docs("androidx.customview:customview:1.1.0")
-    docs("androidx.datastore:datastore:1.0.0-beta02")
-    docs("androidx.datastore:datastore-core:1.0.0-beta02")
-    docs("androidx.datastore:datastore-preferences:1.0.0-beta02")
-    docs("androidx.datastore:datastore-preferences-core:1.0.0-beta02")
-    docs("androidx.datastore:datastore-preferences-rxjava2:1.0.0-beta02")
-    docs("androidx.datastore:datastore-preferences-rxjava3:1.0.0-beta02")
-    docs("androidx.datastore:datastore-rxjava2:1.0.0-beta02")
-    docs("androidx.datastore:datastore-rxjava3:1.0.0-beta02")
+    docs("androidx.datastore:datastore:1.0.0-rc01")
+    docs("androidx.datastore:datastore-core:1.0.0-rc01")
+    docs("androidx.datastore:datastore-preferences:1.0.0-rc01")
+    docs("androidx.datastore:datastore-preferences-core:1.0.0-rc01")
+    docs("androidx.datastore:datastore-preferences-rxjava2:1.0.0-rc01")
+    docs("androidx.datastore:datastore-preferences-rxjava3:1.0.0-rc01")
+    docs("androidx.datastore:datastore-rxjava2:1.0.0-rc01")
+    docs("androidx.datastore:datastore-rxjava3:1.0.0-rc01")
     docs("androidx.documentfile:documentfile:1.0.0")
     docs("androidx.drawerlayout:drawerlayout:1.1.1")
     docs("androidx.dynamicanimation:dynamicanimation:1.1.0-alpha02")
     docs("androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03")
-    docs("androidx.emoji2:emoji2:1.0.0-alpha02")
-    docs("androidx.emoji2:emoji2-views:1.0.0-alpha02")
-    docs("androidx.emoji2:emoji2-views-helper:1.0.0-alpha02")
+    docs("androidx.emoji2:emoji2:1.0.0-alpha03")
+    docs("androidx.emoji2:emoji2-bundled:1.0.0-alpha03")
+    docs("androidx.emoji2:emoji2-views:1.0.0-alpha03")
+    docs("androidx.emoji2:emoji2-views-helper:1.0.0-alpha03")
     docs("androidx.emoji:emoji:1.2.0-alpha03")
     docs("androidx.emoji:emoji-appcompat:1.2.0-alpha03")
     docs("androidx.emoji:emoji-bundled:1.2.0-alpha03")
     docs("androidx.enterprise:enterprise-feedback:1.1.0")
     docs("androidx.enterprise:enterprise-feedback-testing:1.1.0")
     docs("androidx.exifinterface:exifinterface:1.3.2")
-    docs("androidx.fragment:fragment:1.4.0-alpha03")
-    docs("androidx.fragment:fragment-ktx:1.4.0-alpha03")
-    docs("androidx.fragment:fragment-testing:1.4.0-alpha03")
+    docs("androidx.fragment:fragment:1.4.0-alpha04")
+    docs("androidx.fragment:fragment-ktx:1.4.0-alpha04")
+    docs("androidx.fragment:fragment-testing:1.4.0-alpha04")
     docs("androidx.gridlayout:gridlayout:1.0.0")
     docs("androidx.health:health-services-client:1.0.0-alpha01")
     docs("androidx.heifwriter:heifwriter:1.1.0-alpha01")
@@ -151,36 +153,36 @@
     docs("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.0-alpha02")
     docs("androidx.loader:loader:1.1.0")
     docs("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0-alpha01")
-    docs("androidx.media2:media2-common:1.2.0-alpha01")
-    docs("androidx.media2:media2-player:1.2.0-alpha01")
-    docs("androidx.media2:media2-session:1.2.0-alpha01")
-    docs("androidx.media2:media2-widget:1.2.0-alpha01")
-    docs("androidx.media:media:1.4.0-beta01")
+    docs("androidx.media2:media2-common:1.2.0-beta01")
+    docs("androidx.media2:media2-player:1.2.0-beta01")
+    docs("androidx.media2:media2-session:1.2.0-beta01")
+    docs("androidx.media2:media2-widget:1.2.0-beta01")
+    docs("androidx.media:media:1.4.0-rc01")
     docs("androidx.mediarouter:mediarouter:1.2.4")
-    docs("androidx.navigation:navigation-common:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-common-ktx:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-compose:2.4.0-alpha03")
-    samples("androidx.navigation:navigation-compose-samples:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-dynamic-features-fragment:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-dynamic-features-runtime:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-fragment:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-fragment-ktx:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-runtime:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-runtime-ktx:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-testing:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-ui:2.4.0-alpha03")
-    docs("androidx.navigation:navigation-ui-ktx:2.4.0-alpha03")
-    docs("androidx.paging:paging-common:3.1.0-alpha01")
-    docs("androidx.paging:paging-common-ktx:3.1.0-alpha01")
-    docs("androidx.paging:paging-compose:1.0.0-alpha10")
+    docs("androidx.navigation:navigation-common:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-common-ktx:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-compose:2.4.0-alpha04")
+    samples("androidx.navigation:navigation-compose-samples:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-dynamic-features-fragment:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-dynamic-features-runtime:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-fragment:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-fragment-ktx:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-runtime:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-runtime-ktx:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-testing:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-ui:2.4.0-alpha04")
+    docs("androidx.navigation:navigation-ui-ktx:2.4.0-alpha04")
+    docs("androidx.paging:paging-common:3.1.0-alpha02")
+    docs("androidx.paging:paging-common-ktx:3.1.0-alpha02")
+    docs("androidx.paging:paging-compose:1.0.0-alpha11")
     samples("androidx.paging:paging-compose-samples:3.0.0-alpha08")
-    docs("androidx.paging:paging-guava:3.1.0-alpha01")
-    docs("androidx.paging:paging-runtime:3.1.0-alpha01")
-    docs("androidx.paging:paging-runtime-ktx:3.1.0-alpha01")
-    docs("androidx.paging:paging-rxjava2:3.1.0-alpha01")
-    docs("androidx.paging:paging-rxjava2-ktx:3.1.0-alpha01")
-    docs("androidx.paging:paging-rxjava3:3.1.0-alpha01")
-    samples("androidx.paging:paging-samples:3.1.0-alpha01")
+    docs("androidx.paging:paging-guava:3.1.0-alpha02")
+    docs("androidx.paging:paging-runtime:3.1.0-alpha02")
+    docs("androidx.paging:paging-runtime-ktx:3.1.0-alpha02")
+    docs("androidx.paging:paging-rxjava2:3.1.0-alpha02")
+    docs("androidx.paging:paging-rxjava2-ktx:3.1.0-alpha02")
+    docs("androidx.paging:paging-rxjava3:3.1.0-alpha02")
+    samples("androidx.paging:paging-samples:3.1.0-alpha02")
     docs("androidx.palette:palette:1.0.0")
     docs("androidx.palette:palette-ktx:1.0.0")
     docs("androidx.percentlayout:percentlayout:1.0.1")
@@ -192,7 +194,7 @@
     docs("androidx.recyclerview:recyclerview:1.2.1")
     docs("androidx.recyclerview:recyclerview-selection:2.0.0-alpha01")
     docs("androidx.remotecallback:remotecallback:1.0.0-alpha02")
-    docs("androidx.resourceinspection:resourceinspection-annotation:1.0.0-alpha02")
+    docs("androidx.resourceinspection:resourceinspection-annotation:1.0.0-alpha03")
     docs("androidx.room:room-common:2.4.0-alpha03")
     docs("androidx.room:room-guava:2.4.0-alpha03")
     docs("androidx.room:room-ktx:2.4.0-alpha03")
@@ -213,7 +215,7 @@
     docs("androidx.slice:slice-builders-ktx:1.0.0-alpha08")
     docs("androidx.slice:slice-core:1.1.0-alpha02")
     docs("androidx.slice:slice-view:1.1.0-alpha02")
-    docs("androidx.slidingpanelayout:slidingpanelayout:1.2.0-alpha02")
+    docs("androidx.slidingpanelayout:slidingpanelayout:1.2.0-alpha03")
     docs("androidx.sqlite:sqlite:2.2.0-alpha01")
     docs("androidx.sqlite:sqlite-framework:2.2.0-alpha01")
     docs("androidx.sqlite:sqlite-ktx:2.2.0-alpha01")
@@ -232,35 +234,37 @@
     docs("androidx.versionedparcelable:versionedparcelable:1.1.1")
     docs("androidx.viewpager2:viewpager2:1.1.0-alpha01")
     docs("androidx.viewpager:viewpager:1.0.0")
-    docs("androidx.wear.tiles:tiles:1.0.0-alpha07")
-    docs("androidx.wear.tiles:tiles-renderer:1.0.0-alpha07")
-    docs("androidx.wear:wear:1.2.0-alpha10")
+    docs("androidx.wear.compose:compose-foundation:1.0.0-alpha01")
+    docs("androidx.wear.compose:compose-material:1.0.0-alpha01")
+    docs("androidx.wear.tiles:tiles:1.0.0-alpha08")
+    docs("androidx.wear.tiles:tiles-renderer:1.0.0-alpha08")
+    docs("androidx.wear:wear:1.2.0-alpha11")
     stubs(fileTree(dir: "../wear/wear_stubs/", include: ["com.google.android.wearable-stubs.jar"]))
-    docs("androidx.wear:wear-complications-data:1.0.0-alpha16")
-    docs("androidx.wear:wear-complications-provider:1.0.0-alpha16")
+    docs("androidx.wear:wear-complications-data:1.0.0-alpha17")
+    docs("androidx.wear:wear-complications-provider:1.0.0-alpha17")
     docs("androidx.wear:wear-ongoing:1.0.0-alpha07")
-    docs("androidx.wear:wear-phone-interactions:1.0.0-alpha04")
+    docs("androidx.wear:wear-phone-interactions:1.0.0-alpha05")
     docs("androidx.wear:wear-remote-interactions:1.0.0-alpha03")
-    docs("androidx.wear:wear-watchface:1.0.0-alpha16")
-    docs("androidx.wear:wear-watchface-client:1.0.0-alpha16")
-    docs("androidx.wear:wear-watchface-client-guava:1.0.0-alpha16")
-    docs("androidx.wear:wear-watchface-complications-rendering:1.0.0-alpha16")
-    docs("androidx.wear:wear-watchface-data:1.0.0-alpha16")
-    docs("androidx.wear:wear-watchface-editor:1.0.0-alpha16")
-    docs("androidx.wear:wear-watchface-editor-guava:1.0.0-alpha16")
-    docs("androidx.wear:wear-watchface-guava:1.0.0-alpha16")
+    docs("androidx.wear:wear-watchface:1.0.0-alpha17")
+    docs("androidx.wear:wear-watchface-client:1.0.0-alpha17")
+    docs("androidx.wear:wear-watchface-client-guava:1.0.0-alpha17")
+    docs("androidx.wear:wear-watchface-complications-rendering:1.0.0-alpha17")
+    docs("androidx.wear:wear-watchface-data:1.0.0-alpha17")
+    docs("androidx.wear:wear-watchface-editor:1.0.0-alpha17")
+    docs("androidx.wear:wear-watchface-editor-guava:1.0.0-alpha17")
+    docs("androidx.wear:wear-watchface-guava:1.0.0-alpha17")
     samples("androidx.wear:wear-watchface-samples:1.0.0-alpha02")
-    docs("androidx.wear:wear-watchface-style:1.0.0-alpha16")
-    docs("androidx.wear:wear-input:1.1.0-alpha02")
-    docs("androidx.wear:wear-input-testing:1.1.0-alpha02")
+    docs("androidx.wear:wear-watchface-style:1.0.0-alpha17")
+    docs("androidx.wear:wear-input:1.1.0-alpha03")
+    docs("androidx.wear:wear-input-testing:1.1.0-alpha03")
     docs("androidx.webkit:webkit:1.4.0")
-    docs("androidx.window:window:1.0.0-alpha08")
+    docs("androidx.window:window:1.0.0-alpha09")
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
     stubs(project(":window:window-extensions"))
-    docs("androidx.window:window-java:1.0.0-alpha08")
-    docs("androidx.window:window-rxjava2:1.0.0-alpha08")
-    docs("androidx.window:window-rxjava3:1.0.0-alpha08")
-    docs("androidx.window:window-testing:1.0.0-alpha08")
+    docs("androidx.window:window-java:1.0.0-alpha09")
+    docs("androidx.window:window-rxjava2:1.0.0-alpha09")
+    docs("androidx.window:window-rxjava3:1.0.0-alpha09")
+    docs("androidx.window:window-testing:1.0.0-alpha09")
     docs("androidx.work:work-gcm:2.7.0-alpha04")
     docs("androidx.work:work-multiprocess:2.7.0-alpha04")
     docs("androidx.work:work-runtime:2.7.0-alpha04")
diff --git a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UnsafeFragmentLifecycleObserverDetector.kt b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UnsafeFragmentLifecycleObserverDetector.kt
index bddfb6c..e38eb4e 100644
--- a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UnsafeFragmentLifecycleObserverDetector.kt
+++ b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UnsafeFragmentLifecycleObserverDetector.kt
@@ -34,6 +34,8 @@
 import com.intellij.psi.util.PsiTypesUtil
 import org.jetbrains.uast.UCallExpression
 import org.jetbrains.uast.UClass
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.UastFacade
 import org.jetbrains.uast.getContainingUClass
 import org.jetbrains.uast.visitor.AbstractUastVisitor
 
@@ -125,9 +127,12 @@
         }
         val psiMethod = node.resolve() ?: return super.visitCallExpression(node)
         if (!checkCall(node, psiMethod) && node.isInteresting(context)) {
-            val uastNode = context.uastContext.getMethod(psiMethod)
+            val uastNode = UastFacade.convertElementWithParent(
+                psiMethod,
+                UMethod::class.java
+            ) as? UMethod
             visitedMethods.add(node)
-            uastNode.uastBody?.accept(this)
+            uastNode?.uastBody?.accept(this)
             visitedMethods.remove(node)
         }
         return super.visitCallExpression(node)
diff --git a/fragment/fragment-lint/src/test/java/androidx/fragment/lint/ApiLintVersionsTest.kt b/fragment/fragment-lint/src/test/java/androidx/fragment/lint/ApiLintVersionsTest.kt
index 1843af7..c5e38ba 100644
--- a/fragment/fragment-lint/src/test/java/androidx/fragment/lint/ApiLintVersionsTest.kt
+++ b/fragment/fragment-lint/src/test/java/androidx/fragment/lint/ApiLintVersionsTest.kt
@@ -35,6 +35,6 @@
         assertThat(registry.api).isEqualTo(CURRENT_API)
         // Intentionally fails in IDE, because we use different API version in
         // studio and command line
-        assertThat(registry.minApi).isEqualTo(3)
+        assertThat(registry.minApi).isEqualTo(8)
     }
 }
diff --git a/fragment/fragment-testing-lint/src/test/java/androidx/fragment/testing/lint/ApiLintVersionsTest.kt b/fragment/fragment-testing-lint/src/test/java/androidx/fragment/testing/lint/ApiLintVersionsTest.kt
index 3b3e222..3b659c7 100644
--- a/fragment/fragment-testing-lint/src/test/java/androidx/fragment/testing/lint/ApiLintVersionsTest.kt
+++ b/fragment/fragment-testing-lint/src/test/java/androidx/fragment/testing/lint/ApiLintVersionsTest.kt
@@ -36,6 +36,6 @@
         assertThat(registry.api).isEqualTo(CURRENT_API)
         // Intentionally fails in IDE, because we use different API version in
         // studio and command line
-        assertThat(registry.minApi).isEqualTo(3)
+        assertThat(registry.minApi).isEqualTo(8)
     }
 }
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4762f5a..5887db6 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -11,7 +11,7 @@
 androidStudio = "2021.1.1.2"
 # -----------------------------------------------------------------------------
 
-androidLintMin = "26.3.0"
+androidLintMin = "27.2.1"
 # Compose 1.0 stable is aligned with AGP 7.0 / Lint 30.0.0 stable - so we use a higher min to
 # compile against as we don't need to maintain compatibility with older versions of Lint.
 # TODO: update to 30.0.0 stable when it is released
diff --git a/lifecycle/lifecycle-livedata-core-ktx-lint/src/test/java/androidx/lifecycle/lint/ApiLintVersionsTest.kt b/lifecycle/lifecycle-livedata-core-ktx-lint/src/test/java/androidx/lifecycle/lint/ApiLintVersionsTest.kt
index 0cdb8ac..24e2a9d 100644
--- a/lifecycle/lifecycle-livedata-core-ktx-lint/src/test/java/androidx/lifecycle/lint/ApiLintVersionsTest.kt
+++ b/lifecycle/lifecycle-livedata-core-ktx-lint/src/test/java/androidx/lifecycle/lint/ApiLintVersionsTest.kt
@@ -36,6 +36,6 @@
         // We hardcode version registry.api to the version that is used to run tests.
         assertEquals("registry.api matches version used to run tests", CURRENT_API, registry.api)
         // Intentionally fails in IDE, because we use different API version in Studio and CLI.
-        assertEquals("registry.minApi is set to minimum level of 3", 3, registry.minApi)
+        assertEquals("registry.minApi is set to minimum level of 8", 8, registry.minApi)
     }
 }
diff --git a/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/RepeatOnLifecycleDetector.kt b/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/RepeatOnLifecycleDetector.kt
index e0c8906..7d42aa1 100644
--- a/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/RepeatOnLifecycleDetector.kt
+++ b/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/RepeatOnLifecycleDetector.kt
@@ -28,6 +28,8 @@
 import com.intellij.psi.PsiMethod
 import org.jetbrains.uast.UCallExpression
 import org.jetbrains.uast.UClass
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.UastFacade
 import org.jetbrains.uast.visitor.AbstractUastVisitor
 
 /**
@@ -97,8 +99,11 @@
         }
         // Check current method and report if there's a wrong repeatOnLifecycle usage
         if (!checkMethodCall(psiMethod, node)) {
-            val uastNode = context.uastContext.getMethod(psiMethod)
-            uastNode.uastBody?.accept(this)
+            val uastNode = UastFacade.convertElementWithParent(
+                psiMethod,
+                UMethod::class.java
+            ) as? UMethod
+            uastNode?.uastBody?.accept(this)
         }
         return super.visitCallExpression(node)
     }
diff --git a/recyclerview/recyclerview-lint/src/test/java/androidx/recyclerview/lint/ApiLintVersionsTest.kt b/recyclerview/recyclerview-lint/src/test/java/androidx/recyclerview/lint/ApiLintVersionsTest.kt
index c291741..3478bd2 100644
--- a/recyclerview/recyclerview-lint/src/test/java/androidx/recyclerview/lint/ApiLintVersionsTest.kt
+++ b/recyclerview/recyclerview-lint/src/test/java/androidx/recyclerview/lint/ApiLintVersionsTest.kt
@@ -36,6 +36,6 @@
         // We hardcode version registry.api to the version that is used to run tests.
         assertEquals("registry.api matches version used to run tests", CURRENT_API, registry.api)
         // Intentionally fails in IDE, because we use different API version in Studio and CLI.
-        assertEquals("registry.minApi is set to minimum level of 3", 3, registry.minApi)
+        assertEquals("registry.minApi is set to minimum level of 8", 8, registry.minApi)
     }
 }
diff --git a/room/integration-tests/kotlintestapp/build.gradle b/room/integration-tests/kotlintestapp/build.gradle
index 462ad43..18bd746 100644
--- a/room/integration-tests/kotlintestapp/build.gradle
+++ b/room/integration-tests/kotlintestapp/build.gradle
@@ -88,6 +88,7 @@
 dependencies {
     implementation(project(":room:room-common"))
     implementation(project(":room:room-runtime"))
+    implementation(project(":room:room-paging"))
     implementation(projectOrArtifact(":arch:core:core-runtime"))
     implementation(projectOrArtifact(":lifecycle:lifecycle-livedata"))
     implementation(projectOrArtifact(":lifecycle:lifecycle-livedata-ktx"))
@@ -118,13 +119,15 @@
         exclude module: "hamcrest-core"
     })
     androidTestImplementation(libs.truth)
+    androidTestImplementation(libs.kotlinTest)
     androidTestImplementation(project(":room:room-guava"))
+    androidTestImplementation(project(":room:room-paging")) // Added for b/155802460
     androidTestImplementation(project(":room:room-testing"))
     androidTestImplementation(project(":room:room-rxjava2"))
     androidTestImplementation(project(":room:room-rxjava3"))
     androidTestImplementation(project(":room:room-ktx"))
     androidTestImplementation("androidx.arch.core:core-testing:2.0.1")
-    androidTestImplementation(projectOrArtifact(":paging:paging-runtime"))
+    androidTestImplementation("androidx.paging:paging-runtime:3.0.0")
     androidTestImplementation(libs.guavaAndroid)
     androidTestImplementation(libs.rxjava2)
     testImplementation(libs.mockitoCore)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/PagingSourceTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/PagingSourceTest.kt
index b3a0afd..77a0e9b 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/PagingSourceTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/PagingSourceTest.kt
@@ -174,8 +174,8 @@
                 itemStore.peekItems()
             ).containsExactlyElementsIn(
                 items.createExpected(
-                    // This is what paging picks, could change if paging's heuristic changes
-                    fromIndex = 93,
+                    // Paging 3 implementation loads starting from initial key
+                    fromIndex = 98,
                     toIndex = 100
                 )
             )
@@ -223,11 +223,21 @@
             // make sure we blocked the refresh runnable to ensure test makes sense
             queryExecutor.awaitDeferredSizeAtLeast(1)
 
-            // now paging source will not be invalidated so it doesn't know items do not exists.
-            // trigger more to load
+            /** TODO(b/191806126): This .get() call triggers a page fetch on the first generation
+             * although we wrote to DB because invalidation tracker hasn't invalidate the
+             * PagingSource yet. Currently we return a best-effort page, but this could
+             * lead to UI inconsistencies. In this particular scenario,
+             * LimitOffsetPagingSource returns item 89 but presenter doesn't update.
+             */
             itemStore.get(70)
-            // this will make it realize that it is invalid so should trigger getting a new
-            // paging source
+
+            /**
+             * Unlike old room-paging implementation through LimitOffsetDataSource, new
+             * implementation relies on InvalidationTracker to invalidate paging sources, so we
+             * need to execute the deferred refresh runnable to invalidate the paging source.
+             */
+            queryExecutor.executeAll()
+
             itemStore.awaitGeneration(2)
             itemStore.awaitInitialLoad()
             // it might be reloaded in any range so just make sure everything is there
@@ -519,6 +529,12 @@
             copy.forEach(this::execute)
         }
 
+        fun executeAll() {
+            while (deferred.isNotEmpty()) {
+                deferred.removeFirst().run()
+            }
+        }
+
         override fun execute(command: Runnable) {
             lock.withLock {
                 if (filterFunction(command)) {
diff --git a/room/integration-tests/testapp/build.gradle b/room/integration-tests/testapp/build.gradle
index 864deb5..0733b6d 100644
--- a/room/integration-tests/testapp/build.gradle
+++ b/room/integration-tests/testapp/build.gradle
@@ -98,6 +98,7 @@
     androidTestImplementation(project(":room:room-rxjava2"))
     androidTestImplementation(project(":room:room-rxjava3"))
     androidTestImplementation(project(":room:room-guava"))
+    androidTestImplementation(project(":room:room-paging"))
     androidTestImplementation("androidx.arch.core:core-testing:2.0.1")
     androidTestImplementation(projectOrArtifact(":paging:paging-runtime"))
     androidTestImplementation(projectOrArtifact(":lifecycle:lifecycle-runtime"))
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt b/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
index d57e684..90df738 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
@@ -97,6 +97,8 @@
         "$ROOM_PACKAGE.migration",
         "AutoMigrationSpec"
     )
+    val LIMIT_OFFSET_PAGING_SOURCE: ClassName =
+        ClassName.get("$ROOM_PACKAGE.paging", "LimitOffsetPagingSource")
 }
 
 object PagingTypeNames {
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/PagingSourceQueryResultBinderProvider.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/PagingSourceQueryResultBinderProvider.kt
index d6b02d3..ce3267f 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/PagingSourceQueryResultBinderProvider.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/PagingSourceQueryResultBinderProvider.kt
@@ -24,6 +24,7 @@
 import androidx.room.processor.ProcessorErrors
 import androidx.room.solver.QueryResultBinderProvider
 import androidx.room.solver.query.result.ListQueryResultAdapter
+import androidx.room.solver.query.result.CompatPagingSourceQueryResultBinder
 import androidx.room.solver.query.result.PagingSourceQueryResultBinder
 import androidx.room.solver.query.result.PositionalDataSourceQueryResultBinder
 import androidx.room.solver.query.result.QueryResultBinder
@@ -46,13 +47,25 @@
             (listAdapter?.accessedTableNames() ?: emptyList()) +
                 query.tables.map { it.name }
             ).toSet()
-        return PagingSourceQueryResultBinder(
-            PositionalDataSourceQueryResultBinder(
+
+        // If limitOffsetPagingSource is null, then it is not in the compile classpath
+        val limitOffsetPagingSource = context.processingEnv.findType(
+            "androidx.room.paging.LimitOffsetPagingSource"
+        )
+        return if (limitOffsetPagingSource != null) {
+            PagingSourceQueryResultBinder(
                 listAdapter = listAdapter,
                 tableNames = tableNames,
-                forPaging3 = true
             )
-        )
+        } else {
+            CompatPagingSourceQueryResultBinder(
+                PositionalDataSourceQueryResultBinder(
+                    listAdapter = listAdapter,
+                    tableNames = tableNames,
+                    forPaging3 = true
+                )
+            )
+        }
     }
 
     override fun matches(declared: XType): Boolean {
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PagingSourceQueryResultBinder.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PagingSourceQueryResultBinder.kt
index 30804fa..6db2f39 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PagingSourceQueryResultBinder.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PagingSourceQueryResultBinder.kt
@@ -16,9 +16,77 @@
 
 package androidx.room.solver.query.result
 
+import androidx.room.ext.AndroidTypeNames
+import androidx.room.ext.CommonTypeNames
 import androidx.room.ext.L
+import androidx.room.ext.N
+import androidx.room.ext.RoomTypeNames
+import androidx.room.solver.CodeGenScope
+import com.squareup.javapoet.FieldSpec
+import com.squareup.javapoet.MethodSpec
+import com.squareup.javapoet.ParameterSpec
+import com.squareup.javapoet.TypeSpec
+import com.squareup.javapoet.ParameterizedTypeName
+import com.squareup.javapoet.TypeName
+import javax.lang.model.element.Modifier
 
+/**
+ * This Binder uses room/room-paging artifact and binds queries directly to native Paging3
+ * PagingSource through `LimitOffsetPagingSource`. Used solely by Paging3.
+ */
 class PagingSourceQueryResultBinder(
+    private val listAdapter: ListQueryResultAdapter?,
+    private val tableNames: Set<String>,
+) : QueryResultBinder(listAdapter) {
+    private val itemTypeName: TypeName = listAdapter?.rowAdapter?.out?.typeName ?: TypeName.OBJECT
+    private val limitOffsetPagingSourceTypeNam: ParameterizedTypeName = ParameterizedTypeName.get(
+        RoomTypeNames.LIMIT_OFFSET_PAGING_SOURCE, itemTypeName
+    )
+
+    override fun convertAndReturn(
+        roomSQLiteQueryVar: String,
+        canReleaseQuery: Boolean,
+        dbField: FieldSpec,
+        inTransaction: Boolean,
+        scope: CodeGenScope
+    ) {
+        scope.builder().apply {
+            val tableNamesList = tableNames.joinToString(", ") { "\"$it\"" }
+            val limitOffsetPagingSourceSpec = TypeSpec.anonymousClassBuilder(
+                "$L, $N, $L",
+                roomSQLiteQueryVar,
+                dbField,
+                tableNamesList
+            ).apply {
+                addSuperinterface(limitOffsetPagingSourceTypeNam)
+                addMethod(createConvertRowsMethod(scope))
+            }.build()
+            addStatement("return $L", limitOffsetPagingSourceSpec)
+        }
+    }
+
+    private fun createConvertRowsMethod(scope: CodeGenScope): MethodSpec {
+        return MethodSpec.methodBuilder("convertRows").apply {
+            addAnnotation(Override::class.java)
+            addModifiers(Modifier.PROTECTED)
+            returns(ParameterizedTypeName.get(CommonTypeNames.LIST, itemTypeName))
+            val cursorParam = ParameterSpec.builder(AndroidTypeNames.CURSOR, "cursor")
+                .build()
+            addParameter(cursorParam)
+            val resultVar = scope.getTmpVar("_result")
+            val rowsScope = scope.fork()
+            listAdapter?.convert(resultVar, cursorParam.name, rowsScope)
+            addCode(rowsScope.builder().build())
+            addStatement("return $L", resultVar)
+        }.build()
+    }
+}
+
+/**
+ * A compatibility Paging3 binder that uses `LimitOffsetDataSource` along with
+ * `DataSource.Factory.asPagingSourceFactory()` to bind queries to Paging3 PagingSource.
+ */
+class CompatPagingSourceQueryResultBinder(
     positionalDataSourceQueryResultBinder: PositionalDataSourceQueryResultBinder
 ) : PagingQueryResultBinder(positionalDataSourceQueryResultBinder) {
     override fun returnStatementTemplate() = "return $L.asPagingSourceFactory().invoke()"
diff --git a/room/room-compiler/src/test/data/common/input/LimitOffsetPagingSource.java b/room/room-compiler/src/test/data/common/input/LimitOffsetPagingSource.java
new file mode 100644
index 0000000..746d607
--- /dev/null
+++ b/room/room-compiler/src/test/data/common/input/LimitOffsetPagingSource.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.room.paging;
+
+public abstract class LimitOffsetPagingSource<T> extends androidx.paging.PagingSource<Integer, T> {
+
+}
diff --git a/room/room-compiler/src/test/data/common/input/PagingSource.java b/room/room-compiler/src/test/data/common/input/PagingSource.java
new file mode 100644
index 0000000..ddfc658
--- /dev/null
+++ b/room/room-compiler/src/test/data/common/input/PagingSource.java
@@ -0,0 +1,5 @@
+package androidx.paging;
+
+public abstract class PagingSource<K, T> {
+
+}
\ No newline at end of file
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 8869c08..b881c96 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
@@ -19,7 +19,9 @@
 import COMMON
 import androidx.paging.DataSource
 import androidx.paging.PagingSource
+import androidx.room.Dao
 import androidx.room.compiler.processing.XProcessingEnv
+import androidx.room.compiler.processing.isTypeElement
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.runProcessorTest
@@ -28,6 +30,7 @@
 import androidx.room.ext.LifecyclesTypeNames
 import androidx.room.ext.PagingTypeNames
 import androidx.room.ext.ReactiveStreamsTypeNames
+import androidx.room.ext.RoomTypeNames
 import androidx.room.ext.RoomTypeNames.STRING_UTIL
 import androidx.room.ext.RxJava2TypeNames
 import androidx.room.ext.RxJava3TypeNames
@@ -35,6 +38,8 @@
 import androidx.room.parser.SQLTypeAffinity
 import androidx.room.processor.Context
 import androidx.room.processor.CustomConverterProcessor
+import androidx.room.processor.DaoProcessor
+import androidx.room.processor.DaoProcessorTest
 import androidx.room.processor.ProcessorErrors
 import androidx.room.solver.binderprovider.DataSourceFactoryQueryResultBinderProvider
 import androidx.room.solver.binderprovider.DataSourceQueryResultBinderProvider
@@ -42,6 +47,8 @@
 import androidx.room.solver.binderprovider.PagingSourceQueryResultBinderProvider
 import androidx.room.solver.binderprovider.RxQueryResultBinderProvider
 import androidx.room.solver.query.parameter.CollectionQueryParameterAdapter
+import androidx.room.solver.query.result.CompatPagingSourceQueryResultBinder
+import androidx.room.solver.query.result.PagingSourceQueryResultBinder
 import androidx.room.solver.shortcut.binderprovider.GuavaListenableFutureDeleteOrUpdateMethodBinderProvider
 import androidx.room.solver.shortcut.binderprovider.GuavaListenableFutureInsertMethodBinderProvider
 import androidx.room.solver.shortcut.binderprovider.RxCallableDeleteOrUpdateMethodBinderProvider
@@ -54,6 +61,7 @@
 import androidx.room.solver.types.PrimitiveColumnTypeAdapter
 import androidx.room.solver.types.TypeConverter
 import androidx.room.testing.context
+import androidx.room.vo.ReadQueryMethod
 import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.TypeName
 import org.hamcrest.CoreMatchers.`is`
@@ -793,6 +801,88 @@
     }
 
     @Test
+    fun testNewPagingSourceBinder() {
+        val inputSource =
+            Source.java(
+                qName = "foo.bar.MyDao",
+                code =
+                    """
+                ${DaoProcessorTest.DAO_PREFIX}
+
+                @Dao abstract class MyDao {
+                    @Query("SELECT uid FROM User")
+                    abstract androidx.paging.PagingSource<Integer, User> getAllIds();
+                }
+                    """.trimIndent()
+            )
+        runProcessorTest(
+            sources = listOf(
+                inputSource,
+                COMMON.USER,
+                COMMON.PAGING_SOURCE,
+                COMMON.LIMIT_OFFSET_PAGING_SOURCE,
+            ),
+        ) { invocation: XTestInvocation ->
+            val dao = invocation.roundEnv
+                .getElementsAnnotatedWith(
+                    Dao::class.qualifiedName!!
+                ).first()
+            check(dao.isTypeElement())
+            val dbType = invocation.context.processingEnv
+                .requireType(RoomTypeNames.ROOM_DB)
+            val parser = DaoProcessor(
+                invocation.context,
+                dao, dbType, null,
+            )
+            val parsedDao = parser.process()
+            val binder = parsedDao.queryMethods.filterIsInstance<ReadQueryMethod>()
+                .first().queryResultBinder
+            assertThat(binder is PagingSourceQueryResultBinder).isTrue()
+        }
+    }
+
+    @Test
+    fun testCompatPagingSourceBinder() {
+        val inputSource =
+            Source.java(
+                qName = "foo.bar.MyDao",
+                code =
+                    """
+                ${DaoProcessorTest.DAO_PREFIX}
+
+                @Dao abstract class MyDao {
+                    @Query("SELECT uid FROM User")
+                    abstract androidx.paging.PagingSource<Integer, User> getAllIds();
+                }
+                    """.trimIndent()
+            )
+        runProcessorTest(
+            sources = listOf(
+                inputSource,
+                COMMON.USER,
+                COMMON.PAGING_SOURCE,
+            ),
+        ) { invocation: XTestInvocation ->
+            val dao = invocation.roundEnv
+                .getElementsAnnotatedWith(
+                    Dao::class.qualifiedName!!
+                ).first()
+            check(dao.isTypeElement())
+            val dbType = invocation.context.processingEnv
+                .requireType(RoomTypeNames.ROOM_DB)
+            val parser = DaoProcessor(
+                invocation.context,
+                dao, dbType, null
+            )
+            val parsedDao = parser.process()
+            assertThat(parsedDao.queryMethods.size, `is`(1))
+            val binder = parsedDao.queryMethods.filterIsInstance<ReadQueryMethod>()
+                .first().queryResultBinder
+            assertThat(binder is CompatPagingSourceQueryResultBinder).isTrue()
+        }
+    }
+
+    @Test
     fun findDataSource() {
         runProcessorTest {
             invocation ->
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt b/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt
index 6b3adb9..32dfe82 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt
@@ -30,6 +30,7 @@
 import androidx.room.ext.RoomGuavaTypeNames
 import androidx.room.ext.RoomRxJava2TypeNames
 import androidx.room.ext.RoomRxJava3TypeNames
+import androidx.room.ext.RoomTypeNames
 import androidx.room.ext.RxJava2TypeNames
 import androidx.room.ext.RxJava3TypeNames
 import androidx.room.processor.DatabaseViewProcessor
@@ -181,6 +182,20 @@
         )
     }
 
+    val PAGING_SOURCE by lazy {
+        loadJavaCode(
+            "common/input/PagingSource.java",
+            PagingTypeNames.PAGING_SOURCE.toString()
+        )
+    }
+
+    val LIMIT_OFFSET_PAGING_SOURCE by lazy {
+        loadJavaCode(
+            "common/input/LimitOffsetPagingSource.java",
+            RoomTypeNames.LIMIT_OFFSET_PAGING_SOURCE.toString()
+        )
+    }
+
     val LISTENABLE_FUTURE by lazy {
         loadJavaCode(
             "common/input/guava/ListenableFuture.java",
diff --git a/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/ApiLintVersionsTest.kt b/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/ApiLintVersionsTest.kt
index 4bdf051..561f972 100644
--- a/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/ApiLintVersionsTest.kt
+++ b/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/ApiLintVersionsTest.kt
@@ -36,6 +36,6 @@
         // We hardcode version registry.api to the version that is used to run tests.
         assertEquals("registry.api matches version used to run tests", CURRENT_API, registry.api)
         // Intentionally fails in IDE, because we use different API version in Studio and CLI.
-        assertEquals("registry.minApi is set to minimum level of 3", 3, registry.minApi)
+        assertEquals("registry.minApi is set to minimum level of 8", 8, registry.minApi)
     }
 }
diff --git a/work/workmanager-lint/src/test/java/androidx/work/lint/ApiLintVersionsTest.kt b/work/workmanager-lint/src/test/java/androidx/work/lint/ApiLintVersionsTest.kt
index 7288459..3dc48cd 100644
--- a/work/workmanager-lint/src/test/java/androidx/work/lint/ApiLintVersionsTest.kt
+++ b/work/workmanager-lint/src/test/java/androidx/work/lint/ApiLintVersionsTest.kt
@@ -36,6 +36,6 @@
         // We hardcode version registry.api to the version that is used to run tests.
         assertEquals("registry.api matches version used to run tests", CURRENT_API, registry.api)
         // Intentionally fails in IDE, because we use different API version in Studio and CLI.
-        assertEquals("registry.minApi is set to minimum level of 3", 3, registry.minApi)
+        assertEquals("registry.minApi is set to minimum level of 8", 8, registry.minApi)
     }
 }