Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd55b3de authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Avoid possible deadlock when closing advanced extension session

The advanced extension session request processor must not hold the
'mInterfaceLock' when calling the camera device implementation as it
could result in a deadlock with the camera device close that can
run at the same time and try to acquire the same locks in reverse order.
The request processor will only read from 'mCameraConfigMap' which is
initialized only once during session setup and will not change during
the session lifetime.
A sample stack trace will look like this:
Service thread:
1) android.hardware.camera2.impl.CameraCaptureSessionImpl.stopRepeating
2) android.hardware.camera2.impl.CameraAdvancedExtensionSessionImpl$RequestProcessor.stopRepeating

Client thread:
1) android.hardware.camera2.impl.CameraAdvancedExtensionSessionImpl.release
2) android.hardware.camera2.impl.CameraDeviceImpl.close


Bug: 202074988
Test: Manual using application,
Camera CTS

Change-Id: If992667a7d7e54be5bea1fcc4b1d71ec1b895ca0
parent 77794d27
Loading
Loading
Loading
Loading
+34 −42
Original line number Diff line number Diff line
@@ -873,7 +873,6 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
        @Override
        public int submitBurst(List<Request> requests, IRequestCallback callback) {
            int seqId = -1;
            synchronized (mInterfaceLock) {
            try {
                CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback);
                ArrayList<CaptureRequest> captureRequests = new ArrayList<>();
@@ -888,7 +887,6 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
            } catch (IllegalStateException e) {
                Log.e(TAG, "Capture session closed!");
            }
            }

            return seqId;
        }
@@ -896,7 +894,6 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
        @Override
        public int setRepeating(Request request, IRequestCallback callback) {
            int seqId = -1;
            synchronized (mInterfaceLock) {
            try {
                CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice,
                            request, mCameraConfigMap);
@@ -908,14 +905,12 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
            } catch (IllegalStateException e) {
                Log.e(TAG, "Capture session closed!");
            }
            }

            return seqId;
        }

        @Override
        public void abortCaptures() {
            synchronized (mInterfaceLock) {
            try {
                mCaptureSession.abortCaptures();
            } catch (CameraAccessException e) {
@@ -924,11 +919,9 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
                Log.e(TAG, "Capture session closed!");
            }
        }
        }

        @Override
        public void stopRepeating() {
            synchronized (mInterfaceLock) {
            try {
                mCaptureSession.stopRepeating();
            } catch (CameraAccessException e) {
@@ -938,7 +931,6 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
            }
        }
    }
    }

    private static CaptureRequest initializeCaptureRequest(CameraDevice cameraDevice,
            Request request, HashMap<Surface, CameraOutputConfig> surfaceIdMap)