camera: Allow physical capture requests only for requested outputs
An individual physical capture request should only be allowed in
case a respective attached capture output target with the specific
physical device is also present.
Bug: 72524603
Test: Camera CTS
Change-Id: I09502e7a15d3ea0a00e935bf222cc9b61cdaca6f
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 1ebaea9..8e112a1 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -122,8 +122,7 @@
}
binder::Status CameraDeviceClient::insertGbpLocked(const sp<IGraphicBufferProducer>& gbp,
- SurfaceMap* outSurfaceMap,
- Vector<int32_t>* outputStreamIds) {
+ SurfaceMap* outSurfaceMap, Vector<int32_t>* outputStreamIds, int32_t *currentStreamId) {
int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
// Trying to submit request with surface that wasn't created
@@ -146,6 +145,10 @@
__FUNCTION__, mCameraIdStr.string(), streamSurfaceId.streamId(),
streamSurfaceId.surfaceId());
+ if (currentStreamId != nullptr) {
+ *currentStreamId = streamSurfaceId.streamId();
+ }
+
return binder::Status::ok();
}
@@ -218,40 +221,6 @@
"Invalid camera request settings");
}
- CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
- for (const auto& it : request.mPhysicalCameraSettings) {
- String8 physicalId(it.id.c_str());
- if ((physicalId != mDevice->getId()) && !checkPhysicalCameraId(physicalId)) {
- ALOGE("%s: Camera %s: Physical camera id: %s is invalid.", __FUNCTION__,
- mCameraIdStr.string(), physicalId.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Invalid physical camera id");
- }
-
- CameraMetadata metadata(it.settings);
- if (metadata.isEmpty()) {
- ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
- __FUNCTION__, mCameraIdStr.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Request settings are empty");
- }
-
- if (!enforceRequestPermissions(metadata)) {
- // Callee logs
- return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
- "Caller does not have permission to change restricted controls");
- }
-
- physicalSettingsList.push_back({it.id, metadata});
- }
-
- if (streaming && (physicalSettingsList.size() > 1)) {
- ALOGE("%s: Camera %s: Individual physical camera settings are not supported in "
- "streaming requests. Rejecting request.", __FUNCTION__, mCameraIdStr.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Streaming request contains individual physical requests");
- }
-
if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) {
ALOGE("%s: Camera %s: Requests must have at least one surface target. "
"Rejecting request.", __FUNCTION__, mCameraIdStr.string());
@@ -265,15 +234,26 @@
*/
SurfaceMap surfaceMap;
Vector<int32_t> outputStreamIds;
+ std::vector<std::string> requestedPhysicalIds;
if (request.mSurfaceList.size() > 0) {
for (sp<Surface> surface : request.mSurfaceList) {
if (surface == 0) continue;
+ int32_t streamId;
sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
- res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds);
+ res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds, &streamId);
if (!res.isOk()) {
return res;
}
+
+ ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
+ if (index >= 0) {
+ String8 requestedPhysicalId(
+ mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
+ requestedPhysicalIds.push_back(requestedPhysicalId.string());
+ } else {
+ ALOGW("%s: Output stream Id not found among configured outputs!", __FUNCTION__);
+ }
}
} else {
for (size_t i = 0; i < request.mStreamIdxList.size(); i++) {
@@ -298,13 +278,55 @@
"Request targets Surface has invalid surface index");
}
- res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds);
+ res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr);
if (!res.isOk()) {
return res;
}
+
+ String8 requestedPhysicalId(
+ mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
+ requestedPhysicalIds.push_back(requestedPhysicalId.string());
}
}
+ CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
+ for (const auto& it : request.mPhysicalCameraSettings) {
+ String8 physicalId(it.id.c_str());
+ if (physicalId != mDevice->getId()) {
+ auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(),
+ it.id);
+ if (found == requestedPhysicalIds.end()) {
+ ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
+ __FUNCTION__, mCameraIdStr.string(), physicalId.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Invalid physical camera id");
+ }
+ }
+
+ CameraMetadata metadata(it.settings);
+ if (metadata.isEmpty()) {
+ ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
+ __FUNCTION__, mCameraIdStr.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Request settings are empty");
+ }
+
+ physicalSettingsList.push_back({it.id, metadata});
+ }
+
+ if (streaming && (physicalSettingsList.size() > 1)) {
+ ALOGE("%s: Camera %s: Individual physical camera settings are not supported in "
+ "streaming requests. Rejecting request.", __FUNCTION__, mCameraIdStr.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Streaming request contains individual physical requests");
+ }
+
+ if (!enforceRequestPermissions(physicalSettingsList.begin()->metadata)) {
+ // Callee logs
+ return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
+ "Caller does not have permission to change restricted controls");
+ }
+
physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS,
&outputStreamIds[0], outputStreamIds.size());