Camera service: Don't crash if the camera HAL dies mid-use.
Check for transaction errors in all calls to the HIDL interface;
return DEAD_OBJECT consistently if a transaction error occurs.
Test: Camera CTS does not regress; killing camera HAL does not kill camera service.
Bug: 37748853
Change-Id: Iab3ad08376e164db340f8f29c3cfc7fdf261cc00
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index fb303bf..2bdb008 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -211,8 +211,7 @@
if (!requestQueueRet.isOk()) {
ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
requestQueueRet.description().c_str());
- queue = nullptr;
- // Don't use the queue onwards.
+ return DEAD_OBJECT;
}
auto resultQueueRet = session->getCaptureResultMetadataQueue(
[&queue = mResultMetadataQueue](const auto& descriptor) {
@@ -226,8 +225,7 @@
if (!resultQueueRet.isOk()) {
ALOGE("Transaction error when getting result metadata queue from camera session: %s",
resultQueueRet.description().c_str());
- mResultMetadataQueue = nullptr;
- // Don't use the queue onwards.
+ return DEAD_OBJECT;
}
mInterface = std::make_unique<HalInterface>(session, queue);
@@ -3013,7 +3011,7 @@
// Unknown template ID
return BAD_VALUE;
}
- mHidlSession->constructDefaultRequestSettings(id,
+ auto err = mHidlSession->constructDefaultRequestSettings(id,
[&status, &requestTemplate]
(common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
status = s;
@@ -3035,7 +3033,12 @@
}
}
});
- res = CameraProviderManager::mapToStatusT(status);
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+ res = DEAD_OBJECT;
+ } else {
+ res = CameraProviderManager::mapToStatusT(status);
+ }
}
return res;
}
@@ -3109,12 +3112,17 @@
HalStreamConfiguration finalConfiguration;
common::V1_0::Status status;
- mHidlSession->configureStreams(requestedConfiguration,
+ auto err = mHidlSession->configureStreams(requestedConfiguration,
[&status, &finalConfiguration]
(common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) {
finalConfiguration = halConfiguration;
status = s;
});
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+ return DEAD_OBJECT;
+ }
+
if (status != common::V1_0::Status::OK ) {
return CameraProviderManager::mapToStatusT(status);
}
@@ -3300,12 +3308,15 @@
captureRequest->fmqSettingsSize = 0u;
}
}
- mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
+ auto err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
[&status, &numRequestProcessed] (auto s, uint32_t n) {
status = s;
*numRequestProcessed = n;
});
-
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+ return DEAD_OBJECT;
+ }
if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
__FUNCTION__, *numRequestProcessed, batchSize);
@@ -3343,7 +3354,13 @@
if (mHal3Device != nullptr) {
res = mHal3Device->ops->flush(mHal3Device);
} else {
- res = CameraProviderManager::mapToStatusT(mHidlSession->flush());
+ auto err = mHidlSession->flush();
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+ res = DEAD_OBJECT;
+ } else {
+ res = CameraProviderManager::mapToStatusT(err);
+ }
}
return res;
}
@@ -3369,7 +3386,11 @@
if (mHal3Device != nullptr) {
mHal3Device->common.close(&mHal3Device->common);
} else {
- mHidlSession->close();
+ auto err = mHidlSession->close();
+ // Interface will be dead shortly anyway, so don't log errors
+ if (!err.isOk()) {
+ res = DEAD_OBJECT;
+ }
}
return res;
}