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/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 1720b55..06f96f3 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1761,11 +1761,11 @@
return mDevice->setCameraServiceWatchdog(enabled);
}
-status_t CameraDeviceClient::setRotateAndCropOverride(uint8_t rotateAndCrop) {
+status_t CameraDeviceClient::setRotateAndCropOverride(uint8_t rotateAndCrop, bool fromHal) {
if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
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 CameraDeviceClient::setAutoframingOverride(uint8_t autoframingValue) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 95563ee..87b0cd3 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -198,7 +198,8 @@
virtual status_t initialize(sp<CameraProviderManager> manager,
const String8& monitorTags) override;
- virtual status_t setRotateAndCropOverride(uint8_t rotateAndCrop) override;
+ virtual status_t setRotateAndCropOverride(uint8_t rotateAndCrop,
+ bool fromHal = false) override;
virtual status_t setAutoframingOverride(uint8_t autoframingValue) override;
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 86a0ebc..acaf4f2 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -80,7 +80,8 @@
return OK;
}
-status_t CameraOfflineSessionClient::setRotateAndCropOverride(uint8_t /*rotateAndCrop*/) {
+status_t CameraOfflineSessionClient::setRotateAndCropOverride(uint8_t /*rotateAndCrop*/,
+ bool /*fromHal*/) {
// Since we're not submitting more capture requests, changes to rotateAndCrop override
// make no difference.
return OK;
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index ad763f9..76dc1cf 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -80,7 +80,7 @@
status_t initialize(sp<CameraProviderManager> /*manager*/,
const String8& /*monitorTags*/) override;
- status_t setRotateAndCropOverride(uint8_t rotateAndCrop) override;
+ status_t setRotateAndCropOverride(uint8_t rotateAndCrop, bool fromHal = false) override;
status_t setAutoframingOverride(uint8_t autoframingValue) override;