Closed jpribble closed 6 years ago
Correct me if wrong. So ways to reproduce are instantly call: start()
& stop()
? Or is it because also there is a onDestroy()
?
Yes, just quickly calling start() then stop() should reproduce it. The crash occurs before onDestroy() so you can ignore that.
Calling fotoapparat.start(), fotoapparat.stop() one after each other cannot reproduce it (since they run in a single thread). Should be some other reason causing this.
Camera#setPreviewTexture(..) doc:
* @throws IOException if the method fails (for example, if the surface
* texture is unavailable or unsuitable).
Maybe surface becomes/was never unavailable onStop() 🤔
I have the same bug here :
E/AndroidRuntime: FATAL EXCEPTION: pool-2-thread-1
Process: .... PID: 16702
java.lang.Error: java.io.IOException: setPreviewTexture failed
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1119)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.IOException: setPreviewTexture failed
at android.hardware.Camera.setPreviewTexture(Native Method)
at io.fotoapparat.hardware.CameraDeviceKt.setDisplaySurface(CameraDevice.kt:402)
at io.fotoapparat.hardware.CameraDeviceKt.access$setDisplaySurface(CameraDevice.kt:1)
at io.fotoapparat.hardware.CameraDevice.setDisplaySurface(CameraDevice.kt:251)
at io.fotoapparat.routine.camera.StartRoutineKt.start(StartRoutine.kt:67)
at io.fotoapparat.routine.camera.StartRoutineKt.bootStart(StartRoutine.kt:22)
at io.fotoapparat.Fotoapparat$start$1.invoke(Fotoapparat.kt:89)
at io.fotoapparat.Fotoapparat$start$1.invoke(Fotoapparat.kt:41)
at io.fotoapparat.hardware.ExecutorKt$sam$Runnable$ffbfbfd0.run(Executor.kt)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
this problem happens when I hit back button in any second activity to return to cameraactivity. Problem happened in Emulator android api level 23
thanks for the reproduction steps @kim24
I cannot reproduce it. Can you please provide some more info, code with replicating example etc...?
Things I tried, both work fine (on pixel 2):
1.
start()
/ stop()
after each other2.
start()
inside onStart()
stop()
called inside onStop()
because of the new activity, camera closes fineonActivityResult
call finish()
, no start
or stop
are ofc called hereI think this issue only occurs on certain devices. I found it after only a few tests on the Samsung Galaxy Grand Prime but it never occurred in 100+ tests on a Samsung Galaxy S8.
I can also reproduce this error with the following code
public class MainActivity extends AppCompatActivity
{
private Fotoapparat fotoapparat;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CameraView cameraView = findViewById(R.id.camera_view);
fotoapparat = Fotoapparat
.with(this)
.into(cameraView)
.lensPosition(back())
.focusMode(firstAvailable(
continuousFocusPicture(),
autoFocus(),
fixed()
))
.flash(off())
.build();
}
@Override
protected void onResume()
{
super.onResume();
fotoapparat.start();
}
@Override
protected void onPause()
{
fotoapparat.stop();
super.onPause();
}
}
When pausing/resuming the app really fast a couple of times on a Galaxy S6 running Android 6.0.1 I get the following crash:
Process: com.navvis.fotoapparattest, PID: 24056
java.lang.Error: java.io.IOException: setPreviewTexture failed
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1119)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.IOException: setPreviewTexture failed
at android.hardware.Camera.setPreviewTexture(Native Method)
at io.fotoapparat.hardware.CameraDeviceKt.setDisplaySurface(CameraDevice.kt:402)
at io.fotoapparat.hardware.CameraDeviceKt.access$setDisplaySurface(CameraDevice.kt:1)
at io.fotoapparat.hardware.CameraDevice.setDisplaySurface(CameraDevice.kt:251)
at io.fotoapparat.routine.camera.StartRoutineKt.start(StartRoutine.kt:67)
at io.fotoapparat.routine.camera.StartRoutineKt.bootStart(StartRoutine.kt:22)
at io.fotoapparat.Fotoapparat$start$1.invoke(Fotoapparat.kt:89)
at io.fotoapparat.Fotoapparat$start$1.invoke(Fotoapparat.kt:41)
at io.fotoapparat.hardware.ExecutorKt$sam$Runnable$ffbfbfd0.run(Executor.kt)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
.
Since IOException
is a checked exception we should always be ready for it. In this particular case, we could just catch and ignore it.
Thanks for the fix! It no longer crashes but I'm seeing that this can leave the device in a state where the camera preview is black and no frames are passed to the frame processor. Do you think this should be propagated to the cameraErrorCallback instead of ignoring it? Here are the logs from a Samsung GS7 with the black camera preview:
01-25 10:55:50.141 22825-22825/ D/TakePictureActivity: onStart() 01-25 10:55:50.161 22825-22825/ D/Fotoapparat: Fotoapparat: start 01-25 10:55:50.161 22825-22825/ D/Fotoapparat: Fotoapparat: getCurrentParameters 01-25 10:55:50.161 22825-26832/ D/Fotoapparat: Device: selectCamera 01-25 10:55:50.161 22825-22825/ D/Fotoapparat: Fotoapparat: getCapabilities 01-25 10:55:50.161 22825-26832/ D/Fotoapparat: CameraDevice: open 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: CameraDevice: getCapabilities$suspendImpl 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: CameraDevice: updateParameters$suspendImpl 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: New camera parameters are: CameraParameters flashMode: io.fotoapparat.parameter.Flash$Off@c59cc10 focusMode: io.fotoapparat.parameter.FocusMode$ContinuousFocusPicture@7430d28 jpegQuality: 90 previewFpsRange: FpsRange(min=15000, max=30000) antiBandingMode: io.fotoapparat.parameter.AntiBandingMode$Auto@a7efa41 sensorSensitivity: null pictureResolution: Resolution(width=1280, height=720) previewResolution: Resolution(width=1280, height=720) 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: CameraDevice: updateFrameProcessor 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: CameraDevice: setDisplayOrientation 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: Image orientation is: io.fotoapparat.hardware.orientation.Orientation$Horizontal$ReverseLandscape@44fd3d4. Display orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. Preview orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: CameraDevice: getPreviewResolution 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: Preview resolution is: Resolution(width=1280, height=720) 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: CameraDevice: setDisplaySurface 01-25 10:55:50.211 22825-26832/ E/BufferQueueProducer: [SurfaceTexture-0-22825-2] connect(P): BufferQueue has been abandoned 01-25 10:55:50.211 22825-26832/ D/Fotoapparat: Can't start preview because of the exception: java.io.IOException: setPreviewTexture failed 01-25 10:55:50.221 22825-26832/ D/Fotoapparat: CameraDevice: getParameters$suspendImpl 01-25 10:55:50.221 22825-26832/ D/Fotoapparat: CameraDevice: getCapabilities$suspendImpl 01-25 10:55:50.221 22825-23138/ D/mali_winsys: new_window_surface returns 0x3000, [2560x1440]-format:1 01-25 10:55:50.231 22825-22825/ D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=2 01-25 10:55:51.751 22825-26832/ D/Fotoapparat: CameraDevice: setDisplayOrientation 01-25 10:55:51.751 22825-26832/ D/Fotoapparat: Image orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. Display orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. Preview orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. 01-25 10:55:51.931 22825-26832/ D/Fotoapparat: CameraDevice: setDisplayOrientation 01-25 10:55:51.931 22825-26832/ D/Fotoapparat: Image orientation is: io.fotoapparat.hardware.orientation.Orientation$Horizontal$ReverseLandscape@44fd3d4. Display orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. Preview orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. 01-25 10:55:55.121 22825-26832/ D/Fotoapparat: CameraDevice: setDisplayOrientation 01-25 10:55:55.121 22825-26832/ D/Fotoapparat: Image orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$ReversePortrait@f00ccf4. Display orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. Preview orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. 01-25 10:55:55.721 22825-26832/ D/Fotoapparat: CameraDevice: setDisplayOrientation 01-25 10:55:55.721 22825-26832/ D/Fotoapparat: Image orientation is: io.fotoapparat.hardware.orientation.Orientation$Horizontal$ReverseLandscape@44fd3d4. Display orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. Preview orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. 01-25 10:55:55.781 22825-26832/ D/Fotoapparat: CameraDevice: setDisplayOrientation 01-25 10:55:55.781 22825-26832/ D/Fotoapparat: Image orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$ReversePortrait@f00ccf4. Display orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. Preview orientation is: io.fotoapparat.hardware.orientation.Orientation$Vertical$Portrait@27ff97d. 01-25 10:55:55.831 22825-26832/ D/Fotoapparat: CameraDevice: setDisplayOrientation … (continues repeating ^)
@jpribble Agree with you. All off exceptions if the lib cannot handle should be propagated to error callback instead of ignore and close the issue.
I also got this after open any camera app then get back to my app.
@dmitry-zaitsev Pls consider to return known exceptions in the error callback, and let us handle by our self, at least we can call recreate screen or show a error message.
What are you trying to achieve or the steps to reproduce?
This crash was observed on a Samsung Galaxy Grand Prime running Android 5.1.1. It occurred when the camera activity was destroyed immediately after being resumed. Here is the scenario:
During step 3 above, CameraActivity's onStart() (calls camera.start()), onStop() (call camera.stop()), and onDestroy() are all called in less than 1 second.
What was the result you received?
Fatal crash due to an uncaught IOException: setPreviewTexture failed in Fotoapparat's startRoutine.
Logs:
What did you expect?
If there is an exception inside Fotoapparat's async routines, it should be caught and, if it's fatal, be sent to the cameraErrorCallback. I could work around this by optimizing the code not to call camera.start() when it's about to be destroyed but I still wanted to report this uncaught exception since it may affect others.
Context: