Status Update
Comments
le...@google.com <le...@google.com> #2
Hi Mohit,
Thank you for reporting this bug. This may be an improper error handling in the library.
In case we are seeing different bug. Could you provide the crash stack and which Pixel device it is? Thanks.
wu...@google.com <wu...@google.com>
sh...@gmail.com <sh...@gmail.com> #3
Hello everyone,
Extremely sorry for the late reply.
The device which I had used for testing was a Pixel 4A. Most devices don't support UHD for front camera, but here the issue/feature request is being reported for the error handling not working as expected.
Here are the crash logs for the same:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.grapheneos.camera, PID: 26084
java.lang.IllegalArgumentException: Unable to find supported quality by QualitySelector
at androidx.camera.lifecycle.LifecycleCameraRepository.bindToLifecycleCamera(LifecycleCameraRepository.java:280)
at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:459)
at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:312)
at app.grapheneos.camera.CamConfig.startCamera(CamConfig.kt:769)
at app.grapheneos.camera.CamConfig.switchCameraMode(CamConfig.kt:589)
at app.grapheneos.camera.ui.activities.MainActivity$onCreate$9.onClick(MainActivity.kt:654)
at android.view.View.performClick(View.java:7441)
at android.view.View.performClickInternal(View.java:7418)
at android.view.View.access$3700(View.java:835)
at android.view.View$PerformClick.run(View.java:28676)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7844)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1019)
Also, just in case you'll weren't able to reproduce this issue - please make sure you'll use the front camera in video mode when the quality is hardcoded to UHD (2160p).
Thanks a lot for your time and considering this issue.
le...@google.com <le...@google.com> #4
Hi
Thank you for the feedback.
From the crash stack, looks like Pixel 4A doesn't support UHD
for front camera. QualitySelector.isQualitySupported(QualitySelector.QUALITY_UHD)
can be used to check if UHD
is supported on this device.
If UHD
is not supported, then this exception is expected. But please note, for quality check result returns from QualitySelector.isQualitySupported(quality)
is true
, it doesn't mean the quality can always be bound while bindToLifecycle
. It still depends on use case combinations.
For example, Preview + VideoCapture(UHD)
could be bound successfully but Preview + ImageCapture + VideoCapture(UHD)
may not.
Currently there is no API to know what use case combinations can work unless bindToLifecycle
is called. This is what
Therefore, using a flexible QualitySelector
settings will be a recommended way. ex QualitySelector.of(QualitySelector.QUALITY_UHD, QualitySelector.FALLBACK_STRATEGY_LOWER)
which will choose a smaller quality if use case combination doesn't support UHD
.
le...@google.com <le...@google.com> #5
Sorry, QualitySelector.isQualitySupported(QualitySelector.QUALITY_UHD)
should be QualitySelector.isQualitySupported(CameraInfo, QualitySelector.QUALITY_UHD)
A CameraInfo can be retrieved from ProcessCameraProvider#bindToLifecycle
sh...@gmail.com <sh...@gmail.com> #6
Hey Leohuang,
Thanks for recommending the isQualitySupported
method, this could help actually resolve the unsupported video quality issue, but actually this issue/feature request was having an error reporting API that can handle unexpected crashes for stuff in general.
There are some cases where the app async throws the error and hence it cannot be handled with a simple try-catch...so those error could either somehow be made forced to been thrown on the caller thread or a simple interface
based callback API could be created for the bindToLifecycle
method as an optional parameter. Not really sure how technically feasible these changes would be, but hope there is an way to handle the crash caused by this method.
Also, I had made a feature request on groups.google.com that could be combined/linked with this (bindToLifecycle
method and return a custom object that contains information on whether that given combination is supported and if not the reason behind it (maybe in the form of a message that could be displayed to the user).
You'll could choose either ways (whichever is the best for the library and convenient for you'll) to resolve this as an issue.
Thanks a lot for the time and support and for considering this issue!
Regards, Mohit
le...@google.com <le...@google.com> #7
Hi Mohit,
Oh, I think I misunderstood the purpose of this bug at first place. Thank you for raising it and I changed this bug to a feature request.
Leo
Description
The bindToLifecycle sometimes throws an error from an async callback/thread which can't be handled from the main/caller thread. It would be good if the library could have some sort of error reporting API (something like an optional parameter for an interface have a abstract method that can handle a error thrown by the method) or maybe just re-throw any async error(s) to the main thread, such that they can be handled without crashing the app.
One such case could be when an unsupported quality selector is used by the `Recorder` instance which is described in the discussion here.
STEPS TO REPRODUCE:
1. Use an unsupported video quality for the Recorder object for a given config. (for e.g. on Pixel devices I have tested on, UHD isn't supported for the front camera; just an example to reproduce the issue...any other unsupported case can too be used)
2. Use the Recorder object in a VideoCapture instance.
3. Pass the VideoCapture instance while using the bindToLifecycle.
4. Wrap the bindToLifecycle with try-catch statement.
OBSERVED RESULTS: If the quality is really unsupported, an error is thrown in the async thread/callback that does not get caught by the try-catch statement in the main/caller thread, which eventually causes the app to crash in an that cannot be handled correctly.
EXPECTED RESULTS: The error should be caught by the try-catch statement present in the fourth step of STEPS TO REPRODUCE section (, any changes made by the bindToLifecycle method should safely revert) and the app shouldn't crash unexpectedly.
REPRODUCIBILITY: 100%
ADDITIONAL INFORMATION:
Please include all other possible cases where an error might be thrown by the bindToLifecycle method (sync/async) too.
CODE FRAGMENTS:
To quickly reproduce this issue you'll could use the app I'm working on hardcode and,
1.
2. Wrap try-catch around the bindToLifeCycle method (
3. Run the app
Alternatively, you'll could just copy relevant pieces of code from the repository (
Thanks a lot for your time and patiently going through this.