Start ktx for fragment.
Bug: 73289685
Bug: 69247886
Test: ./gradlew :fragment-ktx:cC
Change-Id: Ia4bc50b2141cd507ad8c3c3ad11fd58578239607
diff --git a/fragment/ktx/OWNERS b/fragment/ktx/OWNERS
new file mode 100644
index 0000000..e450f4c
--- /dev/null
+++ b/fragment/ktx/OWNERS
@@ -0,0 +1 @@
+jakew@google.com
diff --git a/fragment/ktx/build.gradle b/fragment/ktx/build.gradle
new file mode 100644
index 0000000..52cb265
--- /dev/null
+++ b/fragment/ktx/build.gradle
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+import static androidx.build.dependencies.DependenciesKt.*
+import androidx.build.LibraryGroups
+import androidx.build.LibraryVersions
+
+plugins {
+ id("SupportAndroidLibraryPlugin")
+ id("org.jetbrains.kotlin.android")
+}
+
+android {
+ buildTypes {
+ debug {
+ testCoverageEnabled = false // Breaks Kotlin compiler.
+ }
+ }
+}
+
+dependencies {
+ api(project(":fragment"))
+ api(KOTLIN_STDLIB)
+ androidTestImplementation(JUNIT)
+ androidTestImplementation(TRUTH)
+ androidTestImplementation(TEST_RUNNER_TMP, libs.exclude_for_espresso)
+ androidTestImplementation(TEST_RULES_TMP, libs.exclude_for_espresso)
+}
+
+supportLibrary {
+ name = "Fragment Kotlin Extensions"
+ publish = true
+ mavenVersion = LibraryVersions.SUPPORT_LIBRARY
+ mavenGroup = LibraryGroups.FRAGMENT
+ inceptionYear = "2018"
+ description = "Kotlin extensions for 'fragment' artifact"
+}
diff --git a/fragment/ktx/src/androidTest/AndroidManifest.xml b/fragment/ktx/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..0a62e3e
--- /dev/null
+++ b/fragment/ktx/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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"
+ package="androidx.fragment.ktx">
+ <application>
+ <activity android:name="androidx.fragment.app.TestActivity"/>
+ </application>
+</manifest>
diff --git a/fragment/ktx/src/androidTest/java/androidx/fragment/app/FragmentManagerTest.kt b/fragment/ktx/src/androidTest/java/androidx/fragment/app/FragmentManagerTest.kt
new file mode 100644
index 0000000..7097955
--- /dev/null
+++ b/fragment/ktx/src/androidTest/java/androidx/fragment/app/FragmentManagerTest.kt
@@ -0,0 +1,59 @@
+package androidx.fragment.app
+
+import android.support.test.annotation.UiThreadTest
+import android.support.test.filters.MediumTest
+import android.support.test.rule.ActivityTestRule
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+
+@MediumTest
+class FragmentManagerTest {
+ @get:Rule val activityRule = ActivityTestRule<TestActivity>(TestActivity::class.java)
+ private val fragmentManager get() = activityRule.activity.supportFragmentManager
+
+ @UiThreadTest
+ @Test fun transaction() {
+ val fragment = TestFragment()
+ fragmentManager.transaction {
+ add(fragment, null)
+ }
+ assertThat(fragmentManager.fragments).doesNotContain(fragment)
+ fragmentManager.executePendingTransactions()
+ assertThat(fragmentManager.fragments).contains(fragment)
+ }
+
+ @UiThreadTest
+ @Test fun transactionNow() {
+ val fragment = TestFragment()
+ fragmentManager.transaction(now = true) {
+ add(fragment, null)
+ }
+ assertThat(fragmentManager.fragments).contains(fragment)
+ }
+
+ @UiThreadTest
+ @Test fun transactionAllowingStateLoss() {
+ // Use a detached FragmentManager to ensure state loss.
+ val fragmentManager = FragmentManagerImpl()
+
+ fragmentManager.transaction(allowStateLoss = true) {
+ add(TestFragment(), null)
+ }
+ assertThat(fragmentManager.fragments).isEmpty()
+ }
+
+ @UiThreadTest
+ @Test fun transactionNowAllowingStateLoss() {
+ // Use a detached FragmentManager to ensure state loss.
+ val fragmentManager = FragmentManagerImpl()
+
+ fragmentManager.transaction(now = true, allowStateLoss = true) {
+ add(TestFragment(), null)
+ }
+ assertThat(fragmentManager.fragments).isEmpty()
+ }
+}
+
+class TestActivity : FragmentActivity()
+class TestFragment : Fragment()
diff --git a/fragment/ktx/src/main/AndroidManifest.xml b/fragment/ktx/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..cd21eb1
--- /dev/null
+++ b/fragment/ktx/src/main/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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 package="androidx.fragment.ktx"/>
diff --git a/fragment/ktx/src/main/java/androidx/fragment/app/FragmentManager.kt b/fragment/ktx/src/main/java/androidx/fragment/app/FragmentManager.kt
new file mode 100644
index 0000000..d9e8e96
--- /dev/null
+++ b/fragment/ktx/src/main/java/androidx/fragment/app/FragmentManager.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+package androidx.fragment.app
+
+/**
+ * Run [body] in a [FragmentTransaction] which is automatically committed if it completes without
+ * exception.
+ *
+ * One of four commit functions will be used based on the values of `now` and `allowStateLoss`:
+ *
+ * | `now` | `allowStateLoss` | Method |
+ * | ----- | ---------------- | ------------------------------ |
+ * | false | false | `commit()` |
+ * | false | true | `commitAllowingStateLoss()` |
+ * | true | false | `commitNow()` |
+ * | true | true | `commitNowAllowingStateLoss()` |
+ */
+inline fun FragmentManager.transaction(
+ now: Boolean = false,
+ allowStateLoss: Boolean = false,
+ body: FragmentTransaction.() -> Unit
+) {
+ val transaction = beginTransaction()
+ transaction.body()
+ if (now) {
+ if (allowStateLoss) {
+ transaction.commitNowAllowingStateLoss()
+ } else {
+ transaction.commitNow()
+ }
+ } else {
+ if (allowStateLoss) {
+ transaction.commitAllowingStateLoss()
+ } else {
+ transaction.commit()
+ }
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index 2642a19..ea8e44a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -79,6 +79,7 @@
includeProject(":emoji-bundled", "emoji/bundled")
includeProject(":emoji-appcompat", "emoji/appcompat")
includeProject(":fragment", "fragment")
+includeProject(":fragment-ktx", "fragment/ktx")
includeProject(":media", "media")
includeProject(":tvprovider", "tv-provider")
includeProject(":vectordrawable", "graphics/drawable/static")