Status Update
Comments
lp...@google.com <lp...@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
di...@google.com <di...@google.com> #3
Do you mind providing code samples and then I can look into it further.
lp...@google.com <lp...@google.com> #4
Sure, something like this: (make sure to run it on a device below R)
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(Button(this).apply {
setText("Hello world")
setOnClickListener {
addOverlayView()
}
})
}
fun addOverlayView() {
val view = MyCustomView(applicationContext).apply {
updateWindowSizeClass()
}
val params = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
).apply { token =
window.decorView.getRootView().windowToken
}
val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
windowManager.addView(view, params)
}
}
class MyCustomView(context: Context) : TextView(context) {
fun updateWindowSizeClass() {
val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
setText("Width = ${metrics.bounds.width()} height = ${metrics.bounds.height()}")
}
}
lp...@google.com <lp...@google.com> #5
This works above R, but below R it crashes with:
java.lang.IllegalArgumentException: Context android.app.Application@20b1a86 is not a UiContext
di...@google.com <di...@google.com> #6
An application Context is not a UI Context so it isn't guaranteed to work. We could add stricter enforcement but that would make it so that the method throws when using an application context.
di...@google.com <di...@google.com> #7
An application Context is not a UI Context because it is not associated with a Display. Therefore creating UI with it is not recommended.
lp...@google.com <lp...@google.com> #8
Sorry if I wasn't clear, but we don't control the callers here, it is common (and supported) for developers to create views with an application context. The question is what should the window size we provide in Compose be in this case. And whatever logic we decide to do there (e.g root view size, default display size) probably makes more sense to implement inside window metrics calculator instead of crashing, so we can be consistent in the fallback behavior across applications and libraries.
Otherwise we would have to basically rely on the implementation detail that the WM library tries to unwrap the context, so we would do it first to see if we can do it safely, and only if so call the WM API
Curious if you have any thoughts as to this, as there is still a 'window' somewhere in the app that is meaningful for UI decisions based on window size
di...@google.com <di...@google.com> #9
There are no correct window metrics that you can get from the Application Context. There is some parts leftover for compatibility reasons but for new code paths one should not use the Application Context to create Views. For example, there is no default display size because Context#getDisplay
will crash. You will not get a correct result going forward when using Context.getSystemService(WindowManager::class.java).getDefaultDisplay()
.
as there is still a 'window' somewhere in the app that is meaningful for UI decisions based on window size
Where is the window
?
Also, in your example above why not use the Activity
as the Context
?
lp...@google.com <lp...@google.com> #10
There are no correct window metrics that you can get from the Application Context
Above R it seems to work fine, since it uses WindowManager#getCurrentWindowMetrics, but I guess there is nothing else we can use below R
You will not get a correct result going forward when using Context.getSystemService(WindowManager::class.java).getDefaultDisplay().
Right, but it's a better approximation than crashing, we need to provide our consumers with some value here. We would only need to do this below R, if the context is not a UI context anyway.
Where is the window?
The same entity that WindowManager#getCurrentWindowMetrics returns above R for an applicationContext, not sure how this is calculated but it seems to map to the current activity inside the application.
Also, in your example above why not use the Activity as the Context?
My example is a bit contrived, in reality this is a common pattern internally. We tried to land a change that calculates default window metrics from the context, and this crashed in multiple tests because the applicationContext was being used, and it's not feasible to update all these existing applicationContext usages that work fine outside of calculating window size.
In any case if there is no desire to avoid this crash at the window library layer, we'll have to land some workaround instead for Compose
di...@google.com <di...@google.com> #11
Above R it seems to work fine, since it uses WindowManager#getCurrentWindowMetrics, but I guess there is nothing else we can use below R
Not crashing isn't the same as working fine. WindowManager#getCurrentWindowMetrics
would be incorrect in a multi display environment.
Right, but it's a better approximation than crashing, we need to provide our consumers with some value here. We would only need to do this below R, if the context is not a UI context anyway.
I don't agree since he default display is the phone's display which can be different from a 42" 4k monitor. And like I said, a non UI context should not be used.
The same entity that WindowManager#getCurrentWindowMetrics returns above R for an applicationContext, not sure how this is calculated but it seems to map to the current activity inside the application.
The problem is when you are in a multi display environment and that is when it would break.
My example is a bit contrived, in reality this is a common pattern internally. We tried to land a change that calculates default window metrics from the context, and this crashed in multiple tests because the applicationContext was being used, and it's not feasible to update all these existing applicationContext usages that work fine outside of calculating window size.
Why are you all using the Application Context instead of a proper UI Context?
lp...@google.com <lp...@google.com> #12
Not crashing isn't the same as working fine. WindowManager#getCurrentWindowMetrics would be incorrect in a multi display environment.
Isn't this what is normally used by WindowMetricsCalculator above R?
di...@google.com <di...@google.com> #13
On a UI Context it is correct, on a non-UI Context it is incorrect.
lp...@google.com <lp...@google.com> #14
Discussed more offline, filed
lp...@google.com <lp...@google.com> #15
Note we'll also need to address the performance regression with the original change:
lp...@google.com <lp...@google.com> #16
Filed a bug for the performance issue, which was rootcaused to insets calculation in WindowMetricsCalculator - since we don't need insets in what we are trying to provide, for now we can just fork the bounds logic, and unify with window library when these blocking issues are resolved
ap...@google.com <ap...@google.com> #17
Project: platform/frameworks/support
Branch: androidx-main
Author: Louis Pullen-Freilich <
Link:
Re-land adding WindowInfo#containerSize
Expand for full commit details
Re-land adding WindowInfo#containerSize
Temporarily using a forked subset of WindowMetricsCalculator to avoid performance issues with inset calculations (that we don't need).
Bug: b/369334429
Fixes: b/360343819
Test: ComposeViewTest
Test: WindowInfoCompositionLocalTest
Relnote: "Adds WindowInfo#containerSize to provide the current window's content container size. This can be retrieved using LocalWindowInfo."
Change-Id: I277673b5576f15f60bc82eeb9d9424c5144a3c25
Files:
- M
compose/ui/ui/api/current.txt
- M
compose/ui/ui/api/restricted_current.txt
- M
compose/ui/ui/build.gradle
- M
compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/ComposeViewTest.kt
- M
compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
- M
compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
- A
compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidWindowInfo.android.kt
- M
compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/WindowInfo.kt
Hash: 7ca3950e4bd0a608b1570f07b75c824912860ed6
Date: Tue Sep 24 14:14:22 2024
ap...@google.com <ap...@google.com> #18
Project: platform/frameworks/support
Branch: androidx-main
Author: Louis Pullen-Freilich <
Link:
Re-re-land adding WindowInfo#containerSize
Expand for full commit details
Re-re-land adding WindowInfo#containerSize
Temporarily using a forked subset of WindowMetricsCalculator to avoid some extra performance issues with inset calculations (that we don't need).
Bug: b/369334429
Fixes: b/360343819
Test: ComposeViewTest
Test: WindowInfoCompositionLocalTest
Relnote: "Adds WindowInfo#containerSize to provide the current window's content container size. This can be retrieved using LocalWindowInfo."
Change-Id: Idc38c705655c9181022161927275318fba86bed8
Files:
- M
compose/ui/ui/api/current.txt
- M
compose/ui/ui/api/restricted_current.txt
- M
compose/ui/ui/build.gradle
- M
compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/ComposeViewTest.kt
- M
compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
- M
compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
- A
compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidWindowInfo.android.kt
- M
compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/WindowInfo.kt
Hash: 2b13d0743f3dc7f38550d0bcfe30dbc5cfd2ecfe
Date: Tue Sep 24 14:14:22 2024
na...@google.com <na...@google.com> #19
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.ui:ui:1.8.0-alpha04
androidx.compose.ui:ui-android:1.8.0-alpha04
androidx.compose.ui:ui-jvmstubs:1.8.0-alpha04
androidx.compose.ui:ui-linuxx64stubs:1.8.0-alpha04
Description
To re-land this we need to figure out what the behavior should be for containerSize in this case.