From 2bfffde8b33444cd5b4a0d32128cfdebdf0c8003 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Wed, 11 Jul 2018 14:00:29 -0700 Subject: [PATCH] Camera: Use physical camera's capability for physical stream check If stream being created is a physical stream, the size check should be against the physical stream's capability. Test: Camera CTS Bug: 111288509 Change-Id: Iad8814562694f16f16d9656ec482b8b21a859c44 Merged-In: Iad8814562694f16f16d9656ec482b8b21a859c44 --- .../api2/CameraDeviceClient.cpp | 15 +++++--- .../api2/CameraDeviceClient.h | 3 +- .../common/CameraDeviceBase.h | 4 +++ .../device3/Camera3Device.cpp | 35 +++++++++++++++++-- .../libcameraservice/device3/Camera3Device.h | 2 ++ 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 98d053448e..baf051a1c2 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -661,7 +661,8 @@ binder::Status CameraDeviceClient::createStream( } sp surface; - res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer); + res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer, + physicalCameraId); if (!res.isOk()) return res; @@ -889,6 +890,8 @@ binder::Status CameraDeviceClient::updateOutputConfiguration(int streamId, const std::vector >& bufferProducers = outputConfiguration.getGraphicBufferProducers(); + String8 physicalCameraId(outputConfiguration.getPhysicalCameraId()); + auto producerCount = bufferProducers.size(); if (producerCount == 0) { ALOGE("%s: bufferProducers must not be empty", __FUNCTION__); @@ -942,7 +945,7 @@ binder::Status CameraDeviceClient::updateOutputConfiguration(int streamId, OutputStreamInfo outInfo; sp surface; res = createSurfaceFromGbp(outInfo, /*isStreamInfoValid*/ false, surface, - newOutputsMap.valueAt(i)); + newOutputsMap.valueAt(i), physicalCameraId); if (!res.isOk()) return res; @@ -1021,7 +1024,8 @@ bool CameraDeviceClient::isPublicFormat(int32_t format) binder::Status CameraDeviceClient::createSurfaceFromGbp( OutputStreamInfo& streamInfo, bool isStreamInfoValid, - sp& surface, const sp& gbp) { + sp& surface, const sp& gbp, + const String8& physicalId) { // bufferProducer must be non-null if (gbp == nullptr) { @@ -1098,7 +1102,7 @@ binder::Status CameraDeviceClient::createSurfaceFromGbp( // Round dimensions to the nearest dimensions available for this format if (flexibleConsumer && isPublicFormat(format) && !CameraDeviceClient::roundBufferDimensionNearest(width, height, - format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) { + format, dataSpace, mDevice->info(physicalId), /*out*/&width, /*out*/&height)) { String8 msg = String8::format("Camera %s: No supported stream configurations with " "format %#x defined, failed to create output stream", mCameraIdStr.string(), format); @@ -1468,6 +1472,7 @@ binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId const std::vector >& bufferProducers = outputConfiguration.getGraphicBufferProducers(); + String8 physicalId(outputConfiguration.getPhysicalCameraId()); if (bufferProducers.size() == 0) { ALOGE("%s: bufferProducers must not be empty", __FUNCTION__); @@ -1521,7 +1526,7 @@ binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId sp surface; res = createSurfaceFromGbp(mStreamInfoMap[streamId], true /*isStreamInfoValid*/, - surface, bufferProducer); + surface, bufferProducer, physicalId); if (!res.isOk()) return res; diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index 5aaf5aaee3..c30561d488 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -258,7 +258,8 @@ private: // Create a Surface from an IGraphicBufferProducer. Returns error if // IGraphicBufferProducer's property doesn't match with streamInfo binder::Status createSurfaceFromGbp(OutputStreamInfo& streamInfo, bool isStreamInfoValid, - sp& surface, const sp& gbp); + sp& surface, const sp& gbp, + const String8& physicalCameraId); // Utility method to insert the surface into SurfaceMap diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h index 0ba74038c5..98c1b5e971 100644 --- a/services/camera/libcameraservice/common/CameraDeviceBase.h +++ b/services/camera/libcameraservice/common/CameraDeviceBase.h @@ -69,6 +69,10 @@ class CameraDeviceBase : public virtual RefBase { * The device's static characteristics metadata buffer */ virtual const CameraMetadata& info() const = 0; + /** + * The physical camera device's static characteristics metadata buffer + */ + virtual const CameraMetadata& info(const String8& physicalId) const = 0; struct PhysicalCameraSettings { std::string cameraId; diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 543914e5a4..0db5642030 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -121,11 +121,25 @@ status_t Camera3Device::initialize(sp manager, const Stri res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo); if (res != OK) { - SET_ERR_L("Could not retrive camera characteristics: %s (%d)", strerror(-res), res); + SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res); session->close(); return res; } + std::vector physicalCameraIds; + bool isLogical = CameraProviderManager::isLogicalCamera(mDeviceInfo, &physicalCameraIds); + if (isLogical) { + for (auto& physicalId : physicalCameraIds) { + res = manager->getCameraCharacteristics(physicalId, &mPhysicalDeviceInfoMap[physicalId]); + if (res != OK) { + SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)", + physicalId.c_str(), strerror(-res), res); + session->close(); + return res; + } + } + } + std::shared_ptr queue; auto requestQueueRet = session->getCaptureRequestMetadataQueue( [&queue](const auto& descriptor) { @@ -719,7 +733,7 @@ status_t Camera3Device::dump(int fd, const Vector &args) { return OK; } -const CameraMetadata& Camera3Device::info() const { +const CameraMetadata& Camera3Device::info(const String8& physicalId) const { ALOGVV("%s: E", __FUNCTION__); if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED || mStatus == STATUS_ERROR)) { @@ -727,7 +741,22 @@ const CameraMetadata& Camera3Device::info() const { mStatus == STATUS_ERROR ? "when in error state" : "before init"); } - return mDeviceInfo; + if (physicalId.isEmpty()) { + return mDeviceInfo; + } else { + std::string id(physicalId.c_str()); + if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) { + return mPhysicalDeviceInfoMap.at(id); + } else { + ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str()); + return mDeviceInfo; + } + } +} + +const CameraMetadata& Camera3Device::info() const { + String8 emptyId; + return info(emptyId); } status_t Camera3Device::checkStatusOkToCaptureLocked() { diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index d8fe19fa66..ef3cbc4e9c 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -101,6 +101,7 @@ class Camera3Device : status_t disconnect() override; status_t dump(int fd, const Vector &args) override; const CameraMetadata& info() const override; + const CameraMetadata& info(const String8& physicalId) const override; // Capture and setStreamingRequest will configure streams if currently in // idle state @@ -379,6 +380,7 @@ class Camera3Device : sp mInterface; CameraMetadata mDeviceInfo; + std::unordered_map mPhysicalDeviceInfoMap; CameraMetadata mRequestTemplateCache[CAMERA3_TEMPLATE_COUNT];