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

Commit acd695c4 authored by Igor Murashkin's avatar Igor Murashkin
Browse files

ProCamera: Fix rare deadlock when client destructs inside the connect call

Bug: 8337737
Change-Id: Ia6fca4365fa20fdbfd6a1ec8d047639a002f2aba
parent f15c0d6d
Loading
Loading
Loading
Loading
+87 −77
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@ sp<ICamera> CameraService::connect(

    sp<Client> client;

    {
        Mutex::Autolock lock(mServiceLock);
        if (!canConnectUnsafe(cameraId, clientPackageName,
                              cameraClient->asBinder(),
@@ -292,7 +293,8 @@ sp<ICamera> CameraService::connect(
        // If there are other non-exclusive users of the camera,
        //  this will tear them down before we can reuse the camera
        if (isValidCameraId(cameraId)) {
        updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE, cameraId);
            updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
                         cameraId);
        }

        switch(deviceVersion) {
@@ -318,14 +320,18 @@ sp<ICamera> CameraService::connect(
        }

        if (!connectFinishUnsafe(client, client->asBinder())) {
        // this is probably not recoverable.. but maybe the client can try again
            // this is probably not recoverable.. maybe the client can try again
            updateStatus(ICameraServiceListener::STATUS_AVAILABLE, cameraId);

            return NULL;
        }

        mClient[cameraId] = client;
    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
        LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
             getpid());
    }
    // important: release the mutex here so the client can call back
    //    into the service from its destructor (can be at the end of the call)

    return client;
}
@@ -357,6 +363,8 @@ sp<IProCameraUser> CameraService::connect(
        return NULL;
    }

    sp<ProClient> client;
    {
        Mutex::Autolock lock(mServiceLock);
        {
            sp<Client> client;
@@ -367,14 +375,13 @@ sp<IProCameraUser> CameraService::connect(
            }
        }

    sp<ProClient> client;

        int facing = -1;
        int deviceVersion = getDeviceVersion(cameraId, &facing);

        switch(deviceVersion) {
          case CAMERA_DEVICE_API_VERSION_1_0:
        ALOGE("Camera id %d uses HALv1, doesn't support ProCamera", cameraId);
            ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
                  cameraId);
            return NULL;
            break;
          case CAMERA_DEVICE_API_VERSION_2_0:
@@ -398,6 +405,9 @@ sp<IProCameraUser> CameraService::connect(

        LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
                getpid());
    }
    // important: release the mutex here so the client can call back
    //    into the service from its destructor (can be at the end of the call)

    return client;
}