Loading camera/device/3.4/types.hal +12 −4 Original line number Original line Diff line number Diff line Loading @@ -185,7 +185,9 @@ struct HalStreamConfiguration { * PhysicalCameraSetting: * PhysicalCameraSetting: * * * Individual camera settings for logical camera backed by multiple physical devices. * Individual camera settings for logical camera backed by multiple physical devices. * Clients are allowed to pass separate settings for each physical device. * Clients are allowed to pass separate settings for each physical device that has * corresponding configured HalStream and the respective stream id is present in the * output buffers of the capture request. */ */ struct PhysicalCameraSetting { struct PhysicalCameraSetting { /** /** Loading @@ -197,8 +199,9 @@ struct PhysicalCameraSetting { /** /** * Contains the physical device camera id. Any settings passed by client here * Contains the physical device camera id. Any settings passed by client here * should be applied for this physical device. In case the physical id is invalid * should be applied for this physical device. In case the physical id is invalid or * Hal should fail the process request and return Status::ILLEGAL_ARGUMENT. * it is not present among the last configured streams, Hal should fail the process * request and return Status::ILLEGAL_ARGUMENT. */ */ string physicalCameraId; string physicalCameraId; Loading Loading @@ -238,7 +241,12 @@ struct CaptureRequest { /** /** * A vector containing individual camera settings for logical camera backed by multiple physical * A vector containing individual camera settings for logical camera backed by multiple physical * devices. In case the vector is empty, Hal should use the settings field in 'v3_2'. * devices. In case the vector is empty, Hal should use the settings field in 'v3_2'. The * individual settings should only be honored for physical devices that have respective Hal * stream. Physical devices that have a corresponding Hal stream but don't have attached * settings here should use the settings field in 'v3_2'. * If any of the physical settings in the array are applied on one or more devices, then the * visual effect on any Hal streams attached to the logical camera is undefined. */ */ vec<PhysicalCameraSetting> physicalCameraSettings; vec<PhysicalCameraSetting> physicalCameraSettings; }; }; Loading camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +186 −45 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <mutex> #include <mutex> #include <regex> #include <regex> #include <unordered_map> #include <unordered_map> #include <unordered_set> #include <condition_variable> #include <condition_variable> #include <inttypes.h> #include <inttypes.h> Loading @@ -28,6 +29,7 @@ #include <android/hardware/camera/device/3.2/ICameraDevice.h> #include <android/hardware/camera/device/3.2/ICameraDevice.h> #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h> #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <binder/MemoryHeapBase.h> #include <binder/MemoryHeapBase.h> Loading Loading @@ -531,8 +533,10 @@ public: } } }; }; struct DeviceCb : public ICameraDeviceCallback { struct DeviceCb : public V3_4::ICameraDeviceCallback { DeviceCb(CameraHidlTest *parent) : mParent(parent) {} DeviceCb(CameraHidlTest *parent) : mParent(parent) {} Return<void> processCaptureResult_3_4( const hidl_vec<V3_4::CaptureResult>& results) override; Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override; Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override; Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override; Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override; Loading Loading @@ -627,6 +631,15 @@ public: ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4); ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, const std::unordered_set<std::string>& physicalIds, sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, V3_2::Stream* previewStream /*out*/, device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, uint32_t *partialResultCount /*out*/); void configurePreviewStream(const std::string &name, int32_t deviceVersion, void configurePreviewStream(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, const AvailableStream *previewThreshold, Loading @@ -641,7 +654,7 @@ public: static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta); static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta); static Status isLogicalMultiCamera(camera_metadata_t *staticMeta); static Status isLogicalMultiCamera(camera_metadata_t *staticMeta); static Status getPhysicalCameraIds(camera_metadata_t *staticMeta, static Status getPhysicalCameraIds(camera_metadata_t *staticMeta, std::vector<std::string> *physicalIds/*out*/); std::unordered_set<std::string> *physicalIds/*out*/); static Status pickConstrainedModeSize(camera_metadata_t *staticMeta, static Status pickConstrainedModeSize(camera_metadata_t *staticMeta, AvailableStream &hfrStream); AvailableStream &hfrStream); static Status isZSLModeAvailable(camera_metadata_t *staticMeta); static Status isZSLModeAvailable(camera_metadata_t *staticMeta); Loading Loading @@ -844,6 +857,27 @@ Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch( return Void(); return Void(); } } Return<void> CameraHidlTest::DeviceCb::processCaptureResult_3_4( const hidl_vec<V3_4::CaptureResult>& results) { if (nullptr == mParent) { return Void(); } bool notify = false; std::unique_lock<std::mutex> l(mParent->mLock); for (size_t i = 0 ; i < results.size(); i++) { notify = processCaptureResultLocked(results[i].v3_2); } l.unlock(); if (notify) { mParent->mResultCondition.notify_one(); } return Void(); } Return<void> CameraHidlTest::DeviceCb::processCaptureResult( Return<void> CameraHidlTest::DeviceCb::processCaptureResult( const hidl_vec<CaptureResult>& results) { const hidl_vec<CaptureResult>& results) { if (nullptr == mParent) { if (nullptr == mParent) { Loading Loading @@ -3304,7 +3338,7 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) { TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; static_cast<int32_t>(PixelFormat::YCBCR_420_888)}; uint64_t bufferId = 1; uint64_t bufferId = 1; uint32_t frameNumber = 1; uint32_t frameNumber = 1; ::android::hardware::hidl_vec<uint8_t> settings; ::android::hardware::hidl_vec<uint8_t> settings; Loading @@ -3327,7 +3361,7 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); continue; continue; } } std::vector<std::string> physicalIds; std::unordered_set<std::string> physicalIds; rc = getPhysicalCameraIds(staticMeta, &physicalIds); rc = getPhysicalCameraIds(staticMeta, &physicalIds); ASSERT_TRUE(Status::OK == rc); ASSERT_TRUE(Status::OK == rc); ASSERT_TRUE(physicalIds.size() > 1); ASSERT_TRUE(physicalIds.size() > 1); Loading @@ -3336,22 +3370,23 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ret = session->close(); ret = session->close(); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); V3_2::Stream previewStream; // Leave only 2 physical devices in the id set. HalStreamConfiguration halStreamConfig; auto it = physicalIds.begin(); it++; it++; physicalIds.erase(it, physicalIds.end()); V3_4::HalStreamConfiguration halStreamConfig; bool supportsPartialResults = false; bool supportsPartialResults = false; uint32_t partialResultCount = 0; uint32_t partialResultCount = 0; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, V3_2::Stream previewStream; &previewStream /*out*/, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, &partialResultCount /*out*/); sp<device::V3_3::ICameraDeviceSession> session3_3; sp<device::V3_4::ICameraDeviceSession> session3_4; sp<device::V3_4::ICameraDeviceSession> session3_4; castSession(session, deviceVersion, &session3_3, &session3_4); configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds, &session3_4, &previewStream, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, &partialResultCount /*out*/); ASSERT_NE(session3_4, nullptr); ASSERT_NE(session3_4, nullptr); std::shared_ptr<ResultMetadataQueue> resultQueue; std::shared_ptr<ResultMetadataQueue> resultQueue; auto resultQueueRet = auto resultQueueRet = session->getCaptureResultMetadataQueue( session3_4->getCaptureResultMetadataQueue( [&resultQueue](const auto& descriptor) { [&resultQueue](const auto& descriptor) { resultQueue = std::make_shared<ResultMetadataQueue>( resultQueue = std::make_shared<ResultMetadataQueue>( descriptor); descriptor); Loading @@ -3365,38 +3400,40 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { }); }); ASSERT_TRUE(resultQueueRet.isOk()); ASSERT_TRUE(resultQueueRet.isOk()); InFlightRequest inflightReq = {1, false, supportsPartialResults, InFlightRequest inflightReq = {static_cast<ssize_t> (physicalIds.size()), false, partialResultCount, resultQueue}; supportsPartialResults, partialResultCount, resultQueue}; RequestTemplate reqTemplate = RequestTemplate::PREVIEW; RequestTemplate reqTemplate = RequestTemplate::PREVIEW; ret = session->constructDefaultRequestSettings(reqTemplate, ret = session3_4->constructDefaultRequestSettings(reqTemplate, [&](auto status, const auto& req) { [&](auto status, const auto& req) { ASSERT_EQ(Status::OK, status); ASSERT_EQ(Status::OK, status); settings = req; settings = req; }); }); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(settings.size() > 0); sp<GraphicBuffer> gb = new GraphicBuffer( std::vector<sp<GraphicBuffer>> graphicBuffers; previewStream.width, previewStream.height, graphicBuffers.reserve(physicalIds.size()); static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, halStreamConfig.streams[0].consumerUsage)); ASSERT_NE(nullptr, gb.get()); ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; outputBuffers.resize(1); outputBuffers.resize(physicalIds.size()); outputBuffers[0] = {halStreamConfig.streams[0].id, bufferId, hidl_handle(gb->getNativeBuffer()->handle), BufferStatus::OK, nullptr, nullptr}; StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; hidl_vec<V3_4::PhysicalCameraSetting> camSettings; hidl_vec<V3_4::PhysicalCameraSetting> camSettings; camSettings.resize(2); camSettings.resize(physicalIds.size()); camSettings[0] = {0, hidl_string(physicalIds[0]), settings}; size_t k = 0; camSettings[1] = {0, hidl_string(physicalIds[1]), settings}; for (const auto physicalIdIt : physicalIds) { sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width, previewStream.height, static_cast<int32_t>(halStreamConfig.streams[k].v3_3.v3_2.overrideFormat), 1, android_convertGralloc1To0Usage( halStreamConfig.streams[k].v3_3.v3_2.producerUsage, halStreamConfig.streams[k].v3_3.v3_2.consumerUsage)); ASSERT_NE(nullptr, gb.get()); outputBuffers[k] = {halStreamConfig.streams[k].v3_3.v3_2.id, bufferId, hidl_handle(gb->getNativeBuffer()->handle), BufferStatus::OK, nullptr, nullptr}; graphicBuffers.push_back(gb); camSettings[k] = {0, hidl_string(physicalIdIt), settings}; k++; } StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings, V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}, camSettings}; emptyInputBuffer, outputBuffers}, camSettings}; Loading Loading @@ -3431,12 +3468,10 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_FALSE(inflightReq.errorCodeValid); ASSERT_FALSE(inflightReq.errorCodeValid); ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); ASSERT_EQ(halStreamConfig.streams[0].id, inflightReq.resultOutputBuffers[0].streamId); } } // Empty physical camera settings should fail process requests // Empty physical camera settings should fail process requests camSettings[1] = {0, hidl_string(physicalIds[1]), emptySettings}; camSettings[1].settings = emptySettings; frameNumber++; frameNumber++; request = {{frameNumber, 0 /* fmqSettingsSize */, settings, request = {{frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}, camSettings}; emptyInputBuffer, outputBuffers}, camSettings}; Loading @@ -3449,7 +3484,8 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); // Invalid physical camera id should fail process requests // Invalid physical camera id should fail process requests camSettings[1] = {0, invalidPhysicalId, settings}; camSettings[1].physicalCameraId = invalidPhysicalId; camSettings[1].settings = settings; request = {{frameNumber, 0 /* fmqSettingsSize */, settings, request = {{frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}, camSettings}; emptyInputBuffer, outputBuffers}, camSettings}; returnStatus = session3_4->processCaptureRequest_3_4( returnStatus = session3_4->processCaptureRequest_3_4( Loading @@ -3460,7 +3496,7 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_TRUE(returnStatus.isOk()); ASSERT_TRUE(returnStatus.isOk()); ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); ret = session->close(); ret = session3_4->close(); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); } } } } Loading Loading @@ -3838,7 +3874,7 @@ Status CameraHidlTest::isLogicalMultiCamera(camera_metadata_t *staticMeta) { // Generate a list of physical camera ids backing a logical multi-camera. // Generate a list of physical camera ids backing a logical multi-camera. Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta, Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta, std::vector<std::string> *physicalIds) { std::unordered_set<std::string> *physicalIds) { if ((nullptr == staticMeta) || (nullptr == physicalIds)) { if ((nullptr == staticMeta) || (nullptr == physicalIds)) { return Status::ILLEGAL_ARGUMENT; return Status::ILLEGAL_ARGUMENT; } } Loading @@ -3856,7 +3892,7 @@ Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta, if (ids[i] == '\0') { if (ids[i] == '\0') { if (start != i) { if (start != i) { std::string currentId(reinterpret_cast<const char *> (ids + start)); std::string currentId(reinterpret_cast<const char *> (ids + start)); physicalIds->push_back(currentId); physicalIds->emplace(currentId); } } start = i + 1; start = i + 1; } } Loading Loading @@ -4028,6 +4064,111 @@ void CameraHidlTest::createStreamConfiguration( *config3_2 = {streams3_2, configMode}; *config3_2 = {streams3_2, configMode}; } } // Configure multiple preview streams using different physical ids. void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, const std::unordered_set<std::string>& physicalIds, sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, V3_2::Stream *previewStream /*out*/, device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, uint32_t *partialResultCount /*out*/) { ASSERT_NE(nullptr, session3_4); ASSERT_NE(nullptr, halStreamConfig); ASSERT_NE(nullptr, previewStream); ASSERT_NE(nullptr, supportsPartialResults); ASSERT_NE(nullptr, partialResultCount); ASSERT_FALSE(physicalIds.empty()); std::vector<AvailableStream> outputPreviewStreams; ::android::sp<ICameraDevice> device3_x; ALOGI("configureStreams: Testing camera device %s", name.c_str()); Return<void> ret; ret = provider->getCameraDeviceInterface_V3_x( name, [&](auto status, const auto& device) { ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); ASSERT_EQ(Status::OK, status); ASSERT_NE(device, nullptr); device3_x = device; }); ASSERT_TRUE(ret.isOk()); sp<DeviceCb> cb = new DeviceCb(this); sp<ICameraDeviceSession> session; ret = device3_x->open( cb, [&session](auto status, const auto& newSession) { ALOGI("device::open returns status:%d", (int)status); ASSERT_EQ(Status::OK, status); ASSERT_NE(newSession, nullptr); session = newSession; }); ASSERT_TRUE(ret.isOk()); sp<device::V3_3::ICameraDeviceSession> session3_3; castSession(session, deviceVersion, &session3_3, session3_4); ASSERT_NE(nullptr, session3_4); camera_metadata_t *staticMeta; ret = device3_x->getCameraCharacteristics([&] (Status s, CameraMetadata metadata) { ASSERT_EQ(Status::OK, s); staticMeta = clone_camera_metadata( reinterpret_cast<const camera_metadata_t*>(metadata.data())); ASSERT_NE(nullptr, staticMeta); }); ASSERT_TRUE(ret.isOk()); camera_metadata_ro_entry entry; auto status = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); if ((0 == status) && (entry.count > 0)) { *partialResultCount = entry.data.i32[0]; *supportsPartialResults = (*partialResultCount > 1); } outputPreviewStreams.clear(); auto rc = getAvailableOutputStreams(staticMeta, outputPreviewStreams, previewThreshold); free_camera_metadata(staticMeta); ASSERT_EQ(Status::OK, rc); ASSERT_FALSE(outputPreviewStreams.empty()); ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(physicalIds.size()); int32_t streamId = 0; for (auto const& physicalId : physicalIds) { V3_4::Stream stream3_4 = {{streamId, StreamType::OUTPUT, static_cast<uint32_t> (outputPreviewStreams[0].width), static_cast<uint32_t> (outputPreviewStreams[0].height), static_cast<PixelFormat> (outputPreviewStreams[0].format), GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0}, physicalId.c_str(), /*bufferSize*/ 0}; streams3_4[streamId++] = stream3_4; } ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}}; RequestTemplate reqTemplate = RequestTemplate::PREVIEW; ret = (*session3_4)->constructDefaultRequestSettings(reqTemplate, [&config3_4](auto status, const auto& req) { ASSERT_EQ(Status::OK, status); config3_4.sessionParams = req; }); ASSERT_TRUE(ret.isOk()); ret = (*session3_4)->configureStreams_3_4(config3_4, [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); ASSERT_EQ(physicalIds.size(), halConfig.streams.size()); *halStreamConfig = halConfig; }); *previewStream = streams3_4[0].v3_2; ASSERT_TRUE(ret.isOk()); } // Open a device session and configure a preview stream. // Open a device session and configure a preview stream. void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion, void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, sp<ICameraProvider> provider, Loading Loading
camera/device/3.4/types.hal +12 −4 Original line number Original line Diff line number Diff line Loading @@ -185,7 +185,9 @@ struct HalStreamConfiguration { * PhysicalCameraSetting: * PhysicalCameraSetting: * * * Individual camera settings for logical camera backed by multiple physical devices. * Individual camera settings for logical camera backed by multiple physical devices. * Clients are allowed to pass separate settings for each physical device. * Clients are allowed to pass separate settings for each physical device that has * corresponding configured HalStream and the respective stream id is present in the * output buffers of the capture request. */ */ struct PhysicalCameraSetting { struct PhysicalCameraSetting { /** /** Loading @@ -197,8 +199,9 @@ struct PhysicalCameraSetting { /** /** * Contains the physical device camera id. Any settings passed by client here * Contains the physical device camera id. Any settings passed by client here * should be applied for this physical device. In case the physical id is invalid * should be applied for this physical device. In case the physical id is invalid or * Hal should fail the process request and return Status::ILLEGAL_ARGUMENT. * it is not present among the last configured streams, Hal should fail the process * request and return Status::ILLEGAL_ARGUMENT. */ */ string physicalCameraId; string physicalCameraId; Loading Loading @@ -238,7 +241,12 @@ struct CaptureRequest { /** /** * A vector containing individual camera settings for logical camera backed by multiple physical * A vector containing individual camera settings for logical camera backed by multiple physical * devices. In case the vector is empty, Hal should use the settings field in 'v3_2'. * devices. In case the vector is empty, Hal should use the settings field in 'v3_2'. The * individual settings should only be honored for physical devices that have respective Hal * stream. Physical devices that have a corresponding Hal stream but don't have attached * settings here should use the settings field in 'v3_2'. * If any of the physical settings in the array are applied on one or more devices, then the * visual effect on any Hal streams attached to the logical camera is undefined. */ */ vec<PhysicalCameraSetting> physicalCameraSettings; vec<PhysicalCameraSetting> physicalCameraSettings; }; }; Loading
camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +186 −45 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <mutex> #include <mutex> #include <regex> #include <regex> #include <unordered_map> #include <unordered_map> #include <unordered_set> #include <condition_variable> #include <condition_variable> #include <inttypes.h> #include <inttypes.h> Loading @@ -28,6 +29,7 @@ #include <android/hardware/camera/device/3.2/ICameraDevice.h> #include <android/hardware/camera/device/3.2/ICameraDevice.h> #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h> #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <binder/MemoryHeapBase.h> #include <binder/MemoryHeapBase.h> Loading Loading @@ -531,8 +533,10 @@ public: } } }; }; struct DeviceCb : public ICameraDeviceCallback { struct DeviceCb : public V3_4::ICameraDeviceCallback { DeviceCb(CameraHidlTest *parent) : mParent(parent) {} DeviceCb(CameraHidlTest *parent) : mParent(parent) {} Return<void> processCaptureResult_3_4( const hidl_vec<V3_4::CaptureResult>& results) override; Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override; Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override; Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override; Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override; Loading Loading @@ -627,6 +631,15 @@ public: ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4); ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, const std::unordered_set<std::string>& physicalIds, sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, V3_2::Stream* previewStream /*out*/, device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, uint32_t *partialResultCount /*out*/); void configurePreviewStream(const std::string &name, int32_t deviceVersion, void configurePreviewStream(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, const AvailableStream *previewThreshold, Loading @@ -641,7 +654,7 @@ public: static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta); static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta); static Status isLogicalMultiCamera(camera_metadata_t *staticMeta); static Status isLogicalMultiCamera(camera_metadata_t *staticMeta); static Status getPhysicalCameraIds(camera_metadata_t *staticMeta, static Status getPhysicalCameraIds(camera_metadata_t *staticMeta, std::vector<std::string> *physicalIds/*out*/); std::unordered_set<std::string> *physicalIds/*out*/); static Status pickConstrainedModeSize(camera_metadata_t *staticMeta, static Status pickConstrainedModeSize(camera_metadata_t *staticMeta, AvailableStream &hfrStream); AvailableStream &hfrStream); static Status isZSLModeAvailable(camera_metadata_t *staticMeta); static Status isZSLModeAvailable(camera_metadata_t *staticMeta); Loading Loading @@ -844,6 +857,27 @@ Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch( return Void(); return Void(); } } Return<void> CameraHidlTest::DeviceCb::processCaptureResult_3_4( const hidl_vec<V3_4::CaptureResult>& results) { if (nullptr == mParent) { return Void(); } bool notify = false; std::unique_lock<std::mutex> l(mParent->mLock); for (size_t i = 0 ; i < results.size(); i++) { notify = processCaptureResultLocked(results[i].v3_2); } l.unlock(); if (notify) { mParent->mResultCondition.notify_one(); } return Void(); } Return<void> CameraHidlTest::DeviceCb::processCaptureResult( Return<void> CameraHidlTest::DeviceCb::processCaptureResult( const hidl_vec<CaptureResult>& results) { const hidl_vec<CaptureResult>& results) { if (nullptr == mParent) { if (nullptr == mParent) { Loading Loading @@ -3304,7 +3338,7 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) { TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; static_cast<int32_t>(PixelFormat::YCBCR_420_888)}; uint64_t bufferId = 1; uint64_t bufferId = 1; uint32_t frameNumber = 1; uint32_t frameNumber = 1; ::android::hardware::hidl_vec<uint8_t> settings; ::android::hardware::hidl_vec<uint8_t> settings; Loading @@ -3327,7 +3361,7 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); continue; continue; } } std::vector<std::string> physicalIds; std::unordered_set<std::string> physicalIds; rc = getPhysicalCameraIds(staticMeta, &physicalIds); rc = getPhysicalCameraIds(staticMeta, &physicalIds); ASSERT_TRUE(Status::OK == rc); ASSERT_TRUE(Status::OK == rc); ASSERT_TRUE(physicalIds.size() > 1); ASSERT_TRUE(physicalIds.size() > 1); Loading @@ -3336,22 +3370,23 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ret = session->close(); ret = session->close(); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); V3_2::Stream previewStream; // Leave only 2 physical devices in the id set. HalStreamConfiguration halStreamConfig; auto it = physicalIds.begin(); it++; it++; physicalIds.erase(it, physicalIds.end()); V3_4::HalStreamConfiguration halStreamConfig; bool supportsPartialResults = false; bool supportsPartialResults = false; uint32_t partialResultCount = 0; uint32_t partialResultCount = 0; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, V3_2::Stream previewStream; &previewStream /*out*/, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, &partialResultCount /*out*/); sp<device::V3_3::ICameraDeviceSession> session3_3; sp<device::V3_4::ICameraDeviceSession> session3_4; sp<device::V3_4::ICameraDeviceSession> session3_4; castSession(session, deviceVersion, &session3_3, &session3_4); configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds, &session3_4, &previewStream, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, &partialResultCount /*out*/); ASSERT_NE(session3_4, nullptr); ASSERT_NE(session3_4, nullptr); std::shared_ptr<ResultMetadataQueue> resultQueue; std::shared_ptr<ResultMetadataQueue> resultQueue; auto resultQueueRet = auto resultQueueRet = session->getCaptureResultMetadataQueue( session3_4->getCaptureResultMetadataQueue( [&resultQueue](const auto& descriptor) { [&resultQueue](const auto& descriptor) { resultQueue = std::make_shared<ResultMetadataQueue>( resultQueue = std::make_shared<ResultMetadataQueue>( descriptor); descriptor); Loading @@ -3365,38 +3400,40 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { }); }); ASSERT_TRUE(resultQueueRet.isOk()); ASSERT_TRUE(resultQueueRet.isOk()); InFlightRequest inflightReq = {1, false, supportsPartialResults, InFlightRequest inflightReq = {static_cast<ssize_t> (physicalIds.size()), false, partialResultCount, resultQueue}; supportsPartialResults, partialResultCount, resultQueue}; RequestTemplate reqTemplate = RequestTemplate::PREVIEW; RequestTemplate reqTemplate = RequestTemplate::PREVIEW; ret = session->constructDefaultRequestSettings(reqTemplate, ret = session3_4->constructDefaultRequestSettings(reqTemplate, [&](auto status, const auto& req) { [&](auto status, const auto& req) { ASSERT_EQ(Status::OK, status); ASSERT_EQ(Status::OK, status); settings = req; settings = req; }); }); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(settings.size() > 0); sp<GraphicBuffer> gb = new GraphicBuffer( std::vector<sp<GraphicBuffer>> graphicBuffers; previewStream.width, previewStream.height, graphicBuffers.reserve(physicalIds.size()); static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, halStreamConfig.streams[0].consumerUsage)); ASSERT_NE(nullptr, gb.get()); ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; outputBuffers.resize(1); outputBuffers.resize(physicalIds.size()); outputBuffers[0] = {halStreamConfig.streams[0].id, bufferId, hidl_handle(gb->getNativeBuffer()->handle), BufferStatus::OK, nullptr, nullptr}; StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; hidl_vec<V3_4::PhysicalCameraSetting> camSettings; hidl_vec<V3_4::PhysicalCameraSetting> camSettings; camSettings.resize(2); camSettings.resize(physicalIds.size()); camSettings[0] = {0, hidl_string(physicalIds[0]), settings}; size_t k = 0; camSettings[1] = {0, hidl_string(physicalIds[1]), settings}; for (const auto physicalIdIt : physicalIds) { sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width, previewStream.height, static_cast<int32_t>(halStreamConfig.streams[k].v3_3.v3_2.overrideFormat), 1, android_convertGralloc1To0Usage( halStreamConfig.streams[k].v3_3.v3_2.producerUsage, halStreamConfig.streams[k].v3_3.v3_2.consumerUsage)); ASSERT_NE(nullptr, gb.get()); outputBuffers[k] = {halStreamConfig.streams[k].v3_3.v3_2.id, bufferId, hidl_handle(gb->getNativeBuffer()->handle), BufferStatus::OK, nullptr, nullptr}; graphicBuffers.push_back(gb); camSettings[k] = {0, hidl_string(physicalIdIt), settings}; k++; } StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings, V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}, camSettings}; emptyInputBuffer, outputBuffers}, camSettings}; Loading Loading @@ -3431,12 +3468,10 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_FALSE(inflightReq.errorCodeValid); ASSERT_FALSE(inflightReq.errorCodeValid); ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); ASSERT_EQ(halStreamConfig.streams[0].id, inflightReq.resultOutputBuffers[0].streamId); } } // Empty physical camera settings should fail process requests // Empty physical camera settings should fail process requests camSettings[1] = {0, hidl_string(physicalIds[1]), emptySettings}; camSettings[1].settings = emptySettings; frameNumber++; frameNumber++; request = {{frameNumber, 0 /* fmqSettingsSize */, settings, request = {{frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}, camSettings}; emptyInputBuffer, outputBuffers}, camSettings}; Loading @@ -3449,7 +3484,8 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); // Invalid physical camera id should fail process requests // Invalid physical camera id should fail process requests camSettings[1] = {0, invalidPhysicalId, settings}; camSettings[1].physicalCameraId = invalidPhysicalId; camSettings[1].settings = settings; request = {{frameNumber, 0 /* fmqSettingsSize */, settings, request = {{frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}, camSettings}; emptyInputBuffer, outputBuffers}, camSettings}; returnStatus = session3_4->processCaptureRequest_3_4( returnStatus = session3_4->processCaptureRequest_3_4( Loading @@ -3460,7 +3496,7 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { ASSERT_TRUE(returnStatus.isOk()); ASSERT_TRUE(returnStatus.isOk()); ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); ret = session->close(); ret = session3_4->close(); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(ret.isOk()); } } } } Loading Loading @@ -3838,7 +3874,7 @@ Status CameraHidlTest::isLogicalMultiCamera(camera_metadata_t *staticMeta) { // Generate a list of physical camera ids backing a logical multi-camera. // Generate a list of physical camera ids backing a logical multi-camera. Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta, Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta, std::vector<std::string> *physicalIds) { std::unordered_set<std::string> *physicalIds) { if ((nullptr == staticMeta) || (nullptr == physicalIds)) { if ((nullptr == staticMeta) || (nullptr == physicalIds)) { return Status::ILLEGAL_ARGUMENT; return Status::ILLEGAL_ARGUMENT; } } Loading @@ -3856,7 +3892,7 @@ Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta, if (ids[i] == '\0') { if (ids[i] == '\0') { if (start != i) { if (start != i) { std::string currentId(reinterpret_cast<const char *> (ids + start)); std::string currentId(reinterpret_cast<const char *> (ids + start)); physicalIds->push_back(currentId); physicalIds->emplace(currentId); } } start = i + 1; start = i + 1; } } Loading Loading @@ -4028,6 +4064,111 @@ void CameraHidlTest::createStreamConfiguration( *config3_2 = {streams3_2, configMode}; *config3_2 = {streams3_2, configMode}; } } // Configure multiple preview streams using different physical ids. void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, const std::unordered_set<std::string>& physicalIds, sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, V3_2::Stream *previewStream /*out*/, device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, uint32_t *partialResultCount /*out*/) { ASSERT_NE(nullptr, session3_4); ASSERT_NE(nullptr, halStreamConfig); ASSERT_NE(nullptr, previewStream); ASSERT_NE(nullptr, supportsPartialResults); ASSERT_NE(nullptr, partialResultCount); ASSERT_FALSE(physicalIds.empty()); std::vector<AvailableStream> outputPreviewStreams; ::android::sp<ICameraDevice> device3_x; ALOGI("configureStreams: Testing camera device %s", name.c_str()); Return<void> ret; ret = provider->getCameraDeviceInterface_V3_x( name, [&](auto status, const auto& device) { ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); ASSERT_EQ(Status::OK, status); ASSERT_NE(device, nullptr); device3_x = device; }); ASSERT_TRUE(ret.isOk()); sp<DeviceCb> cb = new DeviceCb(this); sp<ICameraDeviceSession> session; ret = device3_x->open( cb, [&session](auto status, const auto& newSession) { ALOGI("device::open returns status:%d", (int)status); ASSERT_EQ(Status::OK, status); ASSERT_NE(newSession, nullptr); session = newSession; }); ASSERT_TRUE(ret.isOk()); sp<device::V3_3::ICameraDeviceSession> session3_3; castSession(session, deviceVersion, &session3_3, session3_4); ASSERT_NE(nullptr, session3_4); camera_metadata_t *staticMeta; ret = device3_x->getCameraCharacteristics([&] (Status s, CameraMetadata metadata) { ASSERT_EQ(Status::OK, s); staticMeta = clone_camera_metadata( reinterpret_cast<const camera_metadata_t*>(metadata.data())); ASSERT_NE(nullptr, staticMeta); }); ASSERT_TRUE(ret.isOk()); camera_metadata_ro_entry entry; auto status = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); if ((0 == status) && (entry.count > 0)) { *partialResultCount = entry.data.i32[0]; *supportsPartialResults = (*partialResultCount > 1); } outputPreviewStreams.clear(); auto rc = getAvailableOutputStreams(staticMeta, outputPreviewStreams, previewThreshold); free_camera_metadata(staticMeta); ASSERT_EQ(Status::OK, rc); ASSERT_FALSE(outputPreviewStreams.empty()); ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(physicalIds.size()); int32_t streamId = 0; for (auto const& physicalId : physicalIds) { V3_4::Stream stream3_4 = {{streamId, StreamType::OUTPUT, static_cast<uint32_t> (outputPreviewStreams[0].width), static_cast<uint32_t> (outputPreviewStreams[0].height), static_cast<PixelFormat> (outputPreviewStreams[0].format), GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0}, physicalId.c_str(), /*bufferSize*/ 0}; streams3_4[streamId++] = stream3_4; } ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}}; RequestTemplate reqTemplate = RequestTemplate::PREVIEW; ret = (*session3_4)->constructDefaultRequestSettings(reqTemplate, [&config3_4](auto status, const auto& req) { ASSERT_EQ(Status::OK, status); config3_4.sessionParams = req; }); ASSERT_TRUE(ret.isOk()); ret = (*session3_4)->configureStreams_3_4(config3_4, [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); ASSERT_EQ(physicalIds.size(), halConfig.streams.size()); *halStreamConfig = halConfig; }); *previewStream = streams3_4[0].v3_2; ASSERT_TRUE(ret.isOk()); } // Open a device session and configure a preview stream. // Open a device session and configure a preview stream. void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion, void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, sp<ICameraProvider> provider, Loading