Loading camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +394 −13 Original line number Diff line number Diff line Loading @@ -125,6 +125,7 @@ using ::android::hardware::camera::device::V3_4::PhysicalCameraMetadata; using ::android::hardware::camera::metadata::V3_4:: CameraMetadataEnumAndroidSensorInfoColorFilterArrangement; using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag; using ::android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode; using ::android::hardware::camera::provider::V2_4::ICameraProvider; using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination; Loading Loading @@ -767,6 +768,8 @@ public: sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/); void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice> *device3_5/*out*/); void castDevice3_7(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_7::ICameraDevice>* device3_7 /*out*/); void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2, StreamConfigurationMode configMode, ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, Loading @@ -785,6 +788,16 @@ public: sp<DeviceCb> *outCb /*out*/, uint32_t *jpegBufferSize /*out*/, bool *useHalBufManager /*out*/); void configureStreams3_7(const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider, PixelFormat format, sp<device::V3_7::ICameraDeviceSession>* session3_7 /*out*/, V3_2::Stream* previewStream /*out*/, device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, bool maxResolution); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, Loading Loading @@ -846,6 +859,10 @@ public: hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter = 0); void verifyBuffersReturned(sp<device::V3_7::ICameraDeviceSession> session, hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter = 0); void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5, camera_metadata* oldSessionParams, camera_metadata* newSessionParams); Loading @@ -853,12 +870,15 @@ public: static bool isDepthOnly(const camera_metadata_t* staticMeta); static bool isUltraHighResolution(const camera_metadata_t* staticMeta); static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>& outputStreams, const AvailableStream *threshold = nullptr); const AvailableStream* threshold = nullptr, bool maxResolution = false); static Status getMaxOutputSizeForFormat(const camera_metadata_t* staticMeta, PixelFormat format, Size* size); Size* size, bool maxResolution = false); static Status getMandatoryConcurrentStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>* outputStreams); Loading Loading @@ -4841,6 +4861,184 @@ TEST_P(CameraHidlTest, processMultiCaptureRequestPreview) { } } // Generate and verify an ultra high resolution capture request TEST_P(CameraHidlTest, processUltraHighResolutionRequest) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); uint64_t bufferId = 1; uint32_t frameNumber = 1; ::android::hardware::hidl_vec<uint8_t> settings; for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_7) { continue; } std::string version, deviceId; ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId)); camera_metadata_t* staticMeta; Return<void> ret; sp<ICameraDeviceSession> session; openEmptyDeviceSession(name, mProvider, &session, &staticMeta); if (!isUltraHighResolution(staticMeta)) { free_camera_metadata(staticMeta); ret = session->close(); ASSERT_TRUE(ret.isOk()); continue; } android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings; ret = session->constructDefaultRequestSettings( RequestTemplate::STILL_CAPTURE, [&defaultSettings](auto status, const auto& req) mutable { ASSERT_EQ(Status::OK, status); const camera_metadata_t* metadata = reinterpret_cast<const camera_metadata_t*>(req.data()); size_t expectedSize = req.size(); int result = validate_camera_metadata_structure(metadata, &expectedSize); ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); size_t entryCount = get_camera_metadata_entry_count(metadata); ASSERT_GT(entryCount, 0u); defaultSettings = metadata; }); ASSERT_TRUE(ret.isOk()); uint8_t sensorPixelMode = static_cast<uint8_t>(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION); ASSERT_EQ(::android::OK, defaultSettings.update(ANDROID_SENSOR_PIXEL_MODE, &sensorPixelMode, 1)); const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock(); settings.setToExternal( reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(settingsBuffer)), get_camera_metadata_size(settingsBuffer)); free_camera_metadata(staticMeta); ret = session->close(); ASSERT_TRUE(ret.isOk()); V3_6::HalStreamConfiguration halStreamConfig; bool supportsPartialResults = false; bool useHalBufManager = false; uint32_t partialResultCount = 0; V3_2::Stream previewStream; sp<device::V3_7::ICameraDeviceSession> session3_7; sp<DeviceCb> cb; std::list<PixelFormat> pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16}; for (PixelFormat format : pixelFormats) { configureStreams3_7(name, deviceVersion, mProvider, format, &session3_7, &previewStream, &halStreamConfig, &supportsPartialResults, &partialResultCount, &useHalBufManager, &cb, 0, /*maxResolution*/ true); ASSERT_NE(session3_7, nullptr); std::shared_ptr<ResultMetadataQueue> resultQueue; auto resultQueueRet = session3_7->getCaptureResultMetadataQueue( [&resultQueue](const auto& descriptor) { resultQueue = std::make_shared<ResultMetadataQueue>(descriptor); if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) { ALOGE("%s: HAL returns empty result metadata fmq," " not use it", __func__); resultQueue = nullptr; // Don't use the queue onwards. } }); ASSERT_TRUE(resultQueueRet.isOk()); std::vector<hidl_handle> graphicBuffers; graphicBuffers.reserve(halStreamConfig.streams.size()); ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; outputBuffers.resize(halStreamConfig.streams.size()); InFlightRequest inflightReq = {static_cast<ssize_t>(halStreamConfig.streams.size()), false, supportsPartialResults, partialResultCount, std::unordered_set<std::string>(), resultQueue}; size_t k = 0; for (const auto& halStream : halStreamConfig.streams) { hidl_handle buffer_handle; if (useHalBufManager) { outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, 0, buffer_handle, BufferStatus::OK, nullptr, nullptr}; } else { allocateGraphicBuffer( previewStream.width, previewStream.height, android_convertGralloc1To0Usage(halStream.v3_4.v3_3.v3_2.producerUsage, halStream.v3_4.v3_3.v3_2.consumerUsage), halStream.v3_4.v3_3.v3_2.overrideFormat, &buffer_handle); graphicBuffers.push_back(buffer_handle); outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, bufferId, buffer_handle, BufferStatus::OK, nullptr, nullptr}; bufferId++; } k++; } StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; V3_4::CaptureRequest request3_4; request3_4.v3_2.frameNumber = frameNumber; request3_4.v3_2.fmqSettingsSize = 0; request3_4.v3_2.settings = settings; request3_4.v3_2.inputBuffer = emptyInputBuffer; request3_4.v3_2.outputBuffers = outputBuffers; V3_7::CaptureRequest request3_7; request3_7.v3_4 = request3_4; request3_7.inputWidth = 0; request3_7.inputHeight = 0; { std::unique_lock<std::mutex> l(mLock); mInflightMap.clear(); mInflightMap.add(frameNumber, &inflightReq); } Status stat = Status::INTERNAL_ERROR; uint32_t numRequestProcessed = 0; hidl_vec<BufferCache> cachesToRemove; Return<void> returnStatus = session3_7->processCaptureRequest_3_7( {request3_7}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) { stat = s; numRequestProcessed = n; }); ASSERT_TRUE(returnStatus.isOk()); ASSERT_EQ(Status::OK, stat); ASSERT_EQ(numRequestProcessed, 1u); { std::unique_lock<std::mutex> l(mLock); while (!inflightReq.errorCodeValid && ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) { auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(kStreamBufferTimeoutSec); ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); } ASSERT_FALSE(inflightReq.errorCodeValid); ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); } if (useHalBufManager) { hidl_vec<int32_t> streamIds(halStreamConfig.streams.size()); for (size_t i = 0; i < streamIds.size(); i++) { streamIds[i] = halStreamConfig.streams[i].v3_4.v3_3.v3_2.id; } verifyBuffersReturned(session3_7, streamIds, cb); } ret = session3_7->close(); ASSERT_TRUE(ret.isOk()); } } } // Generate and verify a burst containing alternating sensor sensitivity values TEST_P(CameraHidlTest, processCaptureRequestBurstISO) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); Loading Loading @@ -5539,19 +5737,24 @@ TEST_P(CameraHidlTest, providerDeviceStateNotification) { // static characteristics. Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>& outputStreams, const AvailableStream *threshold) { const AvailableStream* threshold, bool maxResolution) { AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::Y16)}; if (nullptr == staticMeta) { return Status::ILLEGAL_ARGUMENT; } int scalerTag = maxResolution ? ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION : ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS; int depthTag = maxResolution ? ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION : ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS; camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; int foundScalar = find_camera_metadata_ro_entry(staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &scalarEntry); int foundDepth = find_camera_metadata_ro_entry(staticMeta, ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry); int foundScalar = find_camera_metadata_ro_entry(staticMeta, scalerTag, &scalarEntry); int foundDepth = find_camera_metadata_ro_entry(staticMeta, depthTag, &depthEntry); if ((0 != foundScalar || (0 != (scalarEntry.count % 4))) && (0 != foundDepth || (0 != (depthEntry.count % 4)))) { return Status::ILLEGAL_ARGUMENT; Loading Loading @@ -5619,9 +5822,12 @@ Status CameraHidlTest::getMandatoryConcurrentStreams(const camera_metadata_t* st } Status CameraHidlTest::getMaxOutputSizeForFormat(const camera_metadata_t* staticMeta, PixelFormat format, Size* size) { PixelFormat format, Size* size, bool maxResolution) { std::vector<AvailableStream> outputStreams; if (size == nullptr || getAvailableOutputStreams(staticMeta, outputStreams) != Status::OK) { if (size == nullptr || getAvailableOutputStreams(staticMeta, outputStreams, /*threshold*/ nullptr, maxResolution) != Status::OK) { return Status::ILLEGAL_ARGUMENT; } Size maxSize; Loading Loading @@ -6065,6 +6271,148 @@ void CameraHidlTest::createStreamConfiguration( *config3_2 = {streams3_2, configMode}; } // Configure streams void CameraHidlTest::configureStreams3_7( const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider, PixelFormat format, sp<device::V3_7::ICameraDeviceSession>* session3_7 /*out*/, V3_2::Stream* previewStream /*out*/, device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, bool maxResolution) { ASSERT_NE(nullptr, session3_7); ASSERT_NE(nullptr, halStreamConfig); ASSERT_NE(nullptr, previewStream); ASSERT_NE(nullptr, supportsPartialResults); ASSERT_NE(nullptr, partialResultCount); ASSERT_NE(nullptr, useHalBufManager); ASSERT_NE(nullptr, outCb); std::vector<AvailableStream> outputStreams; ::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()); 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); } sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta); 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()); *outCb = cb; sp<device::V3_3::ICameraDeviceSession> session3_3; sp<device::V3_4::ICameraDeviceSession> session3_4; sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, session3_7); ASSERT_NE(nullptr, (*session3_7).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); } outputStreams.clear(); Size maxSize; auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution); ASSERT_EQ(Status::OK, rc); free_camera_metadata(staticMeta); ::android::hardware::hidl_vec<V3_7::Stream> streams3_7(1); streams3_7[0].groupId = -1; streams3_7[0].sensorPixelModesUsed = { CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION}; streams3_7[0].v3_4.bufferSize = 0; streams3_7[0].v3_4.v3_2.id = 0; streams3_7[0].v3_4.v3_2.streamType = StreamType::OUTPUT; streams3_7[0].v3_4.v3_2.width = static_cast<uint32_t>(maxSize.width); streams3_7[0].v3_4.v3_2.height = static_cast<uint32_t>(maxSize.height); streams3_7[0].v3_4.v3_2.format = static_cast<PixelFormat>(format); streams3_7[0].v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ; streams3_7[0].v3_4.v3_2.dataSpace = 0; streams3_7[0].v3_4.v3_2.rotation = StreamRotation::ROTATION_0; ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; config3_7.streams = streams3_7; config3_7.operationMode = StreamConfigurationMode::NORMAL_MODE; config3_7.streamConfigCounter = streamConfigCounter; config3_7.multiResolutionInputImage = false; RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; ret = (*session3_7) ->constructDefaultRequestSettings(reqTemplate, [&config3_7](auto status, const auto& req) { ASSERT_EQ(Status::OK, status); config3_7.sessionParams = req; }); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7); sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr; castDevice3_7(device3_x, deviceVersion, &cameraDevice3_7); ASSERT_NE(cameraDevice3_7, nullptr); bool supported = false; ret = cameraDevice3_7->isStreamCombinationSupported_3_7( config3_7, [&supported](Status s, bool combStatus) { ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s)); if (Status::OK == s) { supported = combStatus; } }); ASSERT_TRUE(ret.isOk()); ASSERT_EQ(supported, true); if (*session3_7 != nullptr) { ret = (*session3_7) ->configureStreams_3_7( config3_7, [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); *halStreamConfig = halConfig; if (*useHalBufManager) { hidl_vec<V3_4::Stream> streams(1); hidl_vec<V3_2::HalStream> halStreams(1); streams[0] = streams3_7[0].v3_4; halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; cb->setCurrentStreamConfig(streams, halStreams); } }); } *previewStream = streams3_7[0].v3_4.v3_2; ASSERT_TRUE(ret.isOk()); } // Configure multiple preview streams using different physical ids. void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, Loading Loading @@ -6362,6 +6710,21 @@ void CameraHidlTest::configureOfflineStillStream(const std::string &name, ASSERT_TRUE(ret.isOk()); } bool CameraHidlTest::isUltraHighResolution(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &scalarEntry); if (rc == 0) { for (uint32_t i = 0; i < scalarEntry.count; i++) { if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR) { return true; } } } return false; } bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; Loading Loading @@ -6590,6 +6953,17 @@ void CameraHidlTest::configureSingleStream( ASSERT_TRUE(ret.isOk()); } void CameraHidlTest::castDevice3_7(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_7::ICameraDevice>* device3_7 /*out*/) { ASSERT_NE(nullptr, device3_7); if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) { auto castResult = device::V3_7::ICameraDevice::castFrom(device); ASSERT_TRUE(castResult.isOk()); *device3_7 = castResult; } } void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice> *device3_5/*out*/) { ASSERT_NE(nullptr, device3_5); Loading Loading @@ -7303,6 +7677,13 @@ void CameraHidlTest::verifyBuffersReturned( cb->waitForBuffersReturned(); } void CameraHidlTest::verifyBuffersReturned(sp<device::V3_7::ICameraDeviceSession> session3_7, hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter) { session3_7->signalStreamFlush(streamIds, /*streamConfigCounter*/ streamConfigCounter); cb->waitForBuffersReturned(); } void CameraHidlTest::verifyLogicalCameraResult(const camera_metadata_t* staticMetadata, const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata) { std::unordered_set<std::string> physicalIds; Loading Loading
camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +394 −13 Original line number Diff line number Diff line Loading @@ -125,6 +125,7 @@ using ::android::hardware::camera::device::V3_4::PhysicalCameraMetadata; using ::android::hardware::camera::metadata::V3_4:: CameraMetadataEnumAndroidSensorInfoColorFilterArrangement; using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag; using ::android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode; using ::android::hardware::camera::provider::V2_4::ICameraProvider; using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination; Loading Loading @@ -767,6 +768,8 @@ public: sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/); void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice> *device3_5/*out*/); void castDevice3_7(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_7::ICameraDevice>* device3_7 /*out*/); void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2, StreamConfigurationMode configMode, ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, Loading @@ -785,6 +788,16 @@ public: sp<DeviceCb> *outCb /*out*/, uint32_t *jpegBufferSize /*out*/, bool *useHalBufManager /*out*/); void configureStreams3_7(const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider, PixelFormat format, sp<device::V3_7::ICameraDeviceSession>* session3_7 /*out*/, V3_2::Stream* previewStream /*out*/, device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, bool maxResolution); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, Loading Loading @@ -846,6 +859,10 @@ public: hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter = 0); void verifyBuffersReturned(sp<device::V3_7::ICameraDeviceSession> session, hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter = 0); void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5, camera_metadata* oldSessionParams, camera_metadata* newSessionParams); Loading @@ -853,12 +870,15 @@ public: static bool isDepthOnly(const camera_metadata_t* staticMeta); static bool isUltraHighResolution(const camera_metadata_t* staticMeta); static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>& outputStreams, const AvailableStream *threshold = nullptr); const AvailableStream* threshold = nullptr, bool maxResolution = false); static Status getMaxOutputSizeForFormat(const camera_metadata_t* staticMeta, PixelFormat format, Size* size); Size* size, bool maxResolution = false); static Status getMandatoryConcurrentStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>* outputStreams); Loading Loading @@ -4841,6 +4861,184 @@ TEST_P(CameraHidlTest, processMultiCaptureRequestPreview) { } } // Generate and verify an ultra high resolution capture request TEST_P(CameraHidlTest, processUltraHighResolutionRequest) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); uint64_t bufferId = 1; uint32_t frameNumber = 1; ::android::hardware::hidl_vec<uint8_t> settings; for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_7) { continue; } std::string version, deviceId; ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId)); camera_metadata_t* staticMeta; Return<void> ret; sp<ICameraDeviceSession> session; openEmptyDeviceSession(name, mProvider, &session, &staticMeta); if (!isUltraHighResolution(staticMeta)) { free_camera_metadata(staticMeta); ret = session->close(); ASSERT_TRUE(ret.isOk()); continue; } android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings; ret = session->constructDefaultRequestSettings( RequestTemplate::STILL_CAPTURE, [&defaultSettings](auto status, const auto& req) mutable { ASSERT_EQ(Status::OK, status); const camera_metadata_t* metadata = reinterpret_cast<const camera_metadata_t*>(req.data()); size_t expectedSize = req.size(); int result = validate_camera_metadata_structure(metadata, &expectedSize); ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); size_t entryCount = get_camera_metadata_entry_count(metadata); ASSERT_GT(entryCount, 0u); defaultSettings = metadata; }); ASSERT_TRUE(ret.isOk()); uint8_t sensorPixelMode = static_cast<uint8_t>(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION); ASSERT_EQ(::android::OK, defaultSettings.update(ANDROID_SENSOR_PIXEL_MODE, &sensorPixelMode, 1)); const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock(); settings.setToExternal( reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(settingsBuffer)), get_camera_metadata_size(settingsBuffer)); free_camera_metadata(staticMeta); ret = session->close(); ASSERT_TRUE(ret.isOk()); V3_6::HalStreamConfiguration halStreamConfig; bool supportsPartialResults = false; bool useHalBufManager = false; uint32_t partialResultCount = 0; V3_2::Stream previewStream; sp<device::V3_7::ICameraDeviceSession> session3_7; sp<DeviceCb> cb; std::list<PixelFormat> pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16}; for (PixelFormat format : pixelFormats) { configureStreams3_7(name, deviceVersion, mProvider, format, &session3_7, &previewStream, &halStreamConfig, &supportsPartialResults, &partialResultCount, &useHalBufManager, &cb, 0, /*maxResolution*/ true); ASSERT_NE(session3_7, nullptr); std::shared_ptr<ResultMetadataQueue> resultQueue; auto resultQueueRet = session3_7->getCaptureResultMetadataQueue( [&resultQueue](const auto& descriptor) { resultQueue = std::make_shared<ResultMetadataQueue>(descriptor); if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) { ALOGE("%s: HAL returns empty result metadata fmq," " not use it", __func__); resultQueue = nullptr; // Don't use the queue onwards. } }); ASSERT_TRUE(resultQueueRet.isOk()); std::vector<hidl_handle> graphicBuffers; graphicBuffers.reserve(halStreamConfig.streams.size()); ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; outputBuffers.resize(halStreamConfig.streams.size()); InFlightRequest inflightReq = {static_cast<ssize_t>(halStreamConfig.streams.size()), false, supportsPartialResults, partialResultCount, std::unordered_set<std::string>(), resultQueue}; size_t k = 0; for (const auto& halStream : halStreamConfig.streams) { hidl_handle buffer_handle; if (useHalBufManager) { outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, 0, buffer_handle, BufferStatus::OK, nullptr, nullptr}; } else { allocateGraphicBuffer( previewStream.width, previewStream.height, android_convertGralloc1To0Usage(halStream.v3_4.v3_3.v3_2.producerUsage, halStream.v3_4.v3_3.v3_2.consumerUsage), halStream.v3_4.v3_3.v3_2.overrideFormat, &buffer_handle); graphicBuffers.push_back(buffer_handle); outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, bufferId, buffer_handle, BufferStatus::OK, nullptr, nullptr}; bufferId++; } k++; } StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; V3_4::CaptureRequest request3_4; request3_4.v3_2.frameNumber = frameNumber; request3_4.v3_2.fmqSettingsSize = 0; request3_4.v3_2.settings = settings; request3_4.v3_2.inputBuffer = emptyInputBuffer; request3_4.v3_2.outputBuffers = outputBuffers; V3_7::CaptureRequest request3_7; request3_7.v3_4 = request3_4; request3_7.inputWidth = 0; request3_7.inputHeight = 0; { std::unique_lock<std::mutex> l(mLock); mInflightMap.clear(); mInflightMap.add(frameNumber, &inflightReq); } Status stat = Status::INTERNAL_ERROR; uint32_t numRequestProcessed = 0; hidl_vec<BufferCache> cachesToRemove; Return<void> returnStatus = session3_7->processCaptureRequest_3_7( {request3_7}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) { stat = s; numRequestProcessed = n; }); ASSERT_TRUE(returnStatus.isOk()); ASSERT_EQ(Status::OK, stat); ASSERT_EQ(numRequestProcessed, 1u); { std::unique_lock<std::mutex> l(mLock); while (!inflightReq.errorCodeValid && ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) { auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(kStreamBufferTimeoutSec); ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); } ASSERT_FALSE(inflightReq.errorCodeValid); ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); } if (useHalBufManager) { hidl_vec<int32_t> streamIds(halStreamConfig.streams.size()); for (size_t i = 0; i < streamIds.size(); i++) { streamIds[i] = halStreamConfig.streams[i].v3_4.v3_3.v3_2.id; } verifyBuffersReturned(session3_7, streamIds, cb); } ret = session3_7->close(); ASSERT_TRUE(ret.isOk()); } } } // Generate and verify a burst containing alternating sensor sensitivity values TEST_P(CameraHidlTest, processCaptureRequestBurstISO) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); Loading Loading @@ -5539,19 +5737,24 @@ TEST_P(CameraHidlTest, providerDeviceStateNotification) { // static characteristics. Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>& outputStreams, const AvailableStream *threshold) { const AvailableStream* threshold, bool maxResolution) { AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::Y16)}; if (nullptr == staticMeta) { return Status::ILLEGAL_ARGUMENT; } int scalerTag = maxResolution ? ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION : ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS; int depthTag = maxResolution ? ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION : ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS; camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; int foundScalar = find_camera_metadata_ro_entry(staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &scalarEntry); int foundDepth = find_camera_metadata_ro_entry(staticMeta, ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry); int foundScalar = find_camera_metadata_ro_entry(staticMeta, scalerTag, &scalarEntry); int foundDepth = find_camera_metadata_ro_entry(staticMeta, depthTag, &depthEntry); if ((0 != foundScalar || (0 != (scalarEntry.count % 4))) && (0 != foundDepth || (0 != (depthEntry.count % 4)))) { return Status::ILLEGAL_ARGUMENT; Loading Loading @@ -5619,9 +5822,12 @@ Status CameraHidlTest::getMandatoryConcurrentStreams(const camera_metadata_t* st } Status CameraHidlTest::getMaxOutputSizeForFormat(const camera_metadata_t* staticMeta, PixelFormat format, Size* size) { PixelFormat format, Size* size, bool maxResolution) { std::vector<AvailableStream> outputStreams; if (size == nullptr || getAvailableOutputStreams(staticMeta, outputStreams) != Status::OK) { if (size == nullptr || getAvailableOutputStreams(staticMeta, outputStreams, /*threshold*/ nullptr, maxResolution) != Status::OK) { return Status::ILLEGAL_ARGUMENT; } Size maxSize; Loading Loading @@ -6065,6 +6271,148 @@ void CameraHidlTest::createStreamConfiguration( *config3_2 = {streams3_2, configMode}; } // Configure streams void CameraHidlTest::configureStreams3_7( const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider, PixelFormat format, sp<device::V3_7::ICameraDeviceSession>* session3_7 /*out*/, V3_2::Stream* previewStream /*out*/, device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, bool maxResolution) { ASSERT_NE(nullptr, session3_7); ASSERT_NE(nullptr, halStreamConfig); ASSERT_NE(nullptr, previewStream); ASSERT_NE(nullptr, supportsPartialResults); ASSERT_NE(nullptr, partialResultCount); ASSERT_NE(nullptr, useHalBufManager); ASSERT_NE(nullptr, outCb); std::vector<AvailableStream> outputStreams; ::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()); 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); } sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta); 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()); *outCb = cb; sp<device::V3_3::ICameraDeviceSession> session3_3; sp<device::V3_4::ICameraDeviceSession> session3_4; sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, session3_7); ASSERT_NE(nullptr, (*session3_7).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); } outputStreams.clear(); Size maxSize; auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution); ASSERT_EQ(Status::OK, rc); free_camera_metadata(staticMeta); ::android::hardware::hidl_vec<V3_7::Stream> streams3_7(1); streams3_7[0].groupId = -1; streams3_7[0].sensorPixelModesUsed = { CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION}; streams3_7[0].v3_4.bufferSize = 0; streams3_7[0].v3_4.v3_2.id = 0; streams3_7[0].v3_4.v3_2.streamType = StreamType::OUTPUT; streams3_7[0].v3_4.v3_2.width = static_cast<uint32_t>(maxSize.width); streams3_7[0].v3_4.v3_2.height = static_cast<uint32_t>(maxSize.height); streams3_7[0].v3_4.v3_2.format = static_cast<PixelFormat>(format); streams3_7[0].v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ; streams3_7[0].v3_4.v3_2.dataSpace = 0; streams3_7[0].v3_4.v3_2.rotation = StreamRotation::ROTATION_0; ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; config3_7.streams = streams3_7; config3_7.operationMode = StreamConfigurationMode::NORMAL_MODE; config3_7.streamConfigCounter = streamConfigCounter; config3_7.multiResolutionInputImage = false; RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; ret = (*session3_7) ->constructDefaultRequestSettings(reqTemplate, [&config3_7](auto status, const auto& req) { ASSERT_EQ(Status::OK, status); config3_7.sessionParams = req; }); ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7); sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr; castDevice3_7(device3_x, deviceVersion, &cameraDevice3_7); ASSERT_NE(cameraDevice3_7, nullptr); bool supported = false; ret = cameraDevice3_7->isStreamCombinationSupported_3_7( config3_7, [&supported](Status s, bool combStatus) { ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s)); if (Status::OK == s) { supported = combStatus; } }); ASSERT_TRUE(ret.isOk()); ASSERT_EQ(supported, true); if (*session3_7 != nullptr) { ret = (*session3_7) ->configureStreams_3_7( config3_7, [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); *halStreamConfig = halConfig; if (*useHalBufManager) { hidl_vec<V3_4::Stream> streams(1); hidl_vec<V3_2::HalStream> halStreams(1); streams[0] = streams3_7[0].v3_4; halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; cb->setCurrentStreamConfig(streams, halStreams); } }); } *previewStream = streams3_7[0].v3_4.v3_2; ASSERT_TRUE(ret.isOk()); } // Configure multiple preview streams using different physical ids. void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, Loading Loading @@ -6362,6 +6710,21 @@ void CameraHidlTest::configureOfflineStillStream(const std::string &name, ASSERT_TRUE(ret.isOk()); } bool CameraHidlTest::isUltraHighResolution(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &scalarEntry); if (rc == 0) { for (uint32_t i = 0; i < scalarEntry.count; i++) { if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR) { return true; } } } return false; } bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; Loading Loading @@ -6590,6 +6953,17 @@ void CameraHidlTest::configureSingleStream( ASSERT_TRUE(ret.isOk()); } void CameraHidlTest::castDevice3_7(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_7::ICameraDevice>* device3_7 /*out*/) { ASSERT_NE(nullptr, device3_7); if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) { auto castResult = device::V3_7::ICameraDevice::castFrom(device); ASSERT_TRUE(castResult.isOk()); *device3_7 = castResult; } } void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice> *device3_5/*out*/) { ASSERT_NE(nullptr, device3_5); Loading Loading @@ -7303,6 +7677,13 @@ void CameraHidlTest::verifyBuffersReturned( cb->waitForBuffersReturned(); } void CameraHidlTest::verifyBuffersReturned(sp<device::V3_7::ICameraDeviceSession> session3_7, hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter) { session3_7->signalStreamFlush(streamIds, /*streamConfigCounter*/ streamConfigCounter); cb->waitForBuffersReturned(); } void CameraHidlTest::verifyLogicalCameraResult(const camera_metadata_t* staticMetadata, const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata) { std::unordered_set<std::string> physicalIds; Loading