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

Commit 58aa9c1f authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Avoid possible deadlock during R&C updates

Rotate and crop updates in the legacy shim layer are
synchronized via the 'mBinderSerializationLock'.
The binder thread that does this will also acquire
the camera service lock. However there might another
thread that is in the middle of a client disconnect
and already owns 'mBinderSerializationLock'. The second
thread will also try to acquire the camera service lock
as shown below and this can result in a deadlock.
Avoid this by using a dedicated lock for the rotate and
crop updates instead of 'mBinderSerializationLock'.

Thread 2:
android::CameraService::removeByClient
..
android::Camera2Client::disconnect()

Thread 1:
android::Camera2Client::setRotateAndCropOverride
android::CameraService::notifyDisplayConfigurationChange

Bug: 233752445
Test: Camera CTS
Change-Id: I3d37f0f6034e929a0bf3321ba122fffbd21fa923
parent a2ac684a
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -1689,12 +1689,15 @@ status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
                __FUNCTION__, mCameraId, degrees);
        return BAD_VALUE;
    }
    SharedParameters::Lock l(mParameters);
    {
        Mutex::Autolock icl(mRotateAndCropLock);
        if (mRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_NONE) {
            ALOGI("%s: Rotate and crop set to: %d, skipping display orientation!", __FUNCTION__,
                    mRotateAndCropMode);
            transform = mRotateAndCropPreviewTransform;
        }
    }
    SharedParameters::Lock l(mParameters);
    if (transform != l.mParameters.previewTransform &&
            getPreviewStreamId() != NO_STREAM) {
        mDevice->setStreamTransform(getPreviewStreamId(), transform);
@@ -2317,7 +2320,7 @@ status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop) {
    if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;

    {
        Mutex::Autolock icl(mBinderSerializationLock);
        Mutex::Autolock icl(mRotateAndCropLock);
        if (mRotateAndCropIsSupported) {
            mRotateAndCropMode = rotateAndCrop;
        } else {
+2 −0
Original line number Diff line number Diff line
@@ -240,6 +240,8 @@ private:
    bool isZslEnabledInStillTemplate();
    // The current rotate & crop mode passed by camera service
    uint8_t mRotateAndCropMode;
    // Synchronize access to 'mRotateAndCropMode'
    mutable Mutex mRotateAndCropLock;
    // Contains the preview stream transformation that would normally be applied
    // when the display rotation is 0
    int mRotateAndCropPreviewTransform;