Fix deadlock when notifyPhysicalCameraDevice is called while waitUntilDrained hasn't completed
The following situation is possible :
thread 1: handling waitUntilIdle from client holds Camera3Device::mInterfaceLock and waits for the
HAL to drain all results.
android::Camera3Device::waitUntilStateThenRelock()
android::Camera3Device::waitUntilDrainedLocked()
android::Camera3Device::waitUntilDrained()
android::CameraDeviceClient::waitUntilIdle()
thread 2: handling processCaptureResult callback from the HAL waits on Camera3Device::mInterfaceLock
NonPI::MutexLockWithTimeout()
android::Camera3Device::setRotateAndCropAutoBehavior()
android::Camera2ClientBase<android::CameraDeviceClientBase>::notifyPhysicalCameraChange()
android::camera3::processCaptureResult()
setRotateAndCropAutoBehaviour() in this case, is an effect of a HAL
callback and shouldn't hold mInterfaceLock. Since mLock already protects
the rotate and crop state we can do without holding mInterfaceLock when
called from processCaptureResult.
Bug: 298705937
Bug: 299348355
Test: GCA (basic validity)
Test: Camera CTS
Test: trigger notifyPhysicalCameraDevice from processCaptureResult while
Camera3Device::waitUntilDrained() is still executing, no deadlock
observed.
Change-Id: If6a89ebc7d38510eece00dfbee62af01b5b5b065
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 5b5892a..9bbb82e 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -2350,7 +2350,7 @@
return mDevice->setCameraServiceWatchdog(enabled);
}
-status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop) {
+status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop, bool fromHal) {
if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
{
@@ -2364,7 +2364,7 @@
}
return mDevice->setRotateAndCropAutoBehavior(
- static_cast<camera_metadata_enum_android_scaler_rotate_and_crop_t>(rotateAndCrop));
+ static_cast<camera_metadata_enum_android_scaler_rotate_and_crop_t>(rotateAndCrop), fromHal);
}
status_t Camera2Client::setAutoframingOverride(uint8_t autoframingValue) {