Merge "Merge remote-tracking branch 'goog/androidx-camerax-dev' into upstream_androidx-camerax-dev" into androidx-master-dev
diff --git a/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt b/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
index f2d5a22..7dcb6e2 100644
--- a/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
+++ b/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
@@ -465,6 +465,44 @@
}
/**
+ * Ensure that FragmentManager
+ */
+ @Test
+ @UiThreadTest
+ fun addRetainedAfterSaveState() {
+ val viewModelStore = ViewModelStore()
+ var fc = activityRule.startupFragmentController(viewModelStore)
+ var fm = fc.supportFragmentManager
+
+ val fragment1 = StrictFragment()
+ fragment1.retainInstance = true
+ fm.beginTransaction()
+ .add(fragment1, "1")
+ .commitNow()
+
+ // Now save the state of the FragmentManager
+ fc.dispatchPause()
+ val savedState = fc.saveAllState()
+
+ val fragment2 = StrictFragment()
+ fragment2.retainInstance = true
+ fm.beginTransaction()
+ .add(fragment2, "2")
+ .commitNowAllowingStateLoss()
+
+ fc.dispatchStop()
+ fc.dispatchDestroy()
+
+ fc = activityRule.startupFragmentController(viewModelStore, savedState)
+ fm = fc.supportFragmentManager
+
+ assertThat(fm.findFragmentByTag("1"))
+ .isSameAs(fragment1)
+ assertThat(fm.findFragmentByTag("2"))
+ .isNull()
+ }
+
+ /**
* When a fragment is saved in non-config, it should be restored to the same index.
*/
@Test
diff --git a/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java b/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java
index 56b4bdf..865ff02 100644
--- a/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java
+++ b/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java
@@ -318,6 +318,12 @@
}
void addRetainedFragment(@NonNull Fragment f) {
+ if (isStateSaved()) {
+ if (FragmentManagerImpl.DEBUG) {
+ Log.v(TAG, "Ignoring addRetainedFragment as the state is already saved");
+ }
+ return;
+ }
boolean added = mNonConfig.addRetainedFragment(f);
if (added && FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Updating retained Fragments: Added " + f);
@@ -325,6 +331,12 @@
}
void removeRetainedFragment(@NonNull Fragment f) {
+ if (isStateSaved()) {
+ if (FragmentManagerImpl.DEBUG) {
+ Log.v(TAG, "Ignoring removeRetainedFragment as the state is already saved");
+ }
+ return;
+ }
boolean removed = mNonConfig.removeRetainedFragment(f);
if (removed && FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Updating retained Fragments: Removed " + f);
diff --git a/leanback/src/main/java/androidx/leanback/widget/FacetProvider.java b/leanback/src/main/java/androidx/leanback/widget/FacetProvider.java
index bbf771bf..c1ca54a 100644
--- a/leanback/src/main/java/androidx/leanback/widget/FacetProvider.java
+++ b/leanback/src/main/java/androidx/leanback/widget/FacetProvider.java
@@ -15,7 +15,44 @@
/**
* This is the query interface to supply optional features(aka facets) on an object without the need
- * of letting the object to subclass or implement java interfaces.
+ * of letting the object to subclass or implement java interfaces. Facets allow leanback to
+ * re-compose optional features from leanback ViewHolder to RecyclerView ViewHolder. A typical
+ * "facet" class is {@link ItemAlignmentFacet} that defines how to align a ViewHolder inside
+ * VerticalGridView or HorizontalGridView.
+ * A FacetProvider could be retrieved from two sources by VerticalGridView/HorizontalGridView in
+ * the following order.
+ * <li>
+ * <p>
+ * ViewHolder based facet:
+ * </p>
+ * <p>
+ * RecyclerView.ViewHolder can implement FacetProvider. If app uses leanback
+ * Presenter.ViewHolder, the facet of Presenter.ViewHolder will be relayed by
+ * ItemBridgeAdapter.ViewHolder which is a wrapper of Presenter.ViewHolder.
+ * ViewHolder based facet is used less frequently than item view type based facet because
+ * in most cases ViewHolders of same type share the same alignment definition.
+ * </p>
+ * <p>
+ * For example, app calls viewHolder.setFacet(ItemAlignmentFacet.class, itemAlignmentFacet) to
+ * set alignment of the ViewHolder instance.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * RecyclerView item view type based facet:
+ * </p>
+ * <p>
+ * RecyclerView.Adapter can implement {@link FacetProviderAdapter} which returns FacetProvider
+ * for each item view type. If app uses leanback ObjectAdapter and Presenter, app wraps
+ * the ObjectAdapter and Presenter using {@link ItemBridgeAdapter}. The implementation of
+ * {@link ItemBridgeAdapter#getFacetProvider(int)} will return the FacetProvider implemented
+ * by {@link Presenter} which is mapped to the item view type.
+ * </p>
+ * <p>
+ * For example, app calls presenter.setFacet(ItemAlignmentFacet.class, itemAlignmentFacet) to
+ * set alignment of all ViewHolders created by this Presenter.
+ * </p>
+ * </li>
*/
public interface FacetProvider {
diff --git a/leanback/src/main/java/androidx/leanback/widget/FacetProviderAdapter.java b/leanback/src/main/java/androidx/leanback/widget/FacetProviderAdapter.java
index 124f6cf..7afbc61 100644
--- a/leanback/src/main/java/androidx/leanback/widget/FacetProviderAdapter.java
+++ b/leanback/src/main/java/androidx/leanback/widget/FacetProviderAdapter.java
@@ -17,9 +17,21 @@
/**
* Optional interface that implemented by {@link RecyclerView.Adapter} to
- * query {@link FacetProvider} for a given type within Adapter. Note that
+ * query {@link FacetProvider} for a given item view type within Adapter. Note that
* {@link RecyclerView.ViewHolder} may also implement {@link FacetProvider} which
- * has a higher priority than the one returned from the FacetProviderAdapter.
+ * has a higher priority than the one returned from{@link #getFacetProvider(int)}.
+ * <p>
+ * A typical use case of {@link FacetProvider} is that VerticalGridView/HorizontalGridView retrieves
+ * {@link ItemAlignmentFacet} for a ViewHolder or a item view type.
+ * <p>
+ * App does not need implement FacetProviderAdapter when using {@link ObjectAdapter},
+ * {@link Presenter} and {@link ItemBridgeAdapter}. {@link ItemBridgeAdapter} implemented
+ * FacetProviderAdapter, it returns the FacetProvider implemented by {@link Presenter} which is
+ * mapped to the item view type.
+ * <p>
+ * For example, app calls presenter.setFacet(ItemAlignmentFacet.class, itemAlignmentFacet) to
+ * set alignment of the ViewHolders created by this Presenter.
+ * </p>
*/
public interface FacetProviderAdapter {
diff --git a/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt b/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
index 05a324f..9468ad8 100644
--- a/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
@@ -101,8 +101,8 @@
}
object LifecyclesTypeNames {
- val LIVE_DATA: ClassName = ClassName.get("androidx.lifecycle", "LiveData")
- val COMPUTABLE_LIVE_DATA: ClassName = ClassName.get("androidx.lifecycle",
+ val LIVE_DATA: ClassName = ClassName.get(LIFECYCLE_PACKAGE, "LiveData")
+ val COMPUTABLE_LIVE_DATA: ClassName = ClassName.get(LIFECYCLE_PACKAGE,
"ComputableLiveData")
}
diff --git a/room/compiler/src/main/kotlin/androidx/room/ext/package_ext.kt b/room/compiler/src/main/kotlin/androidx/room/ext/package_ext.kt
index 97fd37d..446eb004 100644
--- a/room/compiler/src/main/kotlin/androidx/room/ext/package_ext.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/ext/package_ext.kt
@@ -30,6 +30,7 @@
* androidx.sqlite = android.arch.persistence
* androidx.room = android.arch.persistence.room
* androidx.paging = android.arch.paging
+ * androidx.lifecycle = android.arch.lifecycle
* androidx.collection = com.android.support
* ```
*/
@@ -48,6 +49,7 @@
val SQLITE_PACKAGE = getOrDefault("androidx.sqlite")
val ROOM_PACKAGE = getOrDefault("androidx.room")
val PAGING_PACKAGE = getOrDefault("androidx.paging")
+val LIFECYCLE_PACKAGE = getOrDefault("androidx.lifecycle")
val COLLECTION_PACKAGE = getOrDefault("androidx.collection")
private fun getOrDefault(key: String) = PACKAGE_NAME_OVERRIDES.getOrDefault(key, key)