From 4d25042aef196d1f015c8dade70968c8fc7236f7 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Tue, 20 Nov 2018 16:57:01 -0800 Subject: [PATCH] Camera: update VTS for new useHalBufManager feature Test: updated vts pass on B1 internal/external camera HAL Bug: 109829698 Change-Id: I09de76b93e88e88a7b67df0b22dda7f19596c8e4 --- .../VtsHalCameraProviderV2_4TargetTest.cpp | 759 +++++++++++++++--- 1 file changed, 640 insertions(+), 119 deletions(-) diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index c324d59e6e..9f24b88053 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -31,7 +31,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -130,6 +132,7 @@ const int64_t kTorchTimeoutSec = 1; const int64_t kEmptyFlushTimeoutMSec = 200; const char kDumpOutput[] = "/dev/null"; const uint32_t kBurstFrameCount = 10; +const int64_t kBufferReturnTimeoutSec = 1; struct AvailableStream { int32_t width; @@ -541,7 +544,7 @@ public: hidl_vec getCameraDeviceNames(sp provider); - struct EmptyDeviceCb : public V3_4::ICameraDeviceCallback { + struct EmptyDeviceCb : public V3_5::ICameraDeviceCallback { virtual Return processCaptureResult( const hidl_vec& /*results*/) override { ALOGI("processCaptureResult callback"); @@ -561,21 +564,63 @@ public: ADD_FAILURE(); // Empty callback should not reach here return Void(); } + + virtual Return requestStreamBuffers( + const hidl_vec&, + requestStreamBuffers_cb _hidl_cb) override { + ALOGI("requestStreamBuffers callback"); + // HAL might want to request buffer after configureStreams, but tests with EmptyDeviceCb + // doesn't actually need to send capture requests, so just return an error. + hidl_vec emptyBufRets; + _hidl_cb(V3_5::BufferRequestStatus::FAILED_UNKNOWN, emptyBufRets); + return Void(); + } + + virtual Return returnStreamBuffers(const hidl_vec&) override { + ALOGI("returnStreamBuffers"); + ADD_FAILURE(); // Empty callback should not reach here + return Void(); + } + }; - struct DeviceCb : public V3_4::ICameraDeviceCallback { + struct DeviceCb : public V3_5::ICameraDeviceCallback { DeviceCb(CameraHidlTest *parent, bool checkMonochromeResult) : mParent(parent), mCheckMonochromeResult(checkMonochromeResult) {} + Return processCaptureResult_3_4( const hidl_vec& results) override; Return processCaptureResult(const hidl_vec& results) override; Return notify(const hidl_vec& msgs) override; + Return requestStreamBuffers( + const hidl_vec& bufReqs, + requestStreamBuffers_cb _hidl_cb) override; + + Return returnStreamBuffers(const hidl_vec& buffers) override; + + void setCurrentStreamConfig(const hidl_vec& streams, + const hidl_vec& halStreams); + + void waitForBuffersReturned(); + private: bool processCaptureResultLocked(const CaptureResult& results); - CameraHidlTest *mParent; // Parent object + CameraHidlTest *mParent; // Parent object bool mCheckMonochromeResult; + bool hasOutstandingBuffersLocked(); + + /* members for requestStreamBuffers() and returnStreamBuffers()*/ + std::mutex mLock; // protecting members below + bool mUseHalBufManager = false; + hidl_vec mStreams; + hidl_vec mHalStreams; + uint64_t mNextBufferId = 1; + using OutstandingBuffers = std::unordered_map; + // size == mStreams.size(). Tracking each streams outstanding buffers + std::vector mOutstandingBufferIds; + std::condition_variable mFlushedCondition; }; struct TorchProviderCb : public ICameraProviderCallback { @@ -659,21 +704,27 @@ public: camera_metadata_t **staticMeta /*out*/); void castSession(const sp &session, int32_t deviceVersion, sp *session3_3 /*out*/, - sp *session3_4 /*out*/); + sp *session3_4 /*out*/, + sp *session3_5 /*out*/); void createStreamConfiguration(const ::android::hardware::hidl_vec& streams3_2, StreamConfigurationMode configMode, ::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, + ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp provider, const AvailableStream *previewThreshold, const std::unordered_set& physicalIds, sp *session3_4 /*out*/, + sp *session3_5 /*out*/, V3_2::Stream* previewStream /*out*/, device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, - uint32_t *partialResultCount /*out*/); + uint32_t *partialResultCount /*out*/, + bool *useHalBufManager /*out*/, + sp *cb /*out*/, + uint32_t streamConfigCounter = 0); void configurePreviewStream(const std::string &name, int32_t deviceVersion, sp provider, const AvailableStream *previewThreshold, @@ -681,7 +732,10 @@ public: V3_2::Stream *previewStream /*out*/, HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, - uint32_t *partialResultCount /*out*/); + uint32_t *partialResultCount /*out*/, + bool *useHalBufManager /*out*/, + sp *cb /*out*/, + uint32_t streamConfigCounter = 0); void verifyLogicalCameraMetadata(const std::string& cameraName, const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device, @@ -693,6 +747,14 @@ public: void verifyMonochromeCameraResult( const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata); + void verifyBuffersReturned(sp session, + int deviceVerison, int32_t streamId, sp cb, + uint32_t streamConfigCounter = 0); + + void verifyBuffersReturned(sp session, + hidl_vec streamIds, sp cb, + uint32_t streamConfigCounter = 0); + static Status getAvailableOutputStreams(camera_metadata_t *staticMeta, std::vector &outputStreams, const AvailableStream *threshold = nullptr); @@ -1092,9 +1154,51 @@ bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& r if (request->shutterTimestamp != 0) { notify = true; } + + if (mUseHalBufManager) { + returnStreamBuffers(results.outputBuffers); + } return notify; } +void CameraHidlTest::DeviceCb::setCurrentStreamConfig( + const hidl_vec& streams, const hidl_vec& halStreams) { + ASSERT_EQ(streams.size(), halStreams.size()); + ASSERT_NE(streams.size(), 0); + for (size_t i = 0; i < streams.size(); i++) { + ASSERT_EQ(streams[i].id, halStreams[i].id); + } + std::lock_guard l(mLock); + mUseHalBufManager = true; + mStreams = streams; + mHalStreams = halStreams; + mOutstandingBufferIds.clear(); + for (size_t i = 0; i < streams.size(); i++) { + mOutstandingBufferIds.emplace_back(); + } +} + +bool CameraHidlTest::DeviceCb::hasOutstandingBuffersLocked() { + if (!mUseHalBufManager) { + return false; + } + for (const auto& outstandingBuffers : mOutstandingBufferIds) { + if (!outstandingBuffers.empty()) { + return true; + } + } + return false; +} + +void CameraHidlTest::DeviceCb::waitForBuffersReturned() { + std::unique_lock lk(mLock); + if (hasOutstandingBuffersLocked()) { + auto timeout = std::chrono::seconds(kBufferReturnTimeoutSec); + auto st = mFlushedCondition.wait_for(lk, timeout); + ASSERT_NE(std::cv_status::timeout, st); + } +} + Return CameraHidlTest::DeviceCb::notify( const hidl_vec& messages) { std::lock_guard l(mParent->mLock); @@ -1137,6 +1241,124 @@ Return CameraHidlTest::DeviceCb::notify( return Void(); } +Return CameraHidlTest::DeviceCb::requestStreamBuffers( + const hidl_vec& bufReqs, + requestStreamBuffers_cb _hidl_cb) { + using V3_5::BufferRequestStatus; + using V3_5::StreamBufferRet; + using V3_5::StreamBufferRequestError; + hidl_vec bufRets; + std::unique_lock l(mLock); + + if (!mUseHalBufManager) { + ALOGE("%s: Camera does not support HAL buffer management", __FUNCTION__); + ADD_FAILURE(); + _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets); + return Void(); + } + + if (bufReqs.size() > mStreams.size()) { + ALOGE("%s: illegal buffer request: too many requests!", __FUNCTION__); + ADD_FAILURE(); + _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets); + return Void(); + } + + std::vector indexes(bufReqs.size()); + for (size_t i = 0; i < bufReqs.size(); i++) { + bool found = false; + for (size_t idx = 0; idx < mStreams.size(); idx++) { + if (bufReqs[i].streamId == mStreams[idx].id) { + found = true; + indexes[i] = idx; + break; + } + } + if (!found) { + ALOGE("%s: illegal buffer request: unknown streamId %d!", + __FUNCTION__, bufReqs[i].streamId); + ADD_FAILURE(); + _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets); + return Void(); + } + } + + bool allStreamOk = true; + bool atLeastOneStreamOk = false; + bufRets.resize(bufReqs.size()); + for (size_t i = 0; i < bufReqs.size(); i++) { + int32_t idx = indexes[i]; + const auto& stream = mStreams[idx]; + const auto& halStream = mHalStreams[idx]; + const V3_5::BufferRequest& bufReq = bufReqs[i]; + if (mOutstandingBufferIds[idx].size() + bufReq.numBuffersRequested > halStream.maxBuffers) { + bufRets[i].streamId = stream.id; + bufRets[i].val.error(StreamBufferRequestError::MAX_BUFFER_EXCEEDED); + allStreamOk = false; + continue; + } + + hidl_vec tmpRetBuffers(bufReq.numBuffersRequested); + for (size_t i = 0; i < bufReq.numBuffersRequested; i++) { + hidl_handle buffer_handle; + mParent->allocateGraphicBuffer(stream.width, stream.height, + android_convertGralloc1To0Usage( + halStream.producerUsage, halStream.consumerUsage), + halStream.overrideFormat, &buffer_handle); + + tmpRetBuffers[i] = {stream.id, mNextBufferId, buffer_handle, BufferStatus::OK, + nullptr, nullptr}; + mOutstandingBufferIds[idx].insert(std::make_pair(mNextBufferId++, buffer_handle)); + } + atLeastOneStreamOk = true; + bufRets[0].val.buffers(std::move(tmpRetBuffers)); + } + + if (allStreamOk) { + _hidl_cb(BufferRequestStatus::OK, bufRets); + } else if (atLeastOneStreamOk) { + _hidl_cb(BufferRequestStatus::FAILED_PARTIAL, bufRets); + } else { + _hidl_cb(BufferRequestStatus::FAILED_UNKNOWN, bufRets); + } + + if (!hasOutstandingBuffersLocked()) { + l.unlock(); + mFlushedCondition.notify_one(); + } + return Void(); +} + +Return CameraHidlTest::DeviceCb::returnStreamBuffers( + const hidl_vec& buffers) { + if (!mUseHalBufManager) { + ALOGE("%s: Camera does not support HAL buffer management", __FUNCTION__); + ADD_FAILURE(); + } + + std::lock_guard l(mLock); + for (const auto& buf : buffers) { + bool found = false; + for (size_t idx = 0; idx < mOutstandingBufferIds.size(); idx++) { + if (mStreams[idx].id == buf.streamId && + mOutstandingBufferIds[idx].count(buf.bufferId) == 1) { + mOutstandingBufferIds[idx].erase(buf.bufferId); + // TODO: check do we need to close/delete native handle or assume we have enough + // memory to run till the test finish? since we do not capture much requests (and + // most of time one buffer is sufficient) + found = true; + break; + } + } + if (found) { + continue; + } + ALOGE("%s: unknown buffer ID %" PRIu64, __FUNCTION__, buf.bufferId); + ADD_FAILURE(); + } + return Void(); +} + hidl_vec CameraHidlTest::getCameraDeviceNames(sp provider) { std::vector cameraDeviceNames; Return ret; @@ -2377,14 +2599,18 @@ TEST_F(CameraHidlTest, openClose) { // cast the 3.3/3.4 interface, and that lower versions can't be cast to it. sp sessionV3_3; sp sessionV3_4; - castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4); - if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4 || - deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) { + sp sessionV3_5; + castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4, &sessionV3_5); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) { + ASSERT_TRUE(sessionV3_5.get() != nullptr); + } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { ASSERT_TRUE(sessionV3_4.get() != nullptr); } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) { ASSERT_TRUE(sessionV3_3.get() != nullptr); - } else { + } else { //V3_2 ASSERT_TRUE(sessionV3_3.get() == nullptr); + ASSERT_TRUE(sessionV3_4.get() == nullptr); + ASSERT_TRUE(sessionV3_5.get() == nullptr); } native_handle_t* raw_handle = native_handle_create(1, 0); raw_handle->data[0] = open(kDumpOutput, O_RDWR); @@ -2540,15 +2766,17 @@ TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) { sp session; sp session3_3; sp session3_4; + sp session3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); ASSERT_NE(0u, outputStreams.size()); int32_t streamId = 0; + uint32_t streamConfigCounter = 0; for (auto& it : outputStreams) { V3_2::Stream stream3_2; bool isJpeg = static_cast(it.format) == PixelFormat::BLOB; @@ -2561,11 +2789,20 @@ TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) { (isJpeg) ? static_cast(Dataspace::V0_JFIF) : 0, StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams3_2 = {stream3_2}; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); @@ -2617,8 +2854,9 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { sp session; sp session3_3; sp session3_4; + sp session3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -2633,29 +2871,38 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0}; + uint32_t streamConfigCounter = 0; ::android::hardware::hidl_vec streams = {stream3_2}; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if(session3_4 != nullptr) { - ret = session3_4->configureStreams_3_4(config3_4, - [](Status s, device::V3_4::HalStreamConfiguration) { - ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || (Status::INTERNAL_ERROR == s)); - }); + }); + } else if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config3_4, + [](Status s, device::V3_4::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); } else if(session3_3 != nullptr) { ret = session3_3->configureStreams_3_3(config3_2, - [](Status s, device::V3_3::HalStreamConfiguration) { - ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || - (Status::INTERNAL_ERROR == s)); - }); + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); } else { ret = session->configureStreams(config3_2, - [](Status s, HalStreamConfiguration) { - ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || - (Status::INTERNAL_ERROR == s)); - }); + [](Status s, HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); } ASSERT_TRUE(ret.isOk()); @@ -2669,8 +2916,14 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream3_2; createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if(session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, [](Status s, + device::V3_4::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if(session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); @@ -2699,8 +2952,14 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream3_2; createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if(session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if(session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); @@ -2728,8 +2987,14 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { static_cast(UINT32_MAX)}; streams[0] = stream3_2; createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if(session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if(session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); @@ -2776,8 +3041,9 @@ TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { sp session; sp session3_3; sp session3_4; + sp session3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); Status rc = isZSLModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -2807,6 +3073,7 @@ TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { int32_t streamId = 0; bool hasPrivToY8 = false, hasY8ToY8 = false, hasY8ToBlob = false; + uint32_t streamConfigCounter = 0; for (auto& inputIter : inputOutputMap) { AvailableStream input; ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat, @@ -2857,11 +3124,19 @@ TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { ::android::hardware::hidl_vec streams = {inputStream, zslStream, outputStream}; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(3u, halConfig.streams.size()); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); @@ -2923,9 +3198,14 @@ TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) { sp session; sp session3_3; sp session3_4; + sp session3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4); - ASSERT_NE(session3_4, nullptr); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { + ASSERT_NE(session3_4, nullptr); + } else { + ASSERT_NE(session3_5, nullptr); + } std::unordered_set availableSessionKeys; auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS, @@ -2964,17 +3244,29 @@ TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) { StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams = {previewStream}; ::android::hardware::camera::device::V3_4::StreamConfiguration config; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; config.streams = streams; config.operationMode = StreamConfigurationMode::NORMAL_MODE; const camera_metadata_t *sessionParamsBuffer = sessionParams.getAndLock(); config.sessionParams.setToExternal( reinterpret_cast (const_cast (sessionParamsBuffer)), get_camera_metadata_size(sessionParamsBuffer)); - ret = session3_4->configureStreams_3_4(config, - [](Status s, device::V3_4::HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(1u, halConfig.streams.size()); - }); + config3_5.v3_4 = config; + config3_5.streamConfigCounter = 0; + if (session3_5 != nullptr) { + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + }); + } else { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + }); + } + ASSERT_TRUE(ret.isOk()); free_camera_metadata(staticMetaBuffer); @@ -3009,8 +3301,9 @@ TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { sp session; sp session3_3; sp session3_4; + sp session3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); outputBlobStreams.clear(); ASSERT_EQ(Status::OK, @@ -3024,6 +3317,7 @@ TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { ASSERT_NE(0u, outputPreviewStreams.size()); int32_t streamId = 0; + uint32_t streamConfigCounter = 0; for (auto& blobIter : outputBlobStreams) { for (auto& previewIter : outputPreviewStreams) { V3_2::Stream previewStream = {streamId++, @@ -3044,11 +3338,19 @@ TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams = {previewStream, blobStream}; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); @@ -3098,8 +3400,9 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { sp session; sp session3_3; sp session3_4; + sp session3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); Status rc = isConstrainedModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -3114,6 +3417,7 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { ASSERT_EQ(Status::OK, rc); int32_t streamId = 0; + uint32_t streamConfigCounter = 0; V3_2::Stream stream = {streamId, StreamType::OUTPUT, static_cast(hfrStream.width), @@ -3123,11 +3427,20 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { 0, StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams = {stream}; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); @@ -3161,8 +3474,15 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration) { ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || @@ -3193,8 +3513,14 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); @@ -3222,8 +3548,14 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); @@ -3273,8 +3605,9 @@ TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { sp session; sp session3_3; sp session3_4; + sp session3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); outputBlobStreams.clear(); ASSERT_EQ(Status::OK, @@ -3289,6 +3622,7 @@ TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { ASSERT_NE(0u, outputVideoStreams.size()); int32_t streamId = 0; + uint32_t streamConfigCounter = 0; for (auto& blobIter : outputBlobStreams) { for (auto& videoIter : outputVideoStreams) { V3_2::Stream videoStream = {streamId++, @@ -3308,11 +3642,19 @@ TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { static_cast(Dataspace::V0_JFIF), StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams = {videoStream, blobStream}; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + config3_5.streamConfigCounter = streamConfigCounter++; + ret = session3_5->configureStreams_3_5(config3_5, + [](Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else if (session3_4 != nullptr) { ret = session3_4->configureStreams_3_4(config3_4, [](Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); @@ -3363,12 +3705,14 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) { V3_2::Stream previewStream; HalStreamConfiguration halStreamConfig; sp session; + sp cb; bool supportsPartialResults = false; + bool useHalBufManager = false; uint32_t partialResultCount = 0; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, - &partialResultCount /*out*/); + &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/); std::shared_ptr resultQueue; auto resultQueueRet = @@ -3399,17 +3743,26 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) { ASSERT_TRUE(ret.isOk()); hidl_handle buffer_handle; - allocateGraphicBuffer(previewStream.width, previewStream.height, - android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, - halStreamConfig.streams[0].consumerUsage), - halStreamConfig.streams[0].overrideFormat, &buffer_handle); - - StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, - bufferId, - buffer_handle, - BufferStatus::OK, - nullptr, - nullptr}; + StreamBuffer outputBuffer; + if (useHalBufManager) { + outputBuffer = {halStreamConfig.streams[0].id, + /*bufferId*/ 0, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + } else { + allocateGraphicBuffer(previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, + halStreamConfig.streams[0].consumerUsage), + halStreamConfig.streams[0].overrideFormat, &buffer_handle); + outputBuffer = {halStreamConfig.streams[0].id, + bufferId, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + } ::android::hardware::hidl_vec outputBuffers = {outputBuffer}; StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; @@ -3489,6 +3842,10 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) { ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); } + if (useHalBufManager) { + verifyBuffersReturned(session, deviceVersion, previewStream.id, cb); + } + ret = session->close(); ASSERT_TRUE(ret.isOk()); } @@ -3570,12 +3927,16 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { V3_4::HalStreamConfiguration halStreamConfig; bool supportsPartialResults = false; + bool useHalBufManager = false; uint32_t partialResultCount = 0; V3_2::Stream previewStream; sp session3_4; + sp session3_5; + sp cb; configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds, - &session3_4, &previewStream, &halStreamConfig /*out*/, - &supportsPartialResults /*out*/, &partialResultCount /*out*/); + &session3_4, &session3_5, &previewStream, &halStreamConfig /*out*/, + &supportsPartialResults /*out*/, &partialResultCount /*out*/, + &useHalBufManager /*out*/, &cb /*out*/); ASSERT_NE(session3_4, nullptr); std::shared_ptr resultQueue; @@ -3604,14 +3965,19 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { size_t k = 0; for (const auto& halStream : halStreamConfig.streams) { hidl_handle buffer_handle; - allocateGraphicBuffer(previewStream.width, previewStream.height, - android_convertGralloc1To0Usage(halStream.v3_3.v3_2.producerUsage, - halStream.v3_3.v3_2.consumerUsage), - halStream.v3_3.v3_2.overrideFormat, &buffer_handle); - graphicBuffers.push_back(buffer_handle); - outputBuffers[k] = {halStream.v3_3.v3_2.id, bufferId, buffer_handle, - BufferStatus::OK, nullptr, nullptr}; - bufferId++; + if (useHalBufManager) { + outputBuffers[k] = {halStream.v3_3.v3_2.id, /*bufferId*/0, buffer_handle, + BufferStatus::OK, nullptr, nullptr}; + } else { + allocateGraphicBuffer(previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStream.v3_3.v3_2.producerUsage, + halStream.v3_3.v3_2.consumerUsage), + halStream.v3_3.v3_2.overrideFormat, &buffer_handle); + graphicBuffers.push_back(buffer_handle); + outputBuffers[k] = {halStream.v3_3.v3_2.id, bufferId, buffer_handle, + BufferStatus::OK, nullptr, nullptr}; + bufferId++; + } k++; } hidl_vec camSettings(1); @@ -3713,6 +4079,15 @@ TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { defaultPreviewSettings.unlock(settingsBuffer); filteredSettings.unlock(filteredSettingsBuffer); + + if (useHalBufManager) { + hidl_vec streamIds(halStreamConfig.streams.size()); + for (size_t i = 0; i < streamIds.size(); i++) { + streamIds[i] = halStreamConfig.streams[i].v3_3.v3_2.id; + } + verifyBuffersReturned(session3_4, streamIds, cb); + } + ret = session3_4->close(); ASSERT_TRUE(ret.isOk()); } @@ -3761,12 +4136,15 @@ TEST_F(CameraHidlTest, processCaptureRequestBurstISO) { ASSERT_TRUE(ret.isOk()); bool supportsPartialResults = false; + bool useHalBufManager = false; uint32_t partialResultCount = 0; V3_2::Stream previewStream; HalStreamConfiguration halStreamConfig; + sp cb; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/, - &supportsPartialResults /*out*/, &partialResultCount /*out*/); + &supportsPartialResults /*out*/, &partialResultCount /*out*/, + &useHalBufManager /*out*/, &cb /*out*/); std::shared_ptr resultQueue; auto resultQueueRet = session->getCaptureResultMetadataQueue( @@ -3800,13 +4178,18 @@ TEST_F(CameraHidlTest, processCaptureRequestBurstISO) { std::unique_lock l(mLock); isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1]; - allocateGraphicBuffer(previewStream.width, previewStream.height, - android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, - halStreamConfig.streams[0].consumerUsage), - halStreamConfig.streams[0].overrideFormat, &buffers[i]); + if (useHalBufManager) { + outputBuffers[i] = {halStreamConfig.streams[0].id, /*bufferId*/0, + nullptr, BufferStatus::OK, nullptr, nullptr}; + } else { + allocateGraphicBuffer(previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, + halStreamConfig.streams[0].consumerUsage), + halStreamConfig.streams[0].overrideFormat, &buffers[i]); + outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i, + buffers[i], BufferStatus::OK, nullptr, nullptr}; + } - outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i, - buffers[i], BufferStatus::OK, nullptr, nullptr}; requestMeta.append(reinterpret_cast (settings.data())); // Disable all 3A routines @@ -3859,6 +4242,9 @@ TEST_F(CameraHidlTest, processCaptureRequestBurstISO) { std::round(isoValues[i]*isoTol)); } + if (useHalBufManager) { + verifyBuffersReturned(session, deviceVersion, previewStream.id, cb); + } ret = session->close(); ASSERT_TRUE(ret.isOk()); } @@ -3888,18 +4274,25 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) { V3_2::Stream previewStream; HalStreamConfiguration halStreamConfig; sp session; + sp cb; bool supportsPartialResults = false; + bool useHalBufManager = false; uint32_t partialResultCount = 0; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, - &partialResultCount /*out*/); + &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/); hidl_handle buffer_handle; - allocateGraphicBuffer(previewStream.width, previewStream.height, - android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, - halStreamConfig.streams[0].consumerUsage), - halStreamConfig.streams[0].overrideFormat, &buffer_handle); + + if (useHalBufManager) { + bufferId = 0; + } else { + allocateGraphicBuffer(previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, + halStreamConfig.streams[0].consumerUsage), + halStreamConfig.streams[0].overrideFormat, &buffer_handle); + } StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, bufferId, @@ -3955,12 +4348,14 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) { V3_2::Stream previewStream; HalStreamConfiguration halStreamConfig; sp session; + sp cb; bool supportsPartialResults = false; + bool useHalBufManager = false; uint32_t partialResultCount = 0; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, - &partialResultCount /*out*/); + &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/); RequestTemplate reqTemplate = RequestTemplate::PREVIEW; Return ret; @@ -4019,12 +4414,14 @@ TEST_F(CameraHidlTest, flushPreviewRequest) { V3_2::Stream previewStream; HalStreamConfiguration halStreamConfig; sp session; + sp cb; bool supportsPartialResults = false; + bool useHalBufManager = false; uint32_t partialResultCount = 0; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, - &partialResultCount /*out*/); + &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/); std::shared_ptr resultQueue; auto resultQueueRet = @@ -4054,10 +4451,14 @@ TEST_F(CameraHidlTest, flushPreviewRequest) { ASSERT_TRUE(ret.isOk()); hidl_handle buffer_handle; - allocateGraphicBuffer(previewStream.width, previewStream.height, - android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, - halStreamConfig.streams[0].consumerUsage), - halStreamConfig.streams[0].overrideFormat, &buffer_handle); + if (useHalBufManager) { + bufferId = 0; + } else { + allocateGraphicBuffer(previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, + halStreamConfig.streams[0].consumerUsage), + halStreamConfig.streams[0].overrideFormat, &buffer_handle); + } StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, bufferId, @@ -4124,6 +4525,10 @@ TEST_F(CameraHidlTest, flushPreviewRequest) { } } + if (useHalBufManager) { + verifyBuffersReturned(session, deviceVersion, previewStream.id, cb); + } + ret = session->close(); ASSERT_TRUE(ret.isOk()); } @@ -4149,12 +4554,14 @@ TEST_F(CameraHidlTest, flushEmpty) { V3_2::Stream previewStream; HalStreamConfiguration halStreamConfig; sp session; + sp cb; bool supportsPartialResults = false; + bool useHalBufManager = false; uint32_t partialResultCount = 0; configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/, &supportsPartialResults /*out*/, - &partialResultCount /*out*/); + &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/); Return returnStatus = session->flush(); ASSERT_TRUE(returnStatus.isOk()); @@ -4496,9 +4903,11 @@ void CameraHidlTest::createStreamConfiguration( const ::android::hardware::hidl_vec& streams3_2, StreamConfigurationMode configMode, ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2 /*out*/, - ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/) { + ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/, + ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5 /*out*/) { ASSERT_NE(nullptr, config3_2); ASSERT_NE(nullptr, config3_4); + ASSERT_NE(nullptr, config3_5); ::android::hardware::hidl_vec streams3_4(streams3_2.size()); size_t idx = 0; @@ -4507,7 +4916,9 @@ void CameraHidlTest::createStreamConfiguration( stream.v3_2 = stream3_2; streams3_4[idx++] = stream; } - *config3_4 = {streams3_4, configMode, {}}; + // Caller is responsible to fill in non-zero config3_5->streamConfigCounter after this returns + *config3_5 = {{streams3_4, configMode, {}}, 0}; + *config3_4 = config3_5->v3_4; *config3_2 = {streams3_2, configMode}; } @@ -4517,15 +4928,22 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t const AvailableStream *previewThreshold, const std::unordered_set& physicalIds, sp *session3_4 /*out*/, + sp *session3_5 /*out*/, V3_2::Stream *previewStream /*out*/, device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, - uint32_t *partialResultCount /*out*/) { + uint32_t *partialResultCount /*out*/, + bool *useHalBufManager /*out*/, + sp *outCb /*out*/, + uint32_t streamConfigCounter) { ASSERT_NE(nullptr, session3_4); + ASSERT_NE(nullptr, session3_5); ASSERT_NE(nullptr, halStreamConfig); ASSERT_NE(nullptr, previewStream); ASSERT_NE(nullptr, supportsPartialResults); ASSERT_NE(nullptr, partialResultCount); + ASSERT_NE(nullptr, useHalBufManager); + ASSERT_NE(nullptr, outCb); ASSERT_FALSE(physicalIds.empty()); std::vector outputPreviewStreams; @@ -4574,10 +4992,19 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t session = newSession; }); ASSERT_TRUE(ret.isOk()); + *outCb = cb; sp session3_3; - castSession(session, deviceVersion, &session3_3, session3_4); - ASSERT_NE(nullptr, session3_4); + castSession(session, deviceVersion, &session3_3, session3_4, session3_5); + ASSERT_NE(nullptr, (*session3_4).get()); + + *useHalBufManager = false; + status = find_camera_metadata_ro_entry(staticMeta, + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry); + if ((0 == status) && (entry.count == 1)) { + *useHalBufManager = (entry.data.u8[0] == + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); + } outputPreviewStreams.clear(); auto rc = getAvailableOutputStreams(staticMeta, @@ -4599,6 +5026,7 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t } ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}}; RequestTemplate reqTemplate = RequestTemplate::PREVIEW; ret = (*session3_4)->constructDefaultRequestSettings(reqTemplate, @@ -4608,12 +5036,32 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t }); 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; - }); + if (*session3_5 != nullptr) { + config3_5.v3_4 = config3_4; + config3_5.streamConfigCounter = streamConfigCounter; + ret = (*session3_5)->configureStreams_3_5(config3_5, + [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(physicalIds.size(), halConfig.streams.size()); + *halStreamConfig = halConfig; + if (*useHalBufManager) { + hidl_vec streams(physicalIds.size()); + hidl_vec halStreams(physicalIds.size()); + for (size_t i = 0; i < physicalIds.size(); i++) { + streams[i] = streams3_4[i].v3_2; + halStreams[i] = halConfig.streams[i].v3_3.v3_2; + } + cb->setCurrentStreamConfig(streams, halStreams); + } + }); + } else { + 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()); } @@ -4626,12 +5074,17 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t dev V3_2::Stream *previewStream /*out*/, HalStreamConfiguration *halStreamConfig /*out*/, bool *supportsPartialResults /*out*/, - uint32_t *partialResultCount /*out*/) { + uint32_t *partialResultCount /*out*/, + bool *useHalBufManager /*out*/, + sp *outCb /*out*/, + uint32_t streamConfigCounter) { ASSERT_NE(nullptr, session); ASSERT_NE(nullptr, previewStream); ASSERT_NE(nullptr, halStreamConfig); ASSERT_NE(nullptr, supportsPartialResults); ASSERT_NE(nullptr, partialResultCount); + ASSERT_NE(nullptr, useHalBufManager); + ASSERT_NE(nullptr, outCb); std::vector outputPreviewStreams; ::android::sp device3_x; @@ -4678,10 +5131,20 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t dev *session = newSession; }); ASSERT_TRUE(ret.isOk()); + *outCb = cb; sp session3_3; sp session3_4; - castSession(*session, deviceVersion, &session3_3, &session3_4); + sp session3_5; + castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5); + + *useHalBufManager = false; + status = find_camera_metadata_ro_entry(staticMeta, + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry); + if ((0 == status) && (entry.count == 1)) { + *useHalBufManager = (entry.data.u8[0] == + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); + } outputPreviewStreams.clear(); auto rc = getAvailableOutputStreams(staticMeta, @@ -4698,9 +5161,33 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t dev ::android::hardware::hidl_vec streams3_2 = {stream3_2}; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4); - if (session3_4 != nullptr) { + &config3_2, &config3_4, &config3_5); + if (session3_5 != nullptr) { + RequestTemplate reqTemplate = RequestTemplate::PREVIEW; + ret = session3_5->constructDefaultRequestSettings(reqTemplate, + [&config3_5](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + config3_5.v3_4.sessionParams = req; + }); + ASSERT_TRUE(ret.isOk()); + config3_5.streamConfigCounter = streamConfigCounter; + ret = session3_5->configureStreams_3_5(config3_5, + [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + halStreamConfig->streams.resize(1); + halStreamConfig->streams[0] = halConfig.streams[0].v3_3.v3_2; + if (*useHalBufManager) { + hidl_vec streams(1); + hidl_vec halStreams(1); + streams[0] = stream3_2; + halStreams[0] = halConfig.streams[0].v3_3.v3_2; + cb->setCurrentStreamConfig(streams, halStreams); + } + }); + } else if (session3_4 != nullptr) { RequestTemplate reqTemplate = RequestTemplate::PREVIEW; ret = session3_4->constructDefaultRequestSettings(reqTemplate, [&config3_4](auto status, const auto& req) { @@ -4742,18 +5229,25 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t dev //Cast camera device session to corresponding version void CameraHidlTest::castSession(const sp &session, int32_t deviceVersion, sp *session3_3 /*out*/, - sp *session3_4 /*out*/) { + sp *session3_4 /*out*/, + sp *session3_5 /*out*/) { ASSERT_NE(nullptr, session3_3); ASSERT_NE(nullptr, session3_4); + ASSERT_NE(nullptr, session3_5); switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_5: + case CAMERA_DEVICE_API_VERSION_3_5: { + auto castResult = device::V3_5::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + *session3_5 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_4: { auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session); ASSERT_TRUE(castResult.isOk()); *session3_4 = castResult; - break; } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_3: { auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session); ASSERT_TRUE(castResult.isOk()); @@ -5004,6 +5498,33 @@ void CameraHidlTest::verifyMonochromeCameraResult( } } +void CameraHidlTest::verifyBuffersReturned( + sp session, + int deviceVersion, int32_t streamId, + sp cb, uint32_t streamConfigCounter) { + sp session3_3; + sp session3_4; + sp session3_5; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5); + ASSERT_NE(nullptr, session3_5.get()); + + hidl_vec streamIds(1); + streamIds[0] = streamId; + session3_5->signalStreamFlush(streamIds, /*streamConfigCounter*/streamConfigCounter); + cb->waitForBuffersReturned(); +} + +void CameraHidlTest::verifyBuffersReturned( + sp session3_4, + hidl_vec streamIds, sp cb, uint32_t streamConfigCounter) { + auto castResult = device::V3_5::ICameraDeviceSession::castFrom(session3_4); + ASSERT_TRUE(castResult.isOk()); + sp session3_5 = castResult; + ASSERT_NE(nullptr, session3_5.get()); + + session3_5->signalStreamFlush(streamIds, /*streamConfigCounter*/streamConfigCounter); + cb->waitForBuffersReturned(); +} // Open a device session with empty callbacks and return static metadata. void CameraHidlTest::openEmptyDeviceSession(const std::string &name,