Status Update
Comments
il...@google.com <il...@google.com> #2
Branch: androidx-master-dev
commit c60f33e229e31ab328ef6b59dab63b264954831c
Author: Alexandre Elias <aelias@google.com>
Date: Fri Jul 10 16:23:09 2020
Semantics no-op cleanups
Partly in response to lmr's broad code review, I did a pass of
superficial API/implementation cleanup. The main changes are:
- I changed each Boolean SemanticsProperty where false is equivalent to
not being present to take "Unit" instead. This is conceptually
clearer: it avoids questions like "can I cancel out a semantics from a
merged child by setting it to false?" Because "property = Unit" looks
weird, I also changed the style of these to "property()".
- I moved the Semantics id generator closer to where it's used, in
SemanticsModifierCore. I made it internal and an AtomicInt.
(Note that integer ids are heavily used in the Android
AccessibilityNodeInfo APIs so I can't simply remove them entirely.)
- I deleted dead code. Some examples include SemanticsHintOverrides,
a public API not connected to anything, and SemanticsPropertyKey
merge() open method which is never called. (In both cases I have
a different plan in mind for accessibility.)
Fixes: 145951226
Fixes: 145955412
Test: existing tests
Relnote: "Single-value semantics properties now use a calling style.
For example, 'semantics { hidden = true }' is now written as:
'semantics { hidden() }'."
Change-Id: Ic1afd12ea22c926babc9662f1804d80b33aa0cfc
M ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/LayoutNodeModifierBenchmark.kt
M ui/ui-core/api/0.1.0-dev15.txt
M ui/ui-core/api/current.txt
M ui/ui-core/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-core/api/public_plus_experimental_current.txt
M ui/ui-core/api/restricted_0.1.0-dev15.txt
M ui/ui-core/api/restricted_current.txt
M ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/graphics/vector/VectorTest.kt
M ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/semantics/SemanticsTests.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidActuals.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidComposeView.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidComposeViewAccessibilityDelegateCompat.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidPopup.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/Expect.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsConfiguration.kt
D ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsHintOverrides.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsModifier.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsNode.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsOwner.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsWrapper.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/semantics/SemanticsProperties.kt
M ui/ui-foundation/api/0.1.0-dev15.txt
M ui/ui-foundation/api/current.txt
M ui/ui-foundation/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-foundation/api/public_plus_experimental_current.txt
M ui/ui-foundation/api/restricted_0.1.0-dev15.txt
M ui/ui-foundation/api/restricted_current.txt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Selectable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Toggleable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/semantics/FoundationSemanticsProperties.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/CardTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxScreenshotTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/RadioButtonScreenshotTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ScaffoldTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/SnackbarTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/SurfaceTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ripple/RippleIndicationTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/textfield/TextFieldScreenshotTest.kt
M ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
M ui/ui-material/src/main/java/androidx/ui/material/TextFieldImpl.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/AssertsTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/CallSemanticsActionTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/ErrorMessagesTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/FindersTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/PrintToStringTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/ScrollToTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/TextActionsTest.kt
M ui/ui-test/src/main/java/androidx/ui/test/Actions.kt
M ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
M ui/ui-text/api/0.1.0-dev15.txt
M ui/ui-text/api/current.txt
M ui/ui-text/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-text/api/public_plus_experimental_current.txt
M ui/ui-text/api/restricted_0.1.0-dev15.txt
M ui/ui-text/api/restricted_current.txt
M ui/ui-text/src/commonMain/kotlin/androidx/ui/text/CoreTextField.kt
M ui/ui-text/src/commonMain/kotlin/androidx/ui/text/TextSemanticsProperties.kt
ja...@google.com <ja...@google.com> #3
Update from an offline discussion:
We do actually allow fragment reordering, but it seems that we are running into the problem because our fragments are not being added to a Fragment container due to an existing legacy navigation system.
Is there something that can be done to ensure that these containerless fragments don't get destroyed when the gesture starts and still properly get cleaned up when the gesture is committed? And in the interim, perhaps a more stern warning for those attempting to support predictive back if they are not part of a fragment container?
il...@google.com <il...@google.com> #4
Ah, that does change things. Yes, our current code for
It will also require fixing the
il...@google.com <il...@google.com>
ap...@google.com <ap...@google.com> #5
Branch: androidx-main
commit 0e93825ab0a4c1df975c47dcbb9df60d94613d6b
Author: Jeremy Woods <jbwoods@google.com>
Date: Thu Jun 13 22:53:18 2024
No longer drop fragments not in container for predictive back
When using predictive back, if a fragment is not in a container then we
can't run any animations on it. The current behavior is to immediately
move that fragment to the final state, but that means that if you cancel
the transition the fragment will now be destroyed.
Instead of dropping it immediately, we should move any fragments that do
not have a container to their final state after the predicitive back
gesture has completed.
RelNote: "Fixed an issue where fragment without a container were
immediately DESTROYED when starting a predictive back gesture."
Test: modified the original test
Bug: 345244539
Change-Id: If6b83f7dbb655e0bebc99c3c769625626a7c4e8d
M fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java
jb...@google.com <jb...@google.com> #6
This has been fixed internally and will be available in the Fragment version 1.8.1
release.
pr...@google.com <pr...@google.com> #7
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.fragment:fragment:1.8.1
Description
Component used: Fragment
The new "predictive back" feature has surfaced some interesting issues when dealing with the Fragment backstack. In general, there seems to be a mismatch in expectations as to whether a "destroyed" instance of a Fragment will be re-created or not.
On one hand, when the FragmentManager's predictive back detects that the user canceled the gesture, it will take the Fragment instance that was previously destroyed and add it back to the top of the stack, driving the create/start/resume lifecycle again. It does this by by re-committing the FragmentTransaction that added it .
On the other hand, utilities like the lifecycle-bound coroutine scope do not handle the state re-entering "creation" after its destruction. The scope is created once here and when the destroyed state is reached the supervisor job is canceled and the lifecycle observer is removed.
These two behaviors are incompatible, if I'm following this code correctly.
Technically, the destruction of a Fragment does not prohibit its reuse, and so the FragmentManager behavior is not wrong from what I can tell. However, in practice I can imagine that reusing Fragments this way will inherently lead to bugs that will be difficult to diagnose whenever a lifecycle-dependent behavior assumes that destruction is final. In essence, this introduces a lifecycle transition (destroyed -> created) that many fragments may not be designed to support.
If instead the FragmentManager recreates the Fragment from scratch, that would avoid these issues but there will likely be negative performance implications.
It's worth noting that a user may in fact trigger a predictive back gesture without realizing it. In some cases, a tap near the side edge of the device will trigger the beginning and cancellation of the gesture, without any visual cue that this happened. That will exacerbate the difficulty of reproducing and diagnosing these types of lifecycle state bugs.