Merge "Add a fragment-testing-manifest artifact." into androidx-main
diff --git a/fragment/fragment-testing-manifest-lint/OWNERS b/fragment/fragment-testing-manifest-lint/OWNERS
new file mode 100644
index 0000000..80569a3
--- /dev/null
+++ b/fragment/fragment-testing-manifest-lint/OWNERS
@@ -0,0 +1 @@
[email protected]
diff --git a/fragment/fragment-testing-manifest-lint/build.gradle b/fragment/fragment-testing-manifest-lint/build.gradle
new file mode 100644
index 0000000..afa4705
--- /dev/null
+++ b/fragment/fragment-testing-manifest-lint/build.gradle
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+import androidx.build.LibraryType
+
+plugins {
+ id("AndroidXPlugin")
+ id("kotlin")
+}
+
+dependencies {
+ compileOnly(libs.androidLintMinApi)
+ compileOnly(libs.kotlinStdlib)
+
+ testImplementation(libs.kotlinStdlib)
+ testImplementation(libs.androidLint)
+ testImplementation(libs.androidLintTests)
+ testImplementation(libs.junit)
+ testImplementation(libs.truth)
+}
+
+androidx {
+ name = "Android Fragment-Testing-Manifest Lint Checks"
+ type = LibraryType.LINT
+ mavenGroup = LibraryGroups.FRAGMENT
+ inceptionYear = "2022"
+ description = "Lint Checks for the Fragment Testing Manifest module"
+}
diff --git a/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/FragmentTestingManifestIssueRegistry.kt b/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/FragmentTestingManifestIssueRegistry.kt
new file mode 100644
index 0000000..7ce1350
--- /dev/null
+++ b/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/FragmentTestingManifestIssueRegistry.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.fragment.testing.manifest.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+
+@Suppress("UnstableApiUsage")
+class FragmentTestingManifestIssueRegistry : IssueRegistry() {
+ override val api = 13
+ override val minApi = CURRENT_API
+ override val issues get() = listOf(GradleConfigurationDetector.ISSUE)
+ override val vendor = Vendor(
+ feedbackUrl = "https://issuetracker.google.com/issues/new?component=460964",
+ identifier = "androidx.fragment.testing.manifest",
+ vendorName = "Android Open Source Project",
+ )
+}
diff --git a/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetector.kt b/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetector.kt
new file mode 100644
index 0000000..c493e4f
--- /dev/null
+++ b/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetector.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.fragment.testing.manifest.lint
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.GradleContext
+import com.android.tools.lint.detector.api.GradleScanner
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+
+/**
+ * Lint check for ensuring that the Fragment Testing library is included using the correct
+ * debugImplementation configuration.
+ */
+class GradleConfigurationDetector : Detector(), GradleScanner {
+ companion object {
+ val ISSUE = Issue.create(
+ id = "FragmentGradleConfiguration",
+ briefDescription = "Include the fragment-testing-manifest library using the " +
+ "debugImplementation configuration.",
+ explanation = """The fragment-testing-manifest library defines an EmptyActivity\
+ used when using FragmentScenario. Howver, it only needs to be present in testing\
+ configurations therefore use this dependency with the debugImplementation\
+ configuration.""",
+ category = Category.CORRECTNESS,
+ severity = Severity.ERROR,
+ implementation = Implementation(
+ GradleConfigurationDetector::class.java, Scope.GRADLE_SCOPE
+ ),
+ androidSpecific = true
+ ).addMoreInfo("https://d.android.com/training/basics/fragments/testing#configure")
+ }
+
+ override fun checkDslPropertyAssignment(
+ context: GradleContext,
+ property: String,
+ value: String,
+ parent: String,
+ parentParent: String?,
+ valueCookie: Any,
+ statementCookie: Any
+ ) {
+ // Remove enclosing quotes and check starting string to ensure only instances that
+ // result in the fragment-testing library being imported are checked.
+ // Non-string values cannot be resolved so invalid imports via functions, variables, etc.
+ // will not be detected.
+ val library = getStringLiteralValue(value)
+ if (library.startsWith("androidx.fragment:fragment-testing-manifest") &&
+ property != "debugImplementation"
+ ) {
+ context.report(
+ ISSUE, statementCookie, context.getLocation(statementCookie),
+ "Replace with debugImplementation.",
+ fix().replace()
+ .text(property)
+ .with("debugImplementation")
+ .build()
+ )
+ }
+ }
+
+ /**
+ * Extracts the string value from the DSL value by removing surrounding quotes.
+ *
+ * Returns an empty string if [value] is not a string literal.
+ */
+ private fun getStringLiteralValue(value: String): String {
+ if (value.length > 2 && (
+ value.startsWith("'") && value.endsWith("'") ||
+ value.startsWith("\"") && value.endsWith("\"")
+ )
+ ) {
+ return value.substring(1, value.length - 1)
+ }
+ return ""
+ }
+}
diff --git a/fragment/fragment-testing-manifest-lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry b/fragment/fragment-testing-manifest-lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
new file mode 100644
index 0000000..910866a
--- /dev/null
+++ b/fragment/fragment-testing-manifest-lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
@@ -0,0 +1 @@
+androidx.fragment.testing.manifest.lint.FragmentTestingManifestIssueRegistry
diff --git a/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/ApiLintVersionsTest.kt b/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/ApiLintVersionsTest.kt
new file mode 100644
index 0000000..bc638dd
--- /dev/null
+++ b/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/ApiLintVersionsTest.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.fragment.testing.manifest.lint
+
+import com.android.tools.lint.client.api.LintClient
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class ApiLintVersionsTest {
+
+ @Test
+ fun versionsCheck() {
+ LintClient.clientName = LintClient.CLIENT_UNIT_TESTS
+
+ val registry = FragmentTestingManifestIssueRegistry()
+ // we hardcode version registry.api to the version that is used to run tests
+ 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(10)
+ }
+}
diff --git a/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetectorTest.kt b/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetectorTest.kt
new file mode 100644
index 0000000..3980f47
--- /dev/null
+++ b/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetectorTest.kt
@@ -0,0 +1,80 @@
+/*
+ * 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.fragment.testing.manifest.lint
+
+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 GradleConfigurationDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector = GradleConfigurationDetector()
+
+ override fun getIssues(): MutableList<Issue> = mutableListOf(GradleConfigurationDetector.ISSUE)
+
+ @Test
+ fun expectPass() {
+ lint().files(
+ gradle(
+ "build.gradle",
+ """
+ dependencies {
+ debugImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+ }
+ """
+ ).indented()
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun expectFail() {
+ lint().files(
+ gradle(
+ "build.gradle",
+ """
+ dependencies {
+ androidTestImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+ }
+ """
+ ).indented()
+ )
+ .run()
+ .expect(
+ """
+ build.gradle:2: Error: Replace with debugImplementation. [FragmentGradleConfiguration]
+ androidTestImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 1 errors, 0 warnings
+ """.trimIndent()
+ )
+ .checkFix(
+ null,
+ gradle(
+ """
+ dependencies {
+ debugImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+ }
+ """
+ ).indented()
+ )
+ }
+}
diff --git a/fragment/fragment-testing-manifest/api/current.txt b/fragment/fragment-testing-manifest/api/current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/fragment/fragment-testing-manifest/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/fragment/fragment-testing-manifest/api/public_plus_experimental_current.txt b/fragment/fragment-testing-manifest/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/fragment/fragment-testing-manifest/api/public_plus_experimental_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/fragment/fragment-testing-manifest/api/res-current.txt b/fragment/fragment-testing-manifest/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/fragment/fragment-testing-manifest/api/res-current.txt
diff --git a/fragment/fragment-testing-manifest/api/restricted_current.txt b/fragment/fragment-testing-manifest/api/restricted_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/fragment/fragment-testing-manifest/api/restricted_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/fragment/fragment-testing-manifest/build.gradle b/fragment/fragment-testing-manifest/build.gradle
new file mode 100644
index 0000000..55210b93
--- /dev/null
+++ b/fragment/fragment-testing-manifest/build.gradle
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+import androidx.build.LibraryType
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+plugins {
+ id("AndroidXPlugin")
+ id("com.android.library")
+ id("kotlin-android")
+}
+
+dependencies {
+ api(project(":fragment:fragment-ktx"))
+ api(libs.kotlinStdlib)
+
+ lintPublish(project(":fragment:fragment-testing-manifest-lint"))
+}
+
+androidx {
+ name = "Fragment Testing Manifest dependency"
+ type = LibraryType.PUBLISHED_TEST_LIBRARY
+ mavenGroup = LibraryGroups.FRAGMENT
+ inceptionYear = "2022"
+ description = "Fragment testing library that should be added as a debugImplementation dependency to add properties to the debug manifest necessary for testing an application"
+}
+
+android {
+ namespace "androidx.fragment.testing.manifest"
+}
+
+tasks.withType(KotlinCompile).configureEach {
+ kotlinOptions {
+ freeCompilerArgs += [
+ "-Xjvm-default=all",
+ ]
+ }
+}
diff --git a/fragment/fragment-testing-manifest/src/main/AndroidManifest.xml b/fragment/fragment-testing-manifest/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..cbbd7bc5
--- /dev/null
+++ b/fragment/fragment-testing-manifest/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2018 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
+ <uses-permission android:name="android.permission.REORDER_TASKS" />
+ <application>
+ <activity
+ android:name="androidx.fragment.app.testing.EmptyFragmentActivity"
+ android:theme="@style/FragmentScenarioEmptyFragmentActivityTheme"
+ android:taskAffinity=""
+ android:multiprocess="true"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/fragment/fragment-testing-manifest/src/main/java/androidx/fragment/app/testing/EmptyFragmentActivity.kt b/fragment/fragment-testing-manifest/src/main/java/androidx/fragment/app/testing/EmptyFragmentActivity.kt
new file mode 100644
index 0000000..c1d6c7b
--- /dev/null
+++ b/fragment/fragment-testing-manifest/src/main/java/androidx/fragment/app/testing/EmptyFragmentActivity.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.fragment.app.testing
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import androidx.annotation.RestrictTo
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.testing.manifest.R
+
+/**
+ * An empty activity inheriting FragmentActivity. This Activity is used to host Fragment in
+ * FragmentScenario.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class EmptyFragmentActivity : FragmentActivity() {
+ @SuppressLint("RestrictedApi")
+ override fun onCreate(savedInstanceState: Bundle?) {
+ setTheme(
+ intent.getIntExtra(
+ THEME_EXTRAS_BUNDLE_KEY,
+ R.style.FragmentScenarioEmptyFragmentActivityTheme
+ )
+ )
+
+ // Checks if we have a custom FragmentFactory and set it.
+ val factory = FragmentFactoryHolderViewModel.getInstance(this).fragmentFactory
+ if (factory != null) {
+ supportFragmentManager.fragmentFactory = factory
+ }
+
+ // FragmentFactory needs to be set before calling the super.onCreate, otherwise the
+ // Activity crashes when it is recreating and there is a fragment which has no
+ // default constructor.
+ super.onCreate(savedInstanceState)
+ }
+
+ companion object {
+ const val THEME_EXTRAS_BUNDLE_KEY = "androidx.fragment.app.testing.FragmentScenario" +
+ ".EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY"
+ }
+}
\ No newline at end of file
diff --git a/fragment/fragment-testing-manifest/src/main/java/androidx/fragment/app/testing/FragmentFactoryHolderViewModel.kt b/fragment/fragment-testing-manifest/src/main/java/androidx/fragment/app/testing/FragmentFactoryHolderViewModel.kt
new file mode 100644
index 0000000..00840ca
--- /dev/null
+++ b/fragment/fragment-testing-manifest/src/main/java/androidx/fragment/app/testing/FragmentFactoryHolderViewModel.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.fragment.app.testing
+
+import androidx.activity.viewModels
+import androidx.annotation.RestrictTo
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.FragmentFactory
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+
+/**
+ * A view-model to hold a fragment factory.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class FragmentFactoryHolderViewModel : ViewModel() {
+ var fragmentFactory: FragmentFactory? = null
+
+ override fun onCleared() {
+ super.onCleared()
+ fragmentFactory = null
+ }
+
+ companion object {
+ @Suppress("MemberVisibilityCanBePrivate")
+ internal val FACTORY: ViewModelProvider.Factory =
+ object : ViewModelProvider.Factory {
+ @Suppress("UNCHECKED_CAST")
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ val viewModel =
+ FragmentFactoryHolderViewModel()
+ return viewModel as T
+ }
+ }
+
+ fun getInstance(activity: FragmentActivity): FragmentFactoryHolderViewModel {
+ val viewModel: FragmentFactoryHolderViewModel by activity.viewModels { FACTORY }
+ return viewModel
+ }
+ }
+}
\ No newline at end of file
diff --git a/fragment/fragment-testing/src/main/res/values/styles.xml b/fragment/fragment-testing-manifest/src/main/res/values/styles.xml
similarity index 100%
rename from fragment/fragment-testing/src/main/res/values/styles.xml
rename to fragment/fragment-testing-manifest/src/main/res/values/styles.xml
diff --git a/fragment/fragment-testing/build.gradle b/fragment/fragment-testing/build.gradle
index 2d36b95..919eb6c 100644
--- a/fragment/fragment-testing/build.gradle
+++ b/fragment/fragment-testing/build.gradle
@@ -27,6 +27,7 @@
api(project(":fragment:fragment-ktx"))
api(libs.testCore)
api(libs.kotlinStdlib)
+ api(project(":fragment:fragment-testing-manifest"))
androidTestImplementation(libs.kotlinStdlib)
androidTestImplementation(libs.espressoCore)
androidTestImplementation(libs.testExtJunit)
diff --git a/fragment/fragment-testing/src/main/AndroidManifest.xml b/fragment/fragment-testing/src/main/AndroidManifest.xml
index 9b9e0e1a..9968c17 100644
--- a/fragment/fragment-testing/src/main/AndroidManifest.xml
+++ b/fragment/fragment-testing/src/main/AndroidManifest.xml
@@ -18,17 +18,7 @@
xmlns:tools="http://schemas.android.com/tools">
<!-- TODO: Remove this override after androidx.test:core lowers the level -->
<uses-sdk tools:overrideLibrary="androidx.test.core" />
- <uses-permission android:name="android.permission.REORDER_TASKS" />
<application>
- <activity
- android:name="androidx.fragment.app.testing.FragmentScenario$EmptyFragmentActivity"
- android:theme="@style/FragmentScenarioEmptyFragmentActivityTheme"
- android:taskAffinity=""
- android:multiprocess="true"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
+
</application>
</manifest>
\ No newline at end of file
diff --git a/fragment/fragment-testing/src/main/java/androidx/fragment/app/testing/FragmentScenario.kt b/fragment/fragment-testing/src/main/java/androidx/fragment/app/testing/FragmentScenario.kt
index f32df12..b90929fe 100644
--- a/fragment/fragment-testing/src/main/java/androidx/fragment/app/testing/FragmentScenario.kt
+++ b/fragment/fragment-testing/src/main/java/androidx/fragment/app/testing/FragmentScenario.kt
@@ -20,7 +20,6 @@
import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
-import androidx.activity.viewModels
import androidx.annotation.IdRes
import androidx.annotation.StyleRes
import androidx.fragment.app.Fragment
@@ -28,10 +27,8 @@
import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.commitNow
import androidx.fragment.app.testing.FragmentScenario.Companion.launch
-import androidx.fragment.testing.R
+import androidx.fragment.testing.manifest.R
import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import java.io.Closeable
@@ -239,68 +236,6 @@
) : Closeable {
/**
- * An empty activity inheriting FragmentActivity. This Activity is used to host Fragment in
- * FragmentScenario.
- */
- internal class EmptyFragmentActivity : FragmentActivity() {
- @SuppressLint("RestrictedApi")
- override fun onCreate(savedInstanceState: Bundle?) {
- setTheme(
- intent.getIntExtra(
- THEME_EXTRAS_BUNDLE_KEY,
- R.style.FragmentScenarioEmptyFragmentActivityTheme
- )
- )
-
- // Checks if we have a custom FragmentFactory and set it.
- val factory = FragmentFactoryHolderViewModel.getInstance(this).fragmentFactory
- if (factory != null) {
- supportFragmentManager.fragmentFactory = factory
- }
-
- // FragmentFactory needs to be set before calling the super.onCreate, otherwise the
- // Activity crashes when it is recreating and there is a fragment which has no
- // default constructor.
- super.onCreate(savedInstanceState)
- }
-
- companion object {
- const val THEME_EXTRAS_BUNDLE_KEY = "androidx.fragment.app.testing.FragmentScenario" +
- ".EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY"
- }
- }
-
- /**
- * A view-model to hold a fragment factory.
- */
- internal class FragmentFactoryHolderViewModel : ViewModel() {
- var fragmentFactory: FragmentFactory? = null
-
- override fun onCleared() {
- super.onCleared()
- fragmentFactory = null
- }
-
- companion object {
- @Suppress("MemberVisibilityCanBePrivate")
- internal val FACTORY: ViewModelProvider.Factory =
- object : ViewModelProvider.Factory {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- val viewModel =
- FragmentFactoryHolderViewModel()
- return viewModel as T
- }
- }
-
- fun getInstance(activity: FragmentActivity): FragmentFactoryHolderViewModel {
- val viewModel: FragmentFactoryHolderViewModel by activity.viewModels { FACTORY }
- return viewModel
- }
- }
- }
-
- /**
* Moves Fragment state to a new state.
*
* If a new state and current state are the same, this method does nothing. It accepts
diff --git a/fragment/integration-tests/testapp/build.gradle b/fragment/integration-tests/testapp/build.gradle
index f49848c..17004dc 100644
--- a/fragment/integration-tests/testapp/build.gradle
+++ b/fragment/integration-tests/testapp/build.gradle
@@ -37,6 +37,13 @@
implementation(project(":fragment:fragment-ktx"))
implementation("androidx.transition:transition:1.3.0")
implementation("androidx.recyclerview:recyclerview:1.1.0")
+ debugImplementation(project(":fragment:fragment-testing-manifest"))
+
+ androidTestImplementation(project(":fragment:fragment-testing"))
+ androidTestImplementation(libs.testExtJunit)
+ androidTestImplementation(libs.testRunner)
+ androidTestImplementation(libs.truth)
+ androidTestImplementation(libs.espressoCore)
}
tasks["check"].dependsOn(tasks["connectedCheck"])
diff --git a/fragment/integration-tests/testapp/src/androidTest/java/androidx/fragment/testapp/SimpleFragmentTest.kt b/fragment/integration-tests/testapp/src/androidTest/java/androidx/fragment/testapp/SimpleFragmentTest.kt
new file mode 100644
index 0000000..5ef3ea4
--- /dev/null
+++ b/fragment/integration-tests/testapp/src/androidTest/java/androidx/fragment/testapp/SimpleFragmentTest.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 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.fragment.testapp
+
+import androidx.fragment.app.testing.launchFragment
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Simple integration test to verify FragmentScenario behavior in an app module.
+ */
+@RunWith(AndroidJUnit4::class)
+@LargeTest
+class SimpleFragmentTest {
+ @Test
+ fun fragmentScenario() {
+ with(launchFragment<SimpleFragment>()) {
+ }
+ }
+}
diff --git a/fragment/integration-tests/testapp/src/main/java/androidx/fragment/testapp/SimpleFragment.kt b/fragment/integration-tests/testapp/src/main/java/androidx/fragment/testapp/SimpleFragment.kt
new file mode 100644
index 0000000..00c06ea
--- /dev/null
+++ b/fragment/integration-tests/testapp/src/main/java/androidx/fragment/testapp/SimpleFragment.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 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.fragment.testapp
+
+import androidx.fragment.app.Fragment
+
+class SimpleFragment : Fragment(R.layout.simple_fragment)
diff --git a/fragment/integration-tests/testapp/src/main/res/layout/simple_fragment.xml b/fragment/integration-tests/testapp/src/main/res/layout/simple_fragment.xml
new file mode 100644
index 0000000..17e99b5
--- /dev/null
+++ b/fragment/integration-tests/testapp/src/main/res/layout/simple_fragment.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/textView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+</LinearLayout>
diff --git a/settings.gradle b/settings.gradle
index aa8e498..2a444ec 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -653,6 +653,8 @@
includeProject(":fragment:fragment-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
includeProject(":fragment:fragment-testing", [BuildType.MAIN, BuildType.FLAN])
includeProject(":fragment:fragment-testing-lint", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":fragment:fragment-testing-manifest", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":fragment:fragment-testing-manifest-lint", [BuildType.MAIN, BuildType.FLAN])
includeProject(":fragment:fragment-truth", [BuildType.MAIN, BuildType.FLAN])
includeProject(":fragment:integration-tests:testapp", [BuildType.MAIN, BuildType.FLAN])
includeProject(":glance:glance", [BuildType.GLANCE])