Status Update
Comments
kl...@google.com <kl...@google.com>
kl...@google.com <kl...@google.com> #2
This is a particularly hard device to come by - do you happen to have access to the device? If so could you provide us with the output of: adb shell dumpsys media.camera > info.txt
Thanks!
el...@gmail.com <el...@gmail.com> #3
Stacktrace:
Caused by: java.lang.IllegalArgumentException: Can not get supported output size under supported maximum for the format: 34
at androidx.camera.camera2.internal.SupportedSurfaceCombination.getSupportedOutputSizes(SupportedSurfaceCombination.java:355)
at androidx.camera.camera2.internal.SupportedSurfaceCombination.getSuggestedResolutions(SupportedSurfaceCombination.java:197)
at androidx.camera.camera2.internal.Camera2DeviceSurfaceManager.getSuggestedResolutions(Camera2DeviceSurfaceManager.java:198)
at androidx.camera.core.CameraX.calculateSuggestedResolutions(CameraX.java:943)
at androidx.camera.core.CameraX.bindToLifecycle(CameraX.java:293)
at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:227)
Below are some findings based on our debugging
When Dex is connected
previewConfig.getMaxResolution() is returning "731x411" as maxSize.
Inside Preview.Builder.build() -> Default_MAX_resolution is set to "CameraX.getSurfaceManager().getPreviewSize()" which is 731x411
this is being picked as maxSize.
While rendering maxSize is 731x411 and minSize is 640x480 and below are available outputSizes
0 = {Size@11860} "4032x3024"
1 = {Size@11861} "3984x2988"
2 = {Size@11862} "4032x2268"
3 = {Size@11863} "3024x3024"
4 = {Size@11864} "2976x2976"
5 = {Size@11865} "3840x2160"
6 = {Size@11866} "3264x2448"
7 = {Size@11867} "4032x1960"
8 = {Size@11868} "2880x2160"
9 = {Size@11869} "3264x1836"
10 = {Size@11870} "2160x2160"
11 = {Size@11871} "2560x1440"
12 = {Size@11872} "2224x1080"
13 = {Size@11873} "2048x1152"
14 = {Size@11874} "1920x1080"
15 = {Size@11875} "1440x1080"
16 = {Size@11876} "1088x1088"
17 = {Size@11877} "1280x720"
18 = {Size@11878} "1024x768"
19 = {Size@11879} "1056x704"
20 = {Size@11880} "960x720"
21 = {Size@11881} "960x540"
22 = {Size@11882} "720x720"
23 = {Size@11883} "800x450"
24 = {Size@11884} "720x480"
25 = {Size@11885} "640x480"
26 = {Size@11886} "352x288"
27 = {Size@11887} "320x240"
28 = {Size@11888} "256x144"
29 = {Size@11889} "176x144"
and couldn't find any size in this range.
When Dex not connected
minsize = 640x480
maxsize = 1920x1080
0 = {Size@11836} "4032x3024"
1 = {Size@11837} "3984x2988"
2 = {Size@11838} "4032x2268"
3 = {Size@11839} "3024x3024"
4 = {Size@11840} "2976x2976"
5 = {Size@11841} "3840x2160"
6 = {Size@11842} "3264x2448"
7 = {Size@11843} "4032x1960"
8 = {Size@11844} "2880x2160"
9 = {Size@11845} "3264x1836"
10 = {Size@11846} "2160x2160"
11 = {Size@11847} "2560x1440"
12 = {Size@11848} "2224x1080"
13 = {Size@11849} "2048x1152"
14 = {Size@11850} "1920x1080"
15 = {Size@11851} "1440x1080"
16 = {Size@11852} "1088x1088"
17 = {Size@11853} "1280x720"
18 = {Size@11854} "1024x768"
19 = {Size@11855} "1056x704"
20 = {Size@11856} "960x720"
21 = {Size@11857} "960x540"
22 = {Size@11858} "720x720"
23 = {Size@11859} "800x450"
24 = {Size@11860} "720x480"
25 = {Size@11861} "640x480"
26 = {Size@11862} "352x288"
27 = {Size@11863} "320x240"
28 = {Size@11864} "256x144"
29 = {Size@11865} "176x144"
and we have 12 available sizes in this range
Camera2DeviceSurfaceManager.java:: getPreviewSize()
mCameraSupportedSurfaceCombinationMap.get(cameraId).getSurfaceDefinition().getPreviewSize() = "1920x1080"
cameraId=0
el...@gmail.com <el...@gmail.com> #4
The issue root cause is that CameraX will default filter out sizes smaller than 640x480. For Preview, the max size will be limited to under display size. I checked the HW spec info for the issue related devices. Display size of FUJITSU F-04J/F-05J is 360x640. That will result int that no size exists in the conditions that is larger or equal to 640x480 and smaller or equal to 360x640.
A temporary workaround for this situation is to use Preview.Builder#setTargetResolution() to set a size smaller than 640x480 to bypass the problem.
For device FUJITSU arrowsM04, I checked its HW spec info and its display size I found is 1280x720. It seems that the problem should not exist in the device.
Could you confirm that the problem exist on arrowsM04 device? What will be the returned value when using Display#getRealSize to obtain the display size?
kl...@google.com <kl...@google.com>
ap...@google.com <ap...@google.com> #5
> A temporary workaround for this situation is to use Preview.Builder#setTargetResolution() to set a size smaller than 640x480 to bypass the problem.
OK. I will try it.
> Could you confirm that the problem exist on arrowsM04 device?
We receive the crash report (Crashlytics) that this crash has occurred on arrowsM04.
We don't have this device so we can't confirm that the problem really exist on arrowsM04.
> What will be the returned value when using Display#getRealSize to obtain the display size?
We can't investigate it for the same reason.
Thank you.
ap...@google.com <ap...@google.com> #6
This issue happened on devices that the display size is smaller than 640x480. In original auto-resolution mechanism, supported sizes smaller than 640x480 will be default filter out.
The auto-resolution mechanism encodes the guaranteed configurations tables in CameraDevice#createCaptureSession(SessionConfiguration). It defines that the PREVIEW size is the small one of the device display size and 1080p. The PREVIEW size will be the maximal size limitation for Preview use case. The reason it limits the size to display size and 1080p is the stream output in display size or 1080p has been able to provide good enough preview quality. Therefore, auto-resolution mechanism will limit the selected size to be smaller than the small one of the device display size and 1080p.
With above two conditions, in this issue, all sizes smaller than 640x480 have been filter out, therefore, there is no size smaller than the display size 320x240 can be selected to use. And cause the exception.
Solution:
When the display size is smaller than 640x480, auto-resolution mechanism won't filter out those small sizes smaller than 640x480. This makes those small size be left and can be selected for the Preview use case on small display devices.
The solution has been merged and will be included in next CameraX release.
el...@gmail.com <el...@gmail.com> #7
Hello.
This crash still occurs.
- CAMERAX VERSION: 1.0.0-beta4
- ANDROID OS BUILD NUMBER: Android 7.1.1
- DEVICE NAME: FUJITSU F-02H
We receive following crash report from FUJITSU F-02H. So far We have received this crash report only from F-02H.
java.lang.IllegalArgumentException
Can not get supported output size under supported maximum for the format: 34
androidx.camera.camera2.internal.SupportedSurfaceCombination.getSupportedOutputSizes (SupportedSurfaceCombination.java:349)
androidx.camera.camera2.internal.SupportedSurfaceCombination.getSuggestedResolutions (SupportedSurfaceCombination.java:197)
androidx.camera.camera2.internal.Camera2DeviceSurfaceManager.getSuggestedResolutions (Camera2DeviceSurfaceManager.java:198)
androidx.camera.core.CameraX.calculateSuggestedResolutions (CameraX.java:949)
androidx.camera.core.CameraX.bindToLifecycle (CameraX.java:351)
androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle (ProcessCameraProvider.java:230)
(our application's package name).CameraFragment.bindCameraUseCases (CameraFragment.java:174)
kl...@google.com <kl...@google.com> #8
Could you help to provide the following information to clarify the issue?
1. Is the full name of the device Fujitsu Arrows NX F-02H that has a 1440x2560 display?
2. Please help to provide the supported output sizes of ImageFormat.PRIVATE that is obtained by StreamConfigurationMap#getOutputSizes(int).
el...@gmail.com <el...@gmail.com> #9
- Is the full name of the device Fujitsu Arrows NX F-02H that has a 1440x2560 display?
Yes
- Please help to provide the supported output sizes of ImageFormat.PRIVATE that is obtained by StreamConfigurationMap#getOutputSizes(int).
Since we don't have this device, we'll try to collect this information in the next version of our app. The next version will be released later this month.
kl...@google.com <kl...@google.com> #10
Hello.
- Please help to provide the supported output sizes of ImageFormat.PRIVATE that is obtained by StreamConfigurationMap#getOutputSizes(int).
We have collected the output of the device where the crash occurs.
Device1
- Model : arrows Be F-05J
- Android Version : 7.1.1
- Supported output sizes of ImageFormat.PRIVATE
CameraId 0: 480x480
CameraId 1: 2048x1536 ,1920x1080 ,1280x720 ,960x720 ,640x480 ,320x240 ,176x144
Device2
- Model : Fujitsu arrows M04
- Android Version : 7.1.1
- Supported output sizes of ImageFormat.PRIVATE
CameraId 0: 480x480
CameraId 1: 2048x1536 ,1920x1080 ,1280x720 ,960x720 ,640x480 ,320x240 ,176x144
Additional Information
CameraX version : 1.0.0-beta04
We collect the supported output sizes by following code.
val errorString = buildString {
append("The supported output sizes of ImageFormat.PRIVATE: ")
(requireContext().getSystemService(Context.CAMERA_SERVICE) as CameraManager).apply {
cameraIdList.forEachIndexed { index, cameraId ->
val msg = if (VERSION.SDK_INT >= VERSION_CODES.M) {
val configurationMap =
getCameraCharacteristics(cameraId).get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
val sizes = configurationMap?.getOutputSizes(ImageFormat.PRIVATE)
"CameraId $index: ${sizes?.joinToString(" ,")}"
} else {
"CameraId $index: This device version is under M."
}
append(msg)
}
}
}
el...@gmail.com <el...@gmail.com> #11
ma...@gmail.com <ma...@gmail.com> #12
I tried to find the device specs and both 720x1280
size display. For the camera id 0 device, it is a different case that the display size is larger than 640x480
but the device only supports a 480x480
size. The case also caused the same IllegalArgumentException and was also fixed by 1.0.0-beta04
release. Before 480x480
size would be filtered out and then caused the IllegalArgumentException. After it was merged, the 640x480
size threshold was removed and then the 480x480
size would be kept and selected to use.
It looks like 1.0.0-beta04
release had been used to collect the supported sizes information. But the issue should have been fixed by 1.0.0-beta04
release. Did you only check the device model name to collect the supported sizes information or collect the information when the IllegalArgumentException issue happens again?
CameraX's 1.0.0-beta04
version. Maybe you can also consider to upgrade to the latest 1.0.0-rc01
version for your application. Thanks.
el...@gmail.com <el...@gmail.com> #13
Did you only check the device model name to collect the supported sizes information or collect the information when the IllegalArgumentException issue happens again?
We collect informations only from the device on which IllegalArgumentException happened.
Our latest app uses CameraX version 1.0.0-beta10
and this issue still occurres.
However we don't receive crash report from Fujitsu arrows Be F-05J
or Fujitsu arrows M04
so far. (This doesn't mean this issue is fixed on these devices because our app is heavily rely on camera so these device's user wouldn't use our app anymore.)
Instead, we receive crash report from
- Model : Fujitsu F-03K
- Android Version : 7.1.2
- Supported output sizes of ImageFormat.PRIVATE
CameraId 0 : 480x480
CameraId 1 : 2048x1536 ,1920x1080 ,1280x720 ,960x720 ,640x480 ,320x240 ,176x144
yv...@gmail.com <yv...@gmail.com> #14
I missed some settings when I simulated the issue by robolectric test so that I was not able to reproduce it. Now, I can reproduce the issue if the device only supports one 480x480 resolution. I'm working on the solution and target to make it included in next release.
ja...@gmail.com <ja...@gmail.com> #15
Branch: androidx-main
commit 69d15dff7bb857ee33a0f643ff42a0f8bc475ab2
Author: charcoalchen <charcoalchen@google.com>
Date: Fri Jan 08 18:30:03 2021
Fixed IllegalArgumentException issue happened when all preview supported sizes are smaller than 640x480 and display size is larger than 640x480.
Do not filter out sizes smaller than 640x480 when all preview supported sizes are smaller than 640x480 and display size is larger than 640x480.
Relnote:"Fixed IllegalArgumentException issue happened when all preview supported sizes are smaller than 640x480 and display size is larger than 640x480."
Bug: 150506192
Test: SupportedSurfaceCombinationTest
Change-Id: I2a63ce8e2ad42a9cc060c8635ac3603bf440b1ec
M camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/SupportedSurfaceCombination.java
M camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.java
el...@gmail.com <el...@gmail.com> #16
el...@gmail.com <el...@gmail.com> #17
Hi! The new BasicTextField2 in Compose 1.6 alphas seems really promising. For now it seems like the issue of staying on top of the keyboard while typing is fixed; however, on a long text, selecting the text in the area where the keyboard is about to show doesn't scroll the text field to keep the cursor in view.
Once that gets fixed, this issue will be fully resolved and can be effectively closed!
Any updates or ETAs on that?
na...@gmail.com <na...@gmail.com> #18
ro...@gmail.com <ro...@gmail.com> #19
Any new developments on this issue? I'm using BasicTextField to implement a rich edit window (it can attach images, etc.), but it won't keep the text above the keyboard if I add Modifier.verticalScrollable()
:(
which I think is still pretty important
ap...@google.com <ap...@google.com> #20
Branch: androidx-main
commit 6a7220cc4ecc9b6c54e2433a2ade60a360f72690
Author: Zach Klippenstein <klippenstein@google.com>
Date: Wed Jan 17 15:52:42 2024
Ensures BTF2 cursor is scrolled back into view when typing.
If the cursor is scrolled out of view, either from the field's internal
scrollable or something outside it, and the cursor is moved or text is
entered, the cursor should be scrolled back into view as long as the
field is focused. This change makes that happen for BTF2.
This supersedes my original impl, aosp/2178021.
Bug:
Test: TextFieldScrollTest
Relnote: "`BasicTextField2` now keeps the cursor in view while typing
when it has been scrolled out of view or would move out of view due
to input."
Change-Id: Ieb85691dd1a7cf98ab5fc188721d4e4475aec762
M compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldScrollTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/BasicTextField2.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldDecoratorModifier.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextLayoutState.kt
el...@gmail.com <el...@gmail.com> #21
Looks promising! Does that mean this is finally fixed? And when can we expect this to be released so we can test it?
kl...@google.com <kl...@google.com> #22
It will be fixed in BasicTextField2
in the next 1.7.0 alpha release, alpha02. We are not planning to fix it in the current BasicTextField
.
el...@gmail.com <el...@gmail.com> #23
Great news finally!
This is a bit unrelated, but will the name of the BasicTextField2
API be always like this? Or will it eventually replace BasicTextField
?
Because with the 2
it sounds like this "secondary" thing, not like the primary API that everyone should be using.
Other than that, thanks for the amazing work!
el...@gmail.com <el...@gmail.com> #25
Great to hear! Thanks for sharing the talk, and props to you guys for this amazing work!
kl...@google.com <kl...@google.com>
ja...@gmail.com <ja...@gmail.com> #26
el...@gmail.com <el...@gmail.com> #27
ja...@gmail.com <ja...@gmail.com> #28
when it has been scrolled out of view or would move out of view due
to input." this BasicTextField2 not scrolling text above keyboard even keyboad is not opened after clicking text for the second time
el...@gmail.com <el...@gmail.com> #29
Okay I just played with the new BasicTextField... and it seems like this has been only half-fixed.
Inputting anything from the keyboard brings the cursor into focus, which is great. Adding new lines keeps the cursor in view, which is great.
However, tapping the text field (which opens the IME) in an area that will eventually be under the keyboard, does not scroll the cursor to stay in view.
My wacky workaround at the very beginning of this issue does that correctly, and not only for the keyboard, but for any size changes (my app has, in addition to system keyboard, an internal keyboard, and it works the exact same way). If the cursor is in view, I keep it in view no matter what. If the cursor has been scrolled out-of-view, then it's okay to bring it in view only once there's input from the user.
Is this behavior intended? I'm not 100% sure, but I believe that Android's EditText
was keeping the cursor in view once the IME is shown.
I can make a video demonstration with all of these (New BasicTextField, legacy BasicTextField, my workaround, and EditText)
el...@gmail.com <el...@gmail.com> #30
In terms of the keyboard not showing at all the second time you click the text field, I think that's a different bug, and should be reported as its own issue with all the context of where and how that happens to you.
Also note that BasicTextField2
from 1.6.x releases is outdated, so make sure to use the new BasicTextField
in 1.7.0 betas.
da...@gmail.com <da...@gmail.com> #31
To
el...@gmail.com <el...@gmail.com> #32
imePadding()
Modifier on the BasicTextField
, and it doesn't work even with it.
This isn't even IME-specific; any change in the TextField's size should try to keep the cursor in the viewport (if it was already visible before the size change).
imePadding
does exactly just that: add padding, which in turn shrinks the size of the BasicTextField from the bottom. Currently, the new BasicTextField does not react to this at all, thus causing the cursor to stay under the keyboard.
My workaround (from
It is still, however, a workaround (a wacky one to be clear, I'm not even sure I understand my own code, but it works flawlessly in production), and there's nothing than a proper upstream fix for everybody, that would be more performant and just less wacky.
ja...@gmail.com <ja...@gmail.com> #33
el...@gmail.com <el...@gmail.com> #34
BasicTextField2
that's in Compose 1.6.x is outdated.
If you want to try the latest API, update to Compose 1.7.0-beta03 (which is the latest beta as of now), and use BasicTextField
(which now uses the new implementation). This issue is mostly fixed in 1.7.
bringIntoViewRequester
is irrelevant here, because we're talking about the internal scroll of the text field (especially in the case when it takes full screen space). It's not about scrolling some LazyList to keep the field in view, it's about scrolling the field itself to keep the cursor in view.
Again, if you update to 1.7.0 and still face the issue of the keyboard not opening the second time, that's a different issue, please report it separately.
mi...@gmail.com <mi...@gmail.com> #35
el...@gmail.com <el...@gmail.com> #36
Modifier.imePadding()
, but the cursor will still come into view... once you type something.
However, since I still have to use the older BasicTextField
sometimes because I need AnnotatedString
, and because the current fix doesn't satisfy me, I just use a workaround for now, using BringIntoViewRequester
. It's much simpler, cleaner and easier to understand than the abomination I wrote in
To keep the cursor in view on text changes (like the current fix), you need to add a bringIntoViewRequester
to your BasicTextField
, and then get use the TextLayoutResult
from onTextLayout
to get the bounding of the current cursor position, and call request bringIntoView
using that Rect.
To complete the fix, you'll wanna store the TextLayoutResult
in a state, and add a LaunchedEffect
on TextFieldValue.selection
/TextFieldState.selection
changes, which does the exact same thing as before (calling bringIntoView
with cursor rect).
Do the same on size changes (in Modifier.onPlaced
), and you're fully set. The cursor will always be brought to view on size/selection/text changes, while still allowing users to scroll it away when none of these change, works well on desktop, and you can of course choose which triggers to keep.
You can also add some padding to the Rect
you pass to bringIntoView
, for example to keep some space between the line where the cursor is and the IME/bottom/top of screen.
I generally use this alongside a verticalScroll
modifier to apply some internal non-clipping padding, but it should work fine without it, at least on the new BasicTextField
.
Description
Hi there! I've come across a bug in Compose's BasicTextField, which is that the cursor stays behind the keyboard when the clicked line is in the place where the keyboard is about to show. This is because the BasicTextField is occupying the whole screen.
Android's TextView behaves correctly and bumps the selected line to show above the keyboard.
A video is attached with the Jetpack Compose behavior versus how it behaves with a TextView.
This bug can be reworded as "Scroll selected line into view when BasicTextField is resized", as the BasicTextField is essentially resized because of the IME insets.
Here's the code:
Note that
android:windowSoftInputMode
is set toadjustResize
.