Camera2 API and java.lang.IllegalStateException

10,387

Solution 1

java.lang.IllegalStateException: CameraDevice was already closed

This means CameraDevice is closed by someone in certain situation. (ex:Out of memory) To handle this, you can add onClosed() callback in your StateCallback - cameraDeviceStateCallback.

android.hardware.camera2.CameraDevice.StateCallback.onClosed(CameraDevice)

Updated:

It looks like a race condition. In the log, 17555-17555 releaseCameraComponents and 17555-20454 onConfigured callback is called on the different threads. IMO, cameraCaptureSessions should be synchronized in releaseCameraComponents and onConfigured.

private void releaseCameraComponents(){
     synchronized(lock) {
          ....
     }
}
....

@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
    synchronized(lock) {
        ....
    }
}

Solution 2

mCameraOpenCloseLock.release()

this Semaphore should be released after the camera createCaptureSession action to prevent resource conflicts between multiple threads. The source code releases the semaphore too early just after camera opened. Pausing the app will close the camera which causes the error.

To test it, call finish() before mCameraOpenCloseLock.release(), you will not see the error

Share:
10,387
sheddar
Author by

sheddar

Android Dev

Updated on June 18, 2022

Comments

  • sheddar
    sheddar almost 2 years

    I'm creating an app which supports deprecated and new camera API. The first one works like a charm but i'm struggling with Camera2 API. In a phase of testing I've noticed strange behaviour. Testing device is Samsung Galaxy S5 with android 6.0.1 When i press the Power/End key and then go back to application this is what I get(it does not happen everytime):

    03-12 16:14:32.704 24117-24117/pl.tripper.tripper E/MainActivity: onPause
    03-12 16:14:32.774 24117-24128/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] dequeueBuffer: BufferQueue has been abandoned
    03-12 16:14:32.784 24117-24145/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] queueBuffer: BufferQueue has been abandoned
    03-12 16:14:33.044 24117-24128/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned
    03-12 16:14:33.044 24117-24145/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned
    03-12 16:14:33.054 24117-24129/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned
    03-12 16:14:33.054 24117-24128/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned
    03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased
    03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraNewApi: StopCameraThread
    03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved
    03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceDestroyed
    03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/MainActivity: onCreate
    03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/MainActivity: onResume
    03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/CameraNewApi: startCameraThread
    03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewCreated
    03-12 16:14:33.644 24117-24117/pl.tripper.tripper E/CameraNewApi: initCamera
    03-12 16:14:33.674 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceCreated
    03-12 16:14:33.674 24117-24117/pl.tripper.tripper E/CameraNewApi: openCamera
    03-12 16:14:33.914 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged
    03-12 16:14:33.914 24117-25053/pl.tripper.tripper E/CameraNewApi: onOpened
    03-12 16:14:33.914 24117-25053/pl.tripper.tripper E/CameraNewApi: createCameraPreview
    03-12 16:14:33.934 24117-24117/pl.tripper.tripper E/MainActivity: onPause
    03-12 16:14:34.174 24117-24117/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased
    03-12 16:14:34.174 24117-25053/pl.tripper.tripper E/CameraNewApi: onConfigured
    03-12 16:14:34.174 24117-24117/pl.tripper.tripper E/CameraNewApi: StopCameraThread
    03-12 16:14:34.174 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved
    03-12 16:14:34.184 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceDestroyed
    03-12 16:14:34.914 24117-24117/pl.tripper.tripper E/MainActivity: onResume
    03-12 16:14:34.914 24117-24117/pl.tripper.tripper E/CameraNewApi: startCameraThread
    03-12 16:14:34.924 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewCreated
    03-12 16:14:34.924 24117-24117/pl.tripper.tripper E/CameraNewApi: initCamera
    03-12 16:14:34.964 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceCreated
    03-12 16:14:34.964 24117-24117/pl.tripper.tripper E/CameraNewApi: openCamera
    03-12 16:14:35.294 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged
    03-12 16:14:35.294 24117-25121/pl.tripper.tripper E/CameraNewApi: onOpened
    03-12 16:14:35.294 24117-25121/pl.tripper.tripper E/CameraNewApi: createCameraPreview
    03-12 16:14:35.354 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged
    03-12 16:14:35.374 24117-24117/pl.tripper.tripper E/MainActivity: onPause
    03-12 16:14:35.384 24117-25121/pl.tripper.tripper E/CameraNewApi: onConfigured
    03-12 16:14:35.594 24117-24117/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased
    03-12 16:14:35.594 24117-25121/pl.tripper.tripper E/CameraNewApi: Session was closed or camera device has been closed. 
                                                                      java.lang.IllegalStateException: CameraDevice was already closed
                                                                          at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:1997)
                                                                          at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:844)
                                                                          at android.hardware.camera2.impl.CameraDeviceImpl.setRepeatingRequest(CameraDeviceImpl.java:899)
                                                                          at android.hardware.camera2.impl.CameraCaptureSessionImpl.setRepeatingRequest(CameraCaptureSessionImpl.java:236)
                                                                          at pl.tripper.tripper.camera.CameraNewApi$2.onConfigured(CameraNewApi.java:107)
                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                          at android.hardware.camera2.dispatch.InvokeDispatcher.dispatch(InvokeDispatcher.java:39)
                                                                          at android.hardware.camera2.dispatch.HandlerDispatcher$1.run(HandlerDispatcher.java:65)
                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:158)
                                                                          at android.os.HandlerThread.run(HandlerThread.java:61)
    03-12 16:14:35.594 24117-24117/pl.tripper.tripper E/CameraNewApi: StopCameraThread
    03-12 16:14:35.594 24117-25121/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased
    03-12 16:14:35.594 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved
    03-12 16:14:35.604 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceDestroyed
    03-12 16:14:35.644 24117-24117/pl.tripper.tripper E/MainActivity: onCreate
    03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/MainActivity: onResume
    03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/CameraNewApi: startCameraThread
    03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewCreated
    03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/CameraNewApi: initCamera
    03-12 16:14:35.694 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceCreated
    03-12 16:14:35.694 24117-24117/pl.tripper.tripper E/CameraNewApi: openCamera
    03-12 16:14:35.934 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged
    03-12 16:14:35.934 24117-25184/pl.tripper.tripper E/CameraNewApi: onOpened
    03-12 16:14:35.934 24117-25184/pl.tripper.tripper E/CameraNewApi: createCameraPreview
    03-12 16:14:35.944 24117-24117/pl.tripper.tripper E/ViewRootImpl: sendUserActionEvent() mView == null
    03-12 16:14:35.944 24117-24117/pl.tripper.tripper E/ViewRootImpl: sendUserActionEvent() mView == null
    03-12 16:14:35.994 24117-25184/pl.tripper.tripper E/CameraNewApi: onConfigured
    

    Added some error logs when methods are called. I know that cameraDevice is null when session is still up, but i have no idea how to fix it. Camera keeps working after java.lang.IllegalStateException error ocurrs. The second problem is BufferQueueProducer error but i cannot figure out where this is come from.

    03-12 15:47:40.244 30720-30731/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] dequeueBuffer: BufferQueue has been abandoned
    03-12 15:47:40.244 30720-30751/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] queueBuffer: BufferQueue has been abandoned
    03-12 15:47:40.524 30720-30731/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned
    03-12 15:47:40.524 30720-30751/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned
    03-12 15:47:40.524 30720-30732/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned
    03-12 15:47:40.524 30720-30731/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned
    

    Here is my code:

    MainActivity.class

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ButterKnife.bind(this);
    
            Log.e(TAG, "onCreate");
            isImmersiveAvailable();
            cameraApiManager = new CameraApiManager(this, this);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            Log.e(TAG, "onResume");
           cameraApiManager.createCamera();
    
        }
    
        @Override
        protected void onPause() {
            super.onPause();
    
            Log.e(TAG, "onPause");
            cameraApiManager.releaseCameraAndPreview();
        }
    

    CameraApiManager.class

    public class CameraApiManager implements CameraUtility.cameraOpenedListener {
    
        private static final String TAG = "CameraApiManager";
    
        private final WeakReference<MainActivity> mainActivity;
        private Context context;
    
        private CameraSourceApi cameraSourceApi;
        private CameraPreview cameraPreview;
    
        public CameraApiManager(Context context, MainActivity mainActivity){
    
            this.mainActivity= new WeakReference<>(mainActivity);
    
            cameraSourceApi = new CameraSourceApi<>(new CameraNewApi(context));
            this.context = context;
        }
    
        private boolean cameraProgressBarEnable(){
            return context.getResources().getBoolean(R.bool.camera_progress_bar_enable);
        }
    
        private void setCameraProgressBarVisibility(final int visibility ){
            final MainActivity mainActivity = this.mainActivity.get();
            if(mainActivity!= null){
                // UI/Main Thread
                if(Looper.myLooper() == Looper.getMainLooper()){
                    ProgressBar cameraProgressBar = (ProgressBar) mainActivity.findViewById(R.id.camera_progress_bar);
                    cameraProgressBar.setVisibility(visibility);
                } else {
                    mainActivity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            ProgressBar cameraProgressBar = (ProgressBar) mainActivity.findViewById(R.id.camera_progress_bar);
                            cameraProgressBar.setVisibility(visibility);
                        }
                    });
                }
            }
        }
    
        private void showCameraOpenErrorToast(){
            Toast.makeText(context, context.getResources().getString(R.string.camera_open_error_toast), Toast.LENGTH_LONG).show();
        }
    
        private boolean cameraPermissionGranted() {
            return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
        }
    
        public void createCamera(){
            if(cameraPermissionGranted()){
                if(cameraProgressBarEnable()){
                    setCameraProgressBarVisibility(View.VISIBLE);
                }
                cameraSourceApi.createCamera(this);
            }
        }
    
        public void releaseCameraAndPreview(){
            if(cameraPermissionGranted()){
                cameraSourceApi.releaseCamera();
                removeCameraPreview();
            }
        }
    
        @Override
        public void onCameraOpened(boolean succeeded, boolean addPreview, boolean progressBar) {
             if(addPreview) {
                 if (cameraPreview == null) {
                     Log.e(TAG, "cameraPreviewCreated");
                     cameraPreview = new CameraPreview(context, cameraSourceApi);
                     addCameraPreview();
                 }
             }
             if(!progressBar){
                 if(cameraProgressBarEnable()){
                     setCameraProgressBarVisibility(View.GONE);
                 }
             }
             if(!succeeded){
                 showCameraOpenErrorToast();
             }
        }
    
        private void addCameraPreview(){
            MainActivity mainActivity = this.mainActivity.get();
            if(mainActivity != null && cameraPreview != null){
                FrameLayout preview = (FrameLayout) mainActivity.findViewById(R.id.camera_preview);
                preview.addView(cameraPreview);
            }
        }
    
        private void removeCameraPreview(){
            MainActivity mainActivity = this.mainActivity.get();
            if(mainActivity!= null && cameraPreview != null){
                Log.e(TAG, "cameraPreviewRemoved");
                FrameLayout preview = (FrameLayout) mainActivity.findViewById(R.id.camera_preview);
                preview.removeView(cameraPreview);
                cameraPreview = null;
            }
        }
    
         class CameraSourceApi<T extends CameraUtility> implements CameraUtility{
    
            private T camera;
    
            CameraSourceApi(T camera){
                this.camera = camera;
            }
    
            @Override
            public void createCamera(CameraUtility.cameraOpenedListener cameraOpenedListener) {
                camera.createCamera(cameraOpenedListener);
            }
    
            @Override
            public void releaseCamera() {
                camera.releaseCamera();
            }
    
            @Override
            public void onSurfaceCreated(SurfaceHolder surfaceHolder) {
                camera.onSurfaceCreated(surfaceHolder);
            }
    
            @Override
            public void onSurfaceChanged(SurfaceHolder surfaceHolder, int width, int height) {
                camera.onSurfaceChanged(surfaceHolder, width, height);
            }
    
             @Override
             public void onSurfaceDestroyed(SurfaceHolder surfaceHolder) {
                 camera.onSurfaceDestroyed(surfaceHolder);
             }
         }
    }
    

    CameraNewApi.class

    @TargetApi(21)
    class CameraNewApi implements CameraUtility {
    
        private static final String TAG = "CameraNewApi";
    
        private Semaphore cameraOpenCloseLock = new Semaphore(1);
    
        private CameraUtility.cameraOpenedListener cameraOpenedListener;
    
        private Context context;
    
        private Handler backgroundHandler;
        private HandlerThread backgroundThread;
    
        private SurfaceHolder surfaceHolder;
    
        private String backFacingCameraId;
        private CaptureRequest.Builder captureRequestBuilder;
        private CameraDevice cameraDevice;
        private CameraCaptureSession cameraCaptureSessions;
    
        CameraNewApi(Context context){
            this.context = context;
        }
    
    
        private final CameraDevice.StateCallback cameraDeviceStateCallback = new CameraDevice.StateCallback() {
            @Override
            public void onOpened(@NonNull CameraDevice camera) {
                Log.e(TAG, "onOpened");
                cameraOpenCloseLock.release();
                cameraDevice = camera;
                if(surfaceHolder != null){
                    createCameraPreview();
                } else {
                    releaseCameraComponents();
                }
            }
    
            @Override
            public void onDisconnected(@NonNull CameraDevice camera) {
                Log.d(TAG, "deviceCallback.onDisconnected() start");
                Log.e(TAG, "onDisconnected");
                if(cameraOpenedListener != null) {
                    cameraOpenedListener.onCameraOpened(false, false, false);
                }
                cameraOpenCloseLock.release();
                camera.close();
                cameraDevice = null;
            }
    
            @Override
            public void onError(@NonNull CameraDevice camera, int error) {
                Log.e(TAG, "onError");
                Log.d(TAG, "deviceCallback.onError() start");
                if(cameraOpenedListener != null) {
                    cameraOpenedListener.onCameraOpened(false, false, false);
                }
                cameraOpenCloseLock.release();
                camera.close();
                cameraDevice = null;
            }
        };
    
        private final CameraCaptureSession.StateCallback captureSessionStateCallback = new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraCaptureSession session) {
                Log.e(TAG, "onConfigured");
                if(cameraDevice != null){
                    cameraCaptureSessions = session;
                    captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
                    try {
                        if(cameraOpenedListener != null) {
                            cameraOpenedListener.onCameraOpened(true, false, false);
                        }
                        session.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler);
                    } catch (CameraAccessException e) {
                        Log.e(TAG, "Camera has been disconnected", e);
                    } catch (IllegalStateException e){
                        Log.e(TAG, "Session was closed or camera device has been closed. ", e);
                        releaseCameraComponents();
                    }
                }
            }
    
            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                Log.d(TAG, "Capture session configure failed: " + session);
                Log.e(TAG, "onConfigureFailed");
            }
        };
    
        @Override
        public void createCamera(CameraUtility.cameraOpenedListener cameraOpenedListener) {
            this.cameraOpenedListener = cameraOpenedListener;
    
            startBackgroundThread();
            if(cameraOpenedListener != null){
                cameraOpenedListener.onCameraOpened(true, true, true);
            }
            initCamera();
        }
    
        private void releaseCameraComponents(){
            try{
                cameraOpenCloseLock.acquire();
                if(cameraCaptureSessions != null){
                    cameraCaptureSessions.close();
                    cameraCaptureSessions = null;
                }
                if(cameraDevice != null){
                    cameraDevice.close();
                    cameraDevice = null;
                }
                if(surfaceHolder != null){
                    surfaceHolder = null;
                }
                if(cameraOpenedListener != null){
                    cameraOpenedListener = null;
                }
                Log.e(TAG, "cameraComponentsReleased");
            } catch (InterruptedException e) {
                throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
            } finally {
                cameraOpenCloseLock.release();
            }
        }
        @Override
        public void releaseCamera() {
            releaseCameraComponents();
            stopBackgroundThread();
        }
    
        @Override
        public void onSurfaceCreated(SurfaceHolder surfaceHolder) {
            Log.e(TAG, "onSurfaceCreated");
            this.surfaceHolder = surfaceHolder;
            openCamera();
        }
    
        @Override
        public void onSurfaceChanged(SurfaceHolder surfaceHolder, int width, int height) {
            Log.e(TAG, "onSurfaceChanged");
            setSurfaceSize(width, height);
        }
    
        @Override
        public void onSurfaceDestroyed(SurfaceHolder surfaceHolder) {
            Log.e(TAG, "onSurfaceDestroyed");
        }
    
        private void startBackgroundThread() {
            Log.e(TAG, "startCameraThread");
            backgroundThread = new HandlerThread("CameraBackground");
            backgroundThread.start();
            backgroundHandler = new Handler(backgroundThread.getLooper());
        }
    
        private void stopBackgroundThread() {
            Log.e(TAG, "StopCameraThread");
            backgroundThread.quitSafely();
            try {
                backgroundThread.join();
                backgroundThread = null;
                backgroundHandler = null;
            } catch (InterruptedException e) {
                Log.e(TAG, "Error message: ", e);
            }
        }
    
        private void initCamera(){
            Log.e(TAG, "initCamera");
            CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
    
            try{
                for (String cameraId : cameraManager.getCameraIdList()) {
                    CameraCharacteristics characteristics
                            = cameraManager.getCameraCharacteristics(cameraId);
    
                    // Use back camera
                    Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                    if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
                        backFacingCameraId = cameraId;
                        break;
                    }
                }
                if(backFacingCameraId == null){
                    Log.d(TAG, "Could not detect a camera");
                }
            } catch (CameraAccessException e) {
                Log.e(TAG, "Could not get camera list", e);
            }
        }
    
        private void openCamera(){
            Log.e(TAG, "openCamera");
            CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
            try{
                if(backFacingCameraId != null && cameraDevice == null){
                    try{
                        if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
                            throw new RuntimeException("Time out waiting to lock camera opening.");
                        }
                        cameraManager.openCamera(backFacingCameraId, cameraDeviceStateCallback, backgroundHandler);
                    } catch (InterruptedException e) {
                        throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
                    }
                }
            } catch(SecurityException e){
                Log.e(TAG, "Camera permission is not granted", e);
            } catch(CameraAccessException e){
                Log.e(TAG, "Could not open camera", e);
            }
        }
    
        private void createCameraPreview(){
    
            Log.e(TAG, "createCameraPreview");
            Surface surface = surfaceHolder.getSurface();
    
            List<Surface> surfaceList = Collections.singletonList(surface);
    
            try {
                captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                captureRequestBuilder.addTarget(surface);
                cameraDevice.createCaptureSession(surfaceList, captureSessionStateCallback, null);
            } catch (CameraAccessException e){
                Log.e(TAG, "Could not create capture session for camera: " + cameraDevice.getId(), e);
            } catch (IllegalStateException e){
                Log.e(TAG, "Camera has been closed", e);
            }
        }
    

    CameraUtility.interface

    interface CameraUtility {
    
        void createCamera(CameraUtility.cameraOpenedListener cameraOpenedListener);
        void releaseCamera();
        void onSurfaceCreated(SurfaceHolder surfaceHolder);
        void onSurfaceChanged(SurfaceHolder surfaceHolder, int width, int height);
        void onSurfaceDestroyed(SurfaceHolder surfaceHolder);
    
        interface cameraOpenedListener{
            void onCameraOpened(boolean succeeded, boolean addPreview, boolean progressBar);
        }
    }
    

    UPDATE

    That's why it does not happen everytime. Error occurs when right after onPause is called, session starts to repeat requests to maintain preview(onConfigured). Then cameraComponentsReleased triggers where all the cleanup is done, including current CameraDevice object. Still don't have a clue how to manage this situation.

    03-13 12:12:24.375 17555-17555/pl.tripper.tripper E/MainActivity: onPause
    03-13 12:12:24.395 17555-20454/pl.tripper.tripper E/CameraNewApi: onConfigured
    03-13 12:12:24.625 17555-17555/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased
    03-13 12:12:24.625 17555-17555/pl.tripper.tripper E/CameraNewApi: StopCameraThread
    03-13 12:12:24.625 17555-20454/pl.tripper.tripper E/CameraNewApi: Session was closed or camera device has been closed. 
                                                                      java.lang.IllegalStateException: CameraDevice was already closed
                                                                          at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:1997)
                                                                          at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:844)
                                                                          at android.hardware.camera2.impl.CameraDeviceImpl.setRepeatingRequest(CameraDeviceImpl.java:899)
                                                                          at android.hardware.camera2.impl.CameraCaptureSessionImpl.setRepeatingRequest(CameraCaptureSessionImpl.java:236)
                                                                          at pl.tripper.tripper.camera.CameraNewApi$2.onConfigured(CameraNewApi.java:114)
                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                          at android.hardware.camera2.dispatch.InvokeDispatcher.dispatch(InvokeDispatcher.java:39)
                                                                          at android.hardware.camera2.dispatch.HandlerDispatcher$1.run(HandlerDispatcher.java:65)
                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:158)
                                                                          at android.os.HandlerThread.run(HandlerThread.java:61)
    03-13 12:12:24.625 17555-20454/pl.tripper.tripper E/CameraNewApi: Camera onClosed
    03-13 12:12:24.625 17555-17555/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved