Status Update
Comments
em...@getkeepsafe.com <em...@getkeepsafe.com> #2
Hi Doudera,
Thank you for reporting this issue. It is working as intended. This is because the state of CameraControl follows Camera. Once the Camera is closed, all settings will be restored, just like the settings of the focus area and zoom level. The app can restore the torch state by resetting torch at the time of activity onResume.
se...@google.com <se...@google.com> #3
thank you for the fast reply. The behaviour is unexpected to me because if you have the same code as before and just add logging like this:
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture, imageAnalyzer)
.apply {
Log.d(TAG, "Enabling torch after binding") // <-- called everytime it returns to Activity so next statement should be applied
cameraControl.enableTorch(true)
}
The log is always called even when returning to Activity so I suppose it should be applied. Why it is not applied when it is called?
Unfortunately, I cannot make it work even with your hint. I tried to add camera?.cameraControl?.enableTorch(true) to onResume() but without any effect. Can you please describe more how to reset torch state onResume().
As you said the same happens with setZoomRatio() etc.
Thank you, Martin
se...@google.com <se...@google.com> #4
Hi Doudera, Thank you for the detail description. It sounds like some problem in the code. I will investigate it more.
em...@getkeepsafe.com <em...@getkeepsafe.com> #5
From the log, it shows the camera state
-> open -> enable torch -> close -> open
The torch was gone because it restarted the camera.
It needs to investigate more about why it open/close so frequently.
se...@google.com <se...@google.com> #6
In CameraXBasic, it looks like the "cameraProvider.unbindAll()" call in CameraFragment.bindCameraUseCases() method will cause the camera close.
Since camera operation is in another thread, a timing causes the enableTorch() failed because the camera is in closed state at that moment.
It can be detected by checking the returned ListenableFuture result from cameraControl.enableTorch()
020-03-29 12:34:56.139 4946-4946/com.android.example.cameraxbasic E/CameraXBasic: enableTorch
2020-03-29 12:34:56.225 4946-5035/com.android.example.cameraxbasic D/Camera: Transitioning camera internal state: OPENED --> CLOSING
2020-03-29 12:34:56.226 4946-4946/com.android.example.cameraxbasic E/CameraXBasic: enableTorch fail by java.util.concurrent.ExecutionException: androidx.camera.core.CameraControl$OperationCanceledException: Camera is not active.
java.util.concurrent.ExecutionException: androidx.camera.core.CameraControl$OperationCanceledException: Camera is not active.
at androidx.concurrent.futures.AbstractResolvableFuture.getDoneValue(AbstractResolvableFuture.java:518)
at androidx.concurrent.futures.AbstractResolvableFuture.get(AbstractResolvableFuture.java:475)
at androidx.concurrent.futures.CallbackToFutureAdapter$SafeFuture.get(CallbackToFutureAdapter.java:199)
at com.android.example.cameraxbasic.fragments.CameraFragment$bindCameraUseCases$1$2$1.run(CameraFragment.kt:310)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7476)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:968)
Caused by: androidx.camera.core.CameraControl$OperationCanceledException: Camera is not active.
at androidx.camera.camera2.internal.TorchControl.setActive(TorchControl.java:112)
at androidx.camera.camera2.internal.Camera2CameraControl.setActive(Camera2CameraControl.java:135)
at androidx.camera.camera2.internal.Camera2CameraImpl.tryRemoveOnlineUseCases(Camera2CameraImpl.java:727)
at androidx.camera.camera2.internal.Camera2CameraImpl.lambda$removeOnlineUseCase$13$Camera2CameraImpl(Camera2CameraImpl.java:699)
at androidx.camera.camera2.internal.-$$Lambda$Camera2CameraImpl$5wc8VkOCNW87m5eLEZfzgWUl-nY.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:216)
at android.os.HandlerThread.run(HandlerThread.java:67)
It is a defect that CameraX should guarantee the order of the camera request.
Another topic is that why camera will be closed when resuming the CameraFragment.
CameraX is lifecycle aware, if UseCases is bound and pause/resume the page, CameraX will restart those UseCases automatically. So actually it doesn't have to unbind and rebind those UseCases. Unbind and rebind UseCases causes it open camera twice and meet this timing issue. In CameraXBasic, it will unbind and rebind UseCases in onViewCreated().
It is easier to be done in an Activity, just put the bindToLifecycle(...) code in the Activity.onCreate(). For Fragment, maybe Fragment.onAttach() is something like Activity.onCreate, but not pretty sure if it is practical. Or alternatively, it has to unbind all use case in a paired callback such like Fragment.onDestroyView() to prevent Camera from being automatically opened when resuming.
se...@google.com <se...@google.com> #7
Branch: androidx-master-dev
commit 76ad175d0c681ddc6a1b86ff35b180f97049da0d
Author: leo huang <leohuang@google.com>
Date: Sat Jul 11 11:15:41 2020
Fix CameraControl.enableTorch is not working
The issue is caused by a race condition. Camera2CameraControl#setActive(true) is called on the main thread, but #setActive(false) is called on the camera thread. It will cause the control to be in a wrong state and not work properly.
The solution is to post all operations to camera thread to ensure the API calls are executed in the correct order.
But it must update the "LiveData" in advance on the main thread to maintain an existing behavior, i.e. user can immediately obtain the new LiveData value through continuous API calls on the main thread. However, trying to maintain this behavior will conflict with the above solution. There are 2 issues that need to be corrected to ensure the final LiveData value is correct.
(1) LiveData that was updated earlier on the main thread may reset by "setActive(false)" executed on the camera thread. This issue can be resolved by updating LiveData again in the posted camera operation since the tasks on the camera thread always have correct order.
(2) Before updating LiveData on the main thread, it cannot directly check the "active state" of CameraControl because the "active state" is only correct on the camera thread. The solution is to create a synchronized "use count" that can be queried on all threads. In this way, "use count" represents whether CameraControl accepts new requests, "active state" represents whether the requests are sent to Camera.
"Relnote: Fix the CameraControl unable to work by a race condition"
Bug: 152333890
Bug: 160928870
Bug: 160714166
Test: ./gradlew camera:camera-camera2:connectedAndroidTest; ./gradlew camera:camera-camera2:test
Change-Id: I2279f7bda1a9edf90af0c46b2db749d59821e0cc
M camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/CameraControlDeviceTest.java
M camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/Camera2CameraControlTest.java
M camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/ZoomControlDeviceTest.java
M camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControl.java
M camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraImpl.java
M camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/FocusMeteringControl.java
M camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/TorchControl.java
M camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/ZoomControl.java
M camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/TorchControlTest.java
M camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/ZoomControlTest.java
em...@getkeepsafe.com <em...@getkeepsafe.com> #8
I understand.
Is there a way to tell if the snapshot includes the changes from aosp/2227317
in
se...@google.com <se...@google.com> #9
mmm, yeah, seems like there is no information about it there. I'll let you know which build includes it.
em...@getkeepsafe.com <em...@getkeepsafe.com> #10
Thank you for all the help.
I'll test it out as soon at it's available and update here.
ap...@google.com <ap...@google.com> #11
Branch: androidx-main
commit 0bed2f8a6c5c94e5bfcfe7a4e7c13ba1b7ca4166
Author: Sergey Vasilinets <sergeyv@google.com>
Date: Thu Sep 22 16:27:56 2022
Make GreedyScheduler do less "startWork" calls
bug: 248111307
Test: new integration test
Change-Id: I9686ba0810e4444b41ae7d638a6b8db3943da8cb
M work/work-runtime/src/main/java/androidx/work/impl/StartStopToken.kt
M work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/MainActivity.java
M work/work-runtime/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
A work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/StressTest.kt
M work/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
M work/integration-tests/testapp/src/main/res/layout/activity_main.xml
se...@google.com <se...@google.com> #12
Build 9098985
and newer has the change.
em...@getkeepsafe.com <em...@getkeepsafe.com> #13
I've verified the changes in I9686ba0810e4444b41ae7d638a6b8db3943da8cb
improved the performance of the workers being executed. I tested using the
I updated the
Will the changes in I9686ba0810e4444b41ae7d638a6b8db3943da8cb
be included in the next alpha build?
I was hoping to update the WorkManager since it's required for compatibility with targeting Android SDK 31.
Thank you for the support.
se...@google.com <se...@google.com> #14
Yeah, it will be included in the next release, which is 2.8.0-beta01
.
na...@google.com <na...@google.com> #15
This bug was linked in a change in the following release(s):
androidx.work:work-runtime:2.8.0-beta01
em...@getkeepsafe.com <em...@getkeepsafe.com> #16
Thank you!
eo...@gmail.com <eo...@gmail.com> #17
FYI, I get an error in Room DB with this version:
androidx.work:work-runtime:2.8.0-beta01
See error below
# code block
[ERROR] [system.err] /home/eoinzy/workspace/android/myapp/data/build/generated/source/kapt/debug/com/myapp/data/MyAppDatabase_Impl.java:188: error: onCreate(SupportSQLiteDatabase) in <anonymous com.myapp.data.MyAppDatabase_Impl$1> cannot override onCreate(SupportSQLiteDatabase) in Delegate
[ERROR] [system.err] protected void onCreate(SupportSQLiteDatabase _db) {
[ERROR] [system.err] ^
[ERROR] [system.err] attempting to assign weaker access privileges; was public
[ERROR] [system.err] /home/eoinzy/workspace/android/myapp/data/build/generated/source/kapt/debug/com/myapp/data/MyAppDatabase_Impl.java:218: error: onValidateSchema(SupportSQLiteDatabase) in <anonymous com.myapp.data.MyAppDatabase_Impl$1> cannot override onValidateSchema(SupportSQLiteDatabase) in Delegate
[ERROR] [system.err] protected RoomOpenHelper.ValidationResult onValidateSchema(SupportSQLiteDatabase _db) {
[ERROR] [system.err] ^
[ERROR] [system.err] attempting to assign weaker access privileges; was public
[ERROR] [system.err] 2 errors
The issue isn't present in androidx.work:work-runtime:2.8.0-alpha04
da...@google.com <da...@google.com> #18
Re room-compiler
and room-runtime
do you have declared in your project? Can you try using the latest 2.5.0-beta01? I think what is happening is that work-runtime
is using a newer version of room-runtime
than the one declared in your project but room-compiler
is not being updated to match that version as it should be.
eo...@gmail.com <eo...@gmail.com> #19
Yes, that's exactly the issue. Using 2.5.0-beta01 seems to fix it. Apologies for the false alarm.
Description
Component used: WorkManager Version 2.8.0-alpha04
Devices/Android versions reproduced on:
Please see demo project:https://github.com/emarc-m/work-manager-oom
Steps to Reproduce:
QUEUE WORKERS
button to enqueue1_000
one-time unique workersTestWM
to inspect the progress of the workers runningComparing when the workers gets executed with WorkManager 2.8.0-alpha04 vs version 2.3.4, version 2.3.4 would execute the workers immediately compared to 2.8.0-alpha04. It sometimes look like the WorkManager using 2.8.0-alpha04 is not executing any of the queued workers.
I also noticed that there's more logging like this in 2.8.0-alpha04:
For comparison, the sample project can also be built using WorkManager 2.3.4.
Expected behavior: The work manager should execute workers similar to 2.3.4.
Note: This is related to https://issuetracker.google.com/issues/235259756#comment21 which is addressed in 2.8.0-alpha04.