diff options
author | Emilian Peev <epeev@google.com> | 2017-11-13 16:03:44 +0000 |
---|---|---|
committer | Emilian Peev <epeev@google.com> | 2017-12-20 10:44:11 +0000 |
commit | e18057b42f1698f33f34d14e86a53934bd337bb8 (patch) | |
tree | a5c56e72bd99d5eded5d585460f6bc07b5b1a508 | |
parent | 220d98c193513c9f0a13e73379a6665b65ce4ee2 (diff) |
Camera: Bump device version to 3.4
Camera devices supporting version 3.4 will be able to receive
session parameters during the stream configuration phase.
Bug: 64450664
Test: Camera CTS
run commandAndExit vts --skip-all-system-status-check
--skip-preconditions --primary-abi-only --module
VtsHalCameraProviderV2_4Target -l INFO
Change-Id: Ifd83bfe0e512fe75b63602b4aba98f4cc1cdeb53
-rw-r--r-- | camera/device/3.2/default/CameraDeviceSession.cpp | 156 | ||||
-rw-r--r-- | camera/device/3.2/default/CameraDeviceSession.h | 6 | ||||
-rw-r--r-- | camera/device/3.3/default/CameraDeviceSession.cpp | 73 | ||||
-rw-r--r-- | camera/device/3.4/Android.bp | 25 | ||||
-rw-r--r-- | camera/device/3.4/ICameraDeviceSession.hal | 74 | ||||
-rw-r--r-- | camera/device/3.4/default/Android.bp | 56 | ||||
-rw-r--r-- | camera/device/3.4/default/CameraDevice.cpp | 67 | ||||
-rw-r--r-- | camera/device/3.4/default/CameraDeviceSession.cpp | 122 | ||||
-rw-r--r-- | camera/device/3.4/default/OWNERS | 6 | ||||
-rw-r--r-- | camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h | 146 | ||||
-rw-r--r-- | camera/device/3.4/default/include/device_v3_4_impl/CameraDevice_3_4.h | 75 | ||||
-rw-r--r-- | camera/device/3.4/types.hal | 46 | ||||
-rw-r--r-- | camera/device/README.md | 8 | ||||
-rw-r--r-- | camera/provider/2.4/default/Android.bp | 12 | ||||
-rw-r--r-- | camera/provider/2.4/default/CameraProvider.cpp | 31 | ||||
-rw-r--r-- | camera/provider/2.4/vts/functional/Android.bp | 1 | ||||
-rw-r--r-- | camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp | 2110 |
17 files changed, 1890 insertions, 1124 deletions
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp index d6a04bc56b..631404e79c 100644 --- a/camera/device/3.2/default/CameraDeviceSession.cpp +++ b/camera/device/3.2/default/CameraDeviceSession.cpp @@ -803,6 +803,89 @@ android_dataspace CameraDeviceSession::mapToLegacyDataspace( return dataSpace; } +bool CameraDeviceSession::preProcessConfigurationLocked( + const StreamConfiguration& requestedConfiguration, + camera3_stream_configuration_t *stream_list /*out*/, + hidl_vec<camera3_stream_t*> *streams /*out*/) { + + if ((stream_list == nullptr) || (streams == nullptr)) { + return false; + } + + stream_list->operation_mode = (uint32_t) requestedConfiguration.operationMode; + stream_list->num_streams = requestedConfiguration.streams.size(); + streams->resize(stream_list->num_streams); + stream_list->streams = streams->data(); + + for (uint32_t i = 0; i < stream_list->num_streams; i++) { + int id = requestedConfiguration.streams[i].id; + + if (mStreamMap.count(id) == 0) { + Camera3Stream stream; + convertFromHidl(requestedConfiguration.streams[i], &stream); + mStreamMap[id] = stream; + mStreamMap[id].data_space = mapToLegacyDataspace( + mStreamMap[id].data_space); + mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{}); + } else { + // width/height/format must not change, but usage/rotation might need to change + if (mStreamMap[id].stream_type != + (int) requestedConfiguration.streams[i].streamType || + mStreamMap[id].width != requestedConfiguration.streams[i].width || + mStreamMap[id].height != requestedConfiguration.streams[i].height || + mStreamMap[id].format != (int) requestedConfiguration.streams[i].format || + mStreamMap[id].data_space != + mapToLegacyDataspace( static_cast<android_dataspace_t> ( + requestedConfiguration.streams[i].dataSpace))) { + ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id); + return false; + } + mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation; + mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage; + } + (*streams)[i] = &mStreamMap[id]; + } + + return true; +} + +void CameraDeviceSession::postProcessConfigurationLocked( + const StreamConfiguration& requestedConfiguration) { + // delete unused streams, note we do this after adding new streams to ensure new stream + // will not have the same address as deleted stream, and HAL has a chance to reference + // the to be deleted stream in configure_streams call + for(auto it = mStreamMap.begin(); it != mStreamMap.end();) { + int id = it->first; + bool found = false; + for (const auto& stream : requestedConfiguration.streams) { + if (id == stream.id) { + found = true; + break; + } + } + if (!found) { + // Unmap all buffers of deleted stream + // in case the configuration call succeeds and HAL + // is able to release the corresponding resources too. + cleanupBuffersLocked(id); + it = mStreamMap.erase(it); + } else { + ++it; + } + } + + // Track video streams + mVideoStreamIds.clear(); + for (const auto& stream : requestedConfiguration.streams) { + if (stream.streamType == StreamType::OUTPUT && + stream.usage & + graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) { + mVideoStreamIds.push_back(stream.id); + } + } + mResultBatcher.setBatchedStreams(mVideoStreamIds); +} + Return<void> CameraDeviceSession::configureStreams( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_cb _hidl_cb) { @@ -840,42 +923,11 @@ Return<void> CameraDeviceSession::configureStreams( return Void(); } - camera3_stream_configuration_t stream_list; + camera3_stream_configuration_t stream_list{}; hidl_vec<camera3_stream_t*> streams; - - stream_list.operation_mode = (uint32_t) requestedConfiguration.operationMode; - stream_list.num_streams = requestedConfiguration.streams.size(); - streams.resize(stream_list.num_streams); - stream_list.streams = streams.data(); - - for (uint32_t i = 0; i < stream_list.num_streams; i++) { - int id = requestedConfiguration.streams[i].id; - - if (mStreamMap.count(id) == 0) { - Camera3Stream stream; - convertFromHidl(requestedConfiguration.streams[i], &stream); - mStreamMap[id] = stream; - mStreamMap[id].data_space = mapToLegacyDataspace( - mStreamMap[id].data_space); - mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{}); - } else { - // width/height/format must not change, but usage/rotation might need to change - if (mStreamMap[id].stream_type != - (int) requestedConfiguration.streams[i].streamType || - mStreamMap[id].width != requestedConfiguration.streams[i].width || - mStreamMap[id].height != requestedConfiguration.streams[i].height || - mStreamMap[id].format != (int) requestedConfiguration.streams[i].format || - mStreamMap[id].data_space != - mapToLegacyDataspace( static_cast<android_dataspace_t> ( - requestedConfiguration.streams[i].dataSpace))) { - ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id); - _hidl_cb(Status::INTERNAL_ERROR, outStreams); - return Void(); - } - mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation; - mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage; - } - streams[i] = &mStreamMap[id]; + if (!preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)) { + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); } ATRACE_BEGIN("camera3->configure_streams"); @@ -885,39 +937,7 @@ Return<void> CameraDeviceSession::configureStreams( // In case Hal returns error most likely it was not able to release // the corresponding resources of the deleted streams. if (ret == OK) { - // delete unused streams, note we do this after adding new streams to ensure new stream - // will not have the same address as deleted stream, and HAL has a chance to reference - // the to be deleted stream in configure_streams call - for(auto it = mStreamMap.begin(); it != mStreamMap.end();) { - int id = it->first; - bool found = false; - for (const auto& stream : requestedConfiguration.streams) { - if (id == stream.id) { - found = true; - break; - } - } - if (!found) { - // Unmap all buffers of deleted stream - // in case the configuration call succeeds and HAL - // is able to release the corresponding resources too. - cleanupBuffersLocked(id); - it = mStreamMap.erase(it); - } else { - ++it; - } - } - - // Track video streams - mVideoStreamIds.clear(); - for (const auto& stream : requestedConfiguration.streams) { - if (stream.streamType == StreamType::OUTPUT && - stream.usage & - graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) { - mVideoStreamIds.push_back(stream.id); - } - } - mResultBatcher.setBatchedStreams(mVideoStreamIds); + postProcessConfigurationLocked(requestedConfiguration); } if (ret == -EINVAL) { diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h index 69e2e2c802..c5a63c8929 100644 --- a/camera/device/3.2/default/CameraDeviceSession.h +++ b/camera/device/3.2/default/CameraDeviceSession.h @@ -112,6 +112,12 @@ protected: Return<Status> flush(); Return<void> close(); + //Helper methods + bool preProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration, + camera3_stream_configuration_t *stream_list /*out*/, + hidl_vec<camera3_stream_t*> *streams /*out*/); + void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration); + protected: // protecting mClosed/mDisconnected/mInitFail diff --git a/camera/device/3.3/default/CameraDeviceSession.cpp b/camera/device/3.3/default/CameraDeviceSession.cpp index f877895ebb..d36e9ed4a0 100644 --- a/camera/device/3.3/default/CameraDeviceSession.cpp +++ b/camera/device/3.3/default/CameraDeviceSession.cpp @@ -77,42 +77,11 @@ Return<void> CameraDeviceSession::configureStreams_3_3( return Void(); } - camera3_stream_configuration_t stream_list; + camera3_stream_configuration_t stream_list{}; hidl_vec<camera3_stream_t*> streams; - - stream_list.operation_mode = (uint32_t) requestedConfiguration.operationMode; - stream_list.num_streams = requestedConfiguration.streams.size(); - streams.resize(stream_list.num_streams); - stream_list.streams = streams.data(); - - for (uint32_t i = 0; i < stream_list.num_streams; i++) { - int id = requestedConfiguration.streams[i].id; - - if (mStreamMap.count(id) == 0) { - Camera3Stream stream; - V3_2::implementation::convertFromHidl(requestedConfiguration.streams[i], &stream); - mStreamMap[id] = stream; - mStreamMap[id].data_space = mapToLegacyDataspace( - mStreamMap[id].data_space); - mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{}); - } else { - // width/height/format must not change, but usage/rotation might need to change - if (mStreamMap[id].stream_type != - (int) requestedConfiguration.streams[i].streamType || - mStreamMap[id].width != requestedConfiguration.streams[i].width || - mStreamMap[id].height != requestedConfiguration.streams[i].height || - mStreamMap[id].format != (int) requestedConfiguration.streams[i].format || - mStreamMap[id].data_space != - mapToLegacyDataspace( static_cast<android_dataspace_t> ( - requestedConfiguration.streams[i].dataSpace))) { - ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id); - _hidl_cb(Status::INTERNAL_ERROR, outStreams); - return Void(); - } - mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation; - mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage; - } - streams[i] = &mStreamMap[id]; + if (!preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)) { + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); } ATRACE_BEGIN("camera3->configure_streams"); @@ -122,39 +91,7 @@ Return<void> CameraDeviceSession::configureStreams_3_3( // In case Hal returns error most likely it was not able to release // the corresponding resources of the deleted streams. if (ret == OK) { - // delete unused streams, note we do this after adding new streams to ensure new stream - // will not have the same address as deleted stream, and HAL has a chance to reference - // the to be deleted stream in configure_streams call - for(auto it = mStreamMap.begin(); it != mStreamMap.end();) { - int id = it->first; - bool found = false; - for (const auto& stream : requestedConfiguration.streams) { - if (id == stream.id) { - found = true; - break; - } - } - if (!found) { - // Unmap all buffers of deleted stream - // in case the configuration call succeeds and HAL - // is able to release the corresponding resources too. - cleanupBuffersLocked(id); - it = mStreamMap.erase(it); - } else { - ++it; - } - } - - // Track video streams - mVideoStreamIds.clear(); - for (const auto& stream : requestedConfiguration.streams) { - if (stream.streamType == V3_2::StreamType::OUTPUT && - stream.usage & - graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) { - mVideoStreamIds.push_back(stream.id); - } - } - mResultBatcher.setBatchedStreams(mVideoStreamIds); + postProcessConfigurationLocked(requestedConfiguration); } if (ret == -EINVAL) { diff --git a/camera/device/3.4/Android.bp b/camera/device/3.4/Android.bp new file mode 100644 index 0000000000..2523fa8289 --- /dev/null +++ b/camera/device/3.4/Android.bp @@ -0,0 +1,25 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.camera.device@3.4", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "types.hal", + "ICameraDeviceSession.hal", + ], + interfaces: [ + "android.hardware.camera.common@1.0", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", + "android.hardware.graphics.common@1.0", + "android.hidl.base@1.0", + ], + types: [ + "StreamConfiguration", + ], + gen_java: false, +} + diff --git a/camera/device/3.4/ICameraDeviceSession.hal b/camera/device/3.4/ICameraDeviceSession.hal new file mode 100644 index 0000000000..e5693b26d1 --- /dev/null +++ b/camera/device/3.4/ICameraDeviceSession.hal @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.camera.device@3.4; + +import android.hardware.camera.common@1.0::Status; +import @3.3::ICameraDeviceSession; +import @3.3::HalStreamConfiguration; + +/** + * Camera device active session interface. + * + * Obtained via ICameraDevice::open(), this interface contains the methods to + * configure and request captures from an active camera device. + */ +interface ICameraDeviceSession extends @3.3::ICameraDeviceSession { + + /** + * configureStreams_3_4: + * + * Identical to @3.3::ICameraDeviceSession.configureStreams, except that: + * + * - The requested configuration includes session parameters. + * + * @return Status Status code for the operation, one of: + * OK: + * On successful stream configuration. + * INTERNAL_ERROR: + * If there has been a fatal error and the device is no longer + * operational. Only close() can be called successfully by the + * framework after this error is returned. + * ILLEGAL_ARGUMENT: + * If the requested stream configuration is invalid. Some examples + * of invalid stream configurations include: + * - Including more than 1 INPUT stream + * - Not including any OUTPUT streams + * - Including streams with unsupported formats, or an unsupported + * size for that format. + * - Including too many output streams of a certain format. + * - Unsupported rotation configuration + * - Stream sizes/formats don't satisfy the + * camera3_stream_configuration_t->operation_mode requirements + * for non-NORMAL mode, or the requested operation_mode is not + * supported by the HAL. + * - Unsupported usage flag + * The camera service cannot filter out all possible illegal stream + * configurations, since some devices may support more simultaneous + * streams or larger stream resolutions than the minimum required + * for a given camera device hardware level. The HAL must return an + * ILLEGAL_ARGUMENT for any unsupported stream set, and then be + * ready to accept a future valid stream configuration in a later + * configureStreams call. + * @return halConfiguration The stream parameters desired by the HAL for + * each stream, including maximum buffers, the usage flags, and the + * override format. + */ + configureStreams_3_4(@3.4::StreamConfiguration requestedConfiguration) + generates (Status status, + @3.3::HalStreamConfiguration halConfiguration); + +}; diff --git a/camera/device/3.4/default/Android.bp b/camera/device/3.4/default/Android.bp new file mode 100644 index 0000000000..c0ce838bae --- /dev/null +++ b/camera/device/3.4/default/Android.bp @@ -0,0 +1,56 @@ +// +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_library_headers { + name: "camera.device@3.4-impl_headers", + vendor: true, + export_include_dirs: ["include/device_v3_4_impl"], +} + +cc_library_shared { + name: "camera.device@3.4-impl", + defaults: ["hidl_defaults"], + proprietary: true, + vendor: true, + srcs: [ + "CameraDevice.cpp", + "CameraDeviceSession.cpp", + ], + shared_libs: [ + "libhidlbase", + "libhidltransport", + "libutils", + "libcutils", + "camera.device@3.2-impl", + "camera.device@3.3-impl", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", + "android.hardware.camera.provider@2.4", + "android.hardware.graphics.mapper@2.0", + "liblog", + "libhardware", + "libcamera_metadata", + "libfmq", + ], + static_libs: [ + "android.hardware.camera.common@1.0-helper", + ], + local_include_dirs: ["include/device_v3_4_impl"], + export_shared_lib_headers: [ + "libfmq", + ], +} diff --git a/camera/device/3.4/default/CameraDevice.cpp b/camera/device/3.4/default/CameraDevice.cpp new file mode 100644 index 0000000000..d73833a9c3 --- /dev/null +++ b/camera/device/3.4/default/CameraDevice.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CamDev@3.4-impl" +#include <log/log.h> + +#include <utils/Vector.h> +#include <utils/Trace.h> +#include "CameraDevice_3_4.h" +#include <include/convert.h> + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_4 { +namespace implementation { + +using ::android::hardware::camera::common::V1_0::Status; +using namespace ::android::hardware::camera::device; + +CameraDevice::CameraDevice( + sp<CameraModule> module, const std::string& cameraId, + const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames) : + V3_2::implementation::CameraDevice(module, cameraId, cameraDeviceNames) { +} + +CameraDevice::~CameraDevice() { +} + +sp<V3_2::implementation::CameraDeviceSession> CameraDevice::createSession(camera3_device_t* device, + const camera_metadata_t* deviceInfo, + const sp<V3_2::ICameraDeviceCallback>& callback) { + sp<CameraDeviceSession> session = new CameraDeviceSession(device, deviceInfo, callback); + IF_ALOGV() { + session->getInterface()->interfaceChain([]( + ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { + ALOGV("Session interface chain:"); + for (auto iface : interfaceChain) { + ALOGV(" %s", iface.c_str()); + } + }); + } + return session; +} + +// End of methods from ::android::hardware::camera::device::V3_2::ICameraDevice. + +} // namespace implementation +} // namespace V3_4 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp new file mode 100644 index 0000000000..0ae470f2bb --- /dev/null +++ b/camera/device/3.4/default/CameraDeviceSession.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CamDevSession@3.4-impl" +#include <android/log.h> + +#include <set> +#include <utils/Trace.h> +#include <hardware/gralloc.h> +#include <hardware/gralloc1.h> +#include "CameraDeviceSession.h" + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_4 { +namespace implementation { + +CameraDeviceSession::CameraDeviceSession( + camera3_device_t* device, + const camera_metadata_t* deviceInfo, + const sp<V3_2::ICameraDeviceCallback>& callback) : + V3_3::implementation::CameraDeviceSession(device, deviceInfo, callback) { +} + +CameraDeviceSession::~CameraDeviceSession() { +} + +Return<void> CameraDeviceSession::configureStreams_3_4( + const V3_4::StreamConfiguration& requestedConfiguration, + ICameraDeviceSession::configureStreams_3_3_cb _hidl_cb) { + Status status = initStatus(); + HalStreamConfiguration outStreams; + + // hold the inflight lock for entire configureStreams scope since there must not be any + // inflight request/results during stream configuration. + Mutex::Autolock _l(mInflightLock); + if (!mInflightBuffers.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!", + __FUNCTION__, mInflightBuffers.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + + if (!mInflightAETriggerOverrides.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight" + " trigger overrides!", __FUNCTION__, + mInflightAETriggerOverrides.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + + if (!mInflightRawBoostPresent.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight" + " boost overrides!", __FUNCTION__, + mInflightRawBoostPresent.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + + if (status != Status::OK) { + _hidl_cb(status, outStreams); + return Void(); + } + + const camera_metadata_t *paramBuffer = nullptr; + if (0 < requestedConfiguration.sessionParams.size()) { + ::android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams; + V3_2::implementation::convertFromHidl(requestedConfiguration.sessionParams, ¶mBuffer); + } + + camera3_stream_configuration_t stream_list{}; + hidl_vec<camera3_stream_t*> streams; + stream_list.session_parameters = paramBuffer; + if (!preProcessConfigurationLocked(requestedConfiguration.v3_2, &stream_list, &streams)) { + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + + ATRACE_BEGIN("camera3->configure_streams"); + status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list); + ATRACE_END(); + + // In case Hal returns error most likely it was not able to release + // the corresponding resources of the deleted streams. + if (ret == OK) { + postProcessConfigurationLocked(requestedConfiguration.v3_2); + } + + if (ret == -EINVAL) { + status = Status::ILLEGAL_ARGUMENT; + } else if (ret != OK) { + status = Status::INTERNAL_ERROR; + } else { + V3_3::implementation::convertToHidl(stream_list, &outStreams); + mFirstRequest = true; + } + + _hidl_cb(status, outStreams); + return Void(); +} + +} // namespace implementation +} // namespace V3_4 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android diff --git a/camera/device/3.4/default/OWNERS b/camera/device/3.4/default/OWNERS new file mode 100644 index 0000000000..18acfee145 --- /dev/null +++ b/camera/device/3.4/default/OWNERS @@ -0,0 +1,6 @@ +cychen@google.com +epeev@google.com +etalvala@google.com +shuzhenwang@google.com +yinchiayeh@google.com +zhijunhe@google.com diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h new file mode 100644 index 0000000000..bff17346ed --- /dev/null +++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_CAMERADEVICE3SESSION_H +#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_CAMERADEVICE3SESSION_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.4/ICameraDeviceSession.h> +#include <../../3.3/default/CameraDeviceSession.h> +#include <../../3.3/default/include/convert.h> +#include <fmq/MessageQueue.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> +#include <deque> +#include <map> +#include <unordered_map> +#include "CameraMetadata.h" +#include "HandleImporter.h" +#include "hardware/camera3.h" +#include "hardware/camera_common.h" +#include "utils/Mutex.h" + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_4 { +namespace implementation { + +using namespace ::android::hardware::camera::device; +using ::android::hardware::camera::device::V3_2::CaptureRequest; +using ::android::hardware::camera::device::V3_2::StreamConfiguration; +using ::android::hardware::camera::device::V3_3::HalStreamConfiguration; +using ::android::hardware::camera::device::V3_4::ICameraDeviceSession; +using ::android::hardware::camera::common::V1_0::Status; +using ::android::hardware::camera::common::V1_0::helper::HandleImporter; +using ::android::hardware::kSynchronizedReadWrite; +using ::android::hardware::MessageQueue; +using ::android::hardware::MQDescriptorSync; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; +using ::android::Mutex; + +struct CameraDeviceSession : public V3_3::implementation::CameraDeviceSession { + + CameraDeviceSession(camera3_device_t*, + const camera_metadata_t* deviceInfo, + const sp<V3_2::ICameraDeviceCallback>&); + virtual ~CameraDeviceSession(); + + virtual sp<V3_2::ICameraDeviceSession> getInterface() override { + return new TrampolineSessionInterface_3_4(this); + } + +protected: + // Methods from v3.3 and earlier will trampoline to inherited implementation + + // New methods for v3.4 + + Return<void> configureStreams_3_4( + const V3_4::StreamConfiguration& requestedConfiguration, + ICameraDeviceSession::configureStreams_3_3_cb _hidl_cb); +private: + + struct TrampolineSessionInterface_3_4 : public ICameraDeviceSession { + TrampolineSessionInterface_3_4(sp<CameraDeviceSession> parent) : + mParent(parent) {} + + virtual Return<void> constructDefaultRequestSettings( + V3_2::RequestTemplate type, + V3_3::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override { + return mParent->constructDefaultRequestSettings(type, _hidl_cb); + } + + virtual Return<void> configureStreams( + const StreamConfiguration& requestedConfiguration, + V3_3::ICameraDeviceSession::configureStreams_cb _hidl_cb) override { + return mParent->configureStreams(requestedConfiguration, _hidl_cb); + } + + virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests, + const hidl_vec<V3_2::BufferCache>& cachesToRemove, + V3_3::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override { + return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb); + } + + virtual Return<void> getCaptureRequestMetadataQueue( + V3_3::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override { + return mParent->getCaptureRequestMetadataQueue(_hidl_cb); + } + + virtual Return<void> getCaptureResultMetadataQueue( + V3_3::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override { + return mParent->getCaptureResultMetadataQueue(_hidl_cb); + } + + virtual Return<Status> flush() override { + return mParent->flush(); + } + + virtual Return<void> close() override { + return mParent->close(); + } + + virtual Return<void> configureStreams_3_3( + const StreamConfiguration& requestedConfiguration, + configureStreams_3_3_cb _hidl_cb) override { + return mParent->configureStreams_3_3(requestedConfiguration, _hidl_cb); + } + + virtual Return<void> configureStreams_3_4( + const V3_4::StreamConfiguration& requestedConfiguration, + configureStreams_3_3_cb _hidl_cb) override { + return mParent->configureStreams_3_4(requestedConfiguration, _hidl_cb); + } + + private: + sp<CameraDeviceSession> mParent; + }; +}; + +} // namespace implementation +} // namespace V3_4 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_CAMERADEVICE3SESSION_H diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDevice_3_4.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDevice_3_4.h new file mode 100644 index 0000000000..95ee20e35d --- /dev/null +++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDevice_3_4.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_CAMERADEVICE_H +#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_CAMERADEVICE_H + +#include "utils/Mutex.h" +#include "CameraModule.h" +#include "CameraMetadata.h" +#include "CameraDeviceSession.h" +#include <../../3.2/default/CameraDevice_3_2.h> + +#include <android/hardware/camera/device/3.2/ICameraDevice.h> +#include <hidl/Status.h> +#include <hidl/MQDescriptor.h> + +namespace android { +namespace hardware { +namespace camera { +namespace device { +namespace V3_4 { +namespace implementation { + +using namespace ::android::hardware::camera::device; +using ::android::hardware::camera::common::V1_0::helper::CameraModule; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; + +/* + * The camera device HAL implementation is opened lazily (via the open call) + */ +struct CameraDevice : public V3_2::implementation::CameraDevice { + + // Called by provider HAL. + // Provider HAL must ensure the uniqueness of CameraDevice object per cameraId, or there could + // be multiple CameraDevice trying to access the same physical camera. Also, provider will have + // to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying + // camera is detached. + // Delegates nearly all work to CameraDevice_3_2 + CameraDevice(sp<CameraModule> module, + const std::string& cameraId, + const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames); + ~CameraDevice(); + +protected: + virtual sp<V3_2::implementation::CameraDeviceSession> createSession(camera3_device_t*, + const camera_metadata_t* deviceInfo, + const sp<V3_2::ICameraDeviceCallback>&) override; + +}; + +} // namespace implementation +} // namespace V3_4 +} // namespace device +} // namespace camera +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_CAMERADEVICE_H diff --git a/camera/device/3.4/types.hal b/camera/device/3.4/types.hal new file mode 100644 index 0000000000..c822717c3c --- /dev/null +++ b/camera/device/3.4/types.hal @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.camera.device@3.4; + +import @3.2::StreamConfiguration; +import @3.2::types; + +/** + * StreamConfiguration: + * + * Identical to @3.2::StreamConfiguration, except that it contains session parameters. + */ +struct StreamConfiguration { + /** + * The definition of StreamConfiguration from the prior version. + */ + @3.2::StreamConfiguration v3_2; + + /** + * Session wide camera parameters. + * + * The session parameters contain the initial values of any request keys that were + * made available via ANDROID_REQUEST_AVAILABLE_SESSION_KEYS. The Hal implementation + * can advertise any settings that can potentially introduce unexpected delays when + * their value changes during active process requests. Typical examples are + * parameters that trigger time-consuming HW re-configurations or internal camera + * pipeline updates. The field is optional, clients can choose to ignore it and avoid + * including any initial settings. If parameters are present, then hal must examine + * their values and configure the internal camera pipeline accordingly. + */ + CameraMetadata sessionParams; +}; diff --git a/camera/device/README.md b/camera/device/README.md index 9f607816d8..3709cb89ba 100644 --- a/camera/device/README.md +++ b/camera/device/README.md @@ -87,3 +87,11 @@ A minor revision to the ICameraDevice.hal@3.2. supported in the legacy camera HAL. Added in Android 8.1. + +### ICameraDevice.hal@3.4: + +A minor revision to the ICameraDevice.hal@3.3. + + - Adds support for session parameters during stream configuration. + +Added in Android 9 diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp index c0b35912f7..99c3e92810 100644 --- a/camera/provider/2.4/default/Android.bp +++ b/camera/provider/2.4/default/Android.bp @@ -12,9 +12,11 @@ cc_library_shared { "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2", "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", "camera.device@1.0-impl", "camera.device@3.2-impl", "camera.device@3.3-impl", + "camera.device@3.4-impl", "android.hardware.camera.provider@2.4", "android.hardware.camera.common@1.0", "android.hardware.graphics.mapper@2.0", @@ -22,11 +24,14 @@ cc_library_shared { "android.hidl.memory@1.0", "liblog", "libhardware", - "libcamera_metadata" + "libcamera_metadata", + ], + header_libs: [ + "camera.device@3.4-impl_headers", ], static_libs: [ - "android.hardware.camera.common@1.0-helper" - ] + "android.hardware.camera.common@1.0-helper", + ], } cc_binary { @@ -46,6 +51,7 @@ cc_binary { "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2", "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", "android.hardware.camera.provider@2.4", "android.hardware.camera.common@1.0", ], diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp index d50168a20b..ed974a57d0 100644 --- a/camera/provider/2.4/default/CameraProvider.cpp +++ b/camera/provider/2.4/default/CameraProvider.cpp @@ -21,6 +21,7 @@ #include "CameraProvider.h" #include "CameraDevice_1_0.h" #include "CameraDevice_3_3.h" +#include "CameraDevice_3_4.h" #include <cutils/properties.h> #include <string.h> #include <utils/Trace.h> @@ -39,6 +40,7 @@ const char *kLegacyProviderName = "legacy/0"; const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)"); const char *kHAL3_2 = "3.2"; const char *kHAL3_3 = "3.3"; +const char *kHAL3_4 = "3.4"; const char *kHAL1_0 = "1.0"; const int kMaxCameraDeviceNameLen = 128; const int kMaxCameraIdLen = 16; @@ -159,12 +161,16 @@ std::string CameraProvider::getHidlDeviceName( if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 && deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 && deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 && - deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) { + deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 && + deviceVersion != CAMERA_DEVICE_API_VERSION_3_5) { return hidl_string(""); } bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0; int versionMajor = isV1 ? 1 : 3; int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion; + if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) { + versionMinor = 4; + } char deviceName[kMaxCameraDeviceNameLen]; snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s", versionMajor, versionMinor, cameraId.c_str()); @@ -220,7 +226,8 @@ bool CameraProvider::initialize() { break; default: ALOGW("Unknown minor camera device HAL version %d in property " - "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", mPreferredHal3MinorVersion); + "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", + mPreferredHal3MinorVersion); mPreferredHal3MinorVersion = 3; } @@ -292,6 +299,7 @@ int CameraProvider::checkCameraVersion(int id, camera_info info) { case CAMERA_DEVICE_API_VERSION_3_2: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_4: + case CAMERA_DEVICE_API_VERSION_3_5: // in support break; case CAMERA_DEVICE_API_VERSION_2_0: @@ -480,10 +488,27 @@ Return<void> CameraProvider::getCameraDeviceInterface_V3_x( return Void(); } + sp<android::hardware::camera::device::V3_2::ICameraDevice> device; + if (deviceVersion == kHAL3_4) { + ALOGV("Constructing v3.4 camera device"); + sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl = + new android::hardware::camera::device::V3_4::implementation::CameraDevice( + mModule, cameraId, mCameraDeviceNames); + if (deviceImpl == nullptr || deviceImpl->isInitFailed()) { + ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str()); + device = nullptr; + _hidl_cb(Status::INTERNAL_ERROR, nullptr); + return Void(); + } + + device = deviceImpl; + _hidl_cb (Status::OK, device); + return Void(); + } + // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default // to the newest possible Treble HAL revision, but allow for override if needed via // system property. - sp<android::hardware::camera::device::V3_2::ICameraDevice> device; switch (mPreferredHal3MinorVersion) { case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2 ALOGV("Constructing v3.2 camera device"); diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp index 81d3de1566..7bc42539b3 100644 --- a/camera/provider/2.4/vts/functional/Android.bp +++ b/camera/provider/2.4/vts/functional/Android.bp @@ -35,6 +35,7 @@ cc_test { "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2", "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", "android.hardware.camera.provider@2.4", "android.hardware.graphics.common@1.0", "android.hardware.graphics.mapper@2.0", diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index e4cf9af273..c8926c48fa 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -27,6 +27,7 @@ #include <android/hardware/camera/device/1.0/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.4/ICameraDeviceSession.h> #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <binder/MemoryHeapBase.h> @@ -128,9 +129,11 @@ struct AvailableZSLInputOutput { namespace { // "device@<version>/legacy/<id>" const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)"; + const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304; const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303; const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302; const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100; + const char *kHAL3_4 = "3.4"; const char *kHAL3_3 = "3.3"; const char *kHAL3_2 = "3.2"; const char *kHAL1_0 = "1.0"; @@ -164,7 +167,9 @@ namespace { return -1; } - if (version.compare(kHAL3_3) == 0) { + if (version.compare(kHAL3_4) == 0) { + return CAMERA_DEVICE_API_VERSION_3_4; + } else if (version.compare(kHAL3_3) == 0) { return CAMERA_DEVICE_API_VERSION_3_3; } else if (version.compare(kHAL3_2) == 0) { return CAMERA_DEVICE_API_VERSION_3_2; @@ -611,9 +616,11 @@ public: void openEmptyDeviceSession(const std::string &name, sp<ICameraProvider> provider, sp<ICameraDeviceSession> *session /*out*/, - sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/, camera_metadata_t **staticMeta /*out*/); - void configurePreviewStream(const std::string &name, + void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion, + sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/, + sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/); + void configurePreviewStream(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, sp<ICameraDeviceSession> *session /*out*/, @@ -1100,6 +1107,7 @@ TEST_F(CameraHidlTest, getCameraDeviceInterface) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_2: { Return<void> ret; @@ -1140,6 +1148,7 @@ TEST_F(CameraHidlTest, getResourceCost) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_2: { ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; @@ -1879,6 +1888,7 @@ TEST_F(CameraHidlTest, getCameraCharacteristics) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_2: { ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; @@ -1943,6 +1953,7 @@ TEST_F(CameraHidlTest, setTorchMode) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_2: { ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; @@ -2067,6 +2078,7 @@ TEST_F(CameraHidlTest, dumpState) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_2: { ::android::sp<ICameraDevice> device3_x; @@ -2130,6 +2142,7 @@ TEST_F(CameraHidlTest, openClose) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_2: { ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; @@ -2152,12 +2165,14 @@ TEST_F(CameraHidlTest, openClose) { session = newSession; }); ASSERT_TRUE(ret.isOk()); - // Ensure that a device labeling itself as 3.3 can have its session interface cast - // to the 3.3 interface, and that lower versions can't be cast to it. - auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session); - ASSERT_TRUE(castResult.isOk()); - sp<device::V3_3::ICameraDeviceSession> sessionV3_3 = castResult; - if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) { + // Ensure that a device labeling itself as 3.3/3.4 can have its session interface + // cast the 3.3/3.4 interface, and that lower versions can't be cast to it. + sp<device::V3_3::ICameraDeviceSession> sessionV3_3; + sp<device::V3_4::ICameraDeviceSession> sessionV3_4; + castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4); + 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 { ASSERT_TRUE(sessionV3_3.get() == nullptr); @@ -2213,6 +2228,7 @@ TEST_F(CameraHidlTest, constructDefaultRequestSettings) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: case CAMERA_DEVICE_API_VERSION_3_3: case CAMERA_DEVICE_API_VERSION_3_2: { ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; @@ -2301,66 +2317,69 @@ TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - camera_metadata_t* staticMeta; - Return<void> ret; - sp<ICameraDeviceSession> session; - sp<device::V3_3::ICameraDeviceSession> session3_3; - openEmptyDeviceSession(name, mProvider, - &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/); - - outputStreams.clear(); - ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); - ASSERT_NE(0u, outputStreams.size()); - - int32_t streamId = 0; - for (auto& it : outputStreams) { - Stream stream = {streamId, - StreamType::OUTPUT, - static_cast<uint32_t>(it.width), - static_cast<uint32_t>(it.height), - static_cast<PixelFormat>(it.format), - GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, - 0, - StreamRotation::ROTATION_0}; - ::android::hardware::hidl_vec<Stream> streams = {stream}; - StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [streamId](Status s, HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(1u, halConfig.streams.size()); - ASSERT_EQ(halConfig.streams[0].id, streamId); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(1u, halConfig.streams.size()); - ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); - }); - } - ASSERT_TRUE(ret.isOk()); - streamId++; - } - - free_camera_metadata(staticMeta); - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } + + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + openEmptyDeviceSession(name, mProvider, + &session /*out*/, &staticMeta /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4); + + outputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); + ASSERT_NE(0u, outputStreams.size()); + + int32_t streamId = 0; + for (auto& it : outputStreams) { + Stream stream = {streamId, + StreamType::OUTPUT, + static_cast<uint32_t>(it.width), + static_cast<uint32_t>(it.height), + static_cast<PixelFormat>(it.format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec<Stream> streams = {stream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); + }); + } else { + ret = session->configureStreams(config.v3_2, + [streamId](Status s, HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].id, streamId); + }); } - break; + ASSERT_TRUE(ret.isOk()); + streamId++; } + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -2371,132 +2390,148 @@ TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - camera_metadata_t* staticMeta; - Return<void> ret; - sp<ICameraDeviceSession> session; - sp<device::V3_3::ICameraDeviceSession> session3_3; - openEmptyDeviceSession(name, mProvider, - &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/); - - outputStreams.clear(); - ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); - ASSERT_NE(0u, outputStreams.size()); - - int32_t streamId = 0; - Stream stream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(0), - static_cast<uint32_t>(0), - static_cast<PixelFormat>(outputStreams[0].format), - GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, - 0, - StreamRotation::ROTATION_0}; - ::android::hardware::hidl_vec<Stream> streams = {stream}; - StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE}; - if(session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration) { - ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || - (Status::INTERNAL_ERROR == s)); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } + + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4); + + outputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); + ASSERT_NE(0u, outputStreams.size()); + + int32_t streamId = 0; + Stream stream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(0), + static_cast<uint32_t>(0), + static_cast<PixelFormat>(outputStreams[0].format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec<Stream> streams = {stream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if(session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } else if(session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } + ASSERT_TRUE(ret.isOk()); + + stream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(UINT32_MAX), + static_cast<uint32_t>(UINT32_MAX), + static_cast<PixelFormat>(outputStreams[0].format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if(session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, [](Status s, + device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if(session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, [](Status s, + device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else { + ret = session->configureStreams(config.v3_2, [](Status s, + HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } + ASSERT_TRUE(ret.isOk()); + + for (auto& it : outputStreams) { + stream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(it.width), + static_cast<uint32_t>(it.height), + static_cast<PixelFormat>(UINT32_MAX), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if(session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); }); - } else { - ret = session3_3->configureStreams_3_3(config, + } else if(session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, [](Status s, device::V3_3::HalStreamConfiguration) { - ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || - (Status::INTERNAL_ERROR == s)); + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); }); - } - ASSERT_TRUE(ret.isOk()); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } + ASSERT_TRUE(ret.isOk()); - stream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(UINT32_MAX), - static_cast<uint32_t>(UINT32_MAX), - static_cast<PixelFormat>(outputStreams[0].format), - GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, - 0, - StreamRotation::ROTATION_0}; - streams[0] = stream; - config = {streams, StreamConfigurationMode::NORMAL_MODE}; - if(session3_3 == nullptr) { - ret = session->configureStreams(config, [](Status s, - HalStreamConfiguration) { + stream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(it.width), + static_cast<uint32_t>(it.height), + static_cast<PixelFormat>(it.format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + static_cast<StreamRotation>(UINT32_MAX)}; + streams[0] = stream; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if(session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); }); - } else { - ret = session3_3->configureStreams_3_3(config, [](Status s, - device::V3_3::HalStreamConfiguration) { + } else if(session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration) { ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); }); - } - ASSERT_TRUE(ret.isOk()); - - for (auto& it : outputStreams) { - stream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(it.width), - static_cast<uint32_t>(it.height), - static_cast<PixelFormat>(UINT32_MAX), - GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, - 0, - StreamRotation::ROTATION_0}; - streams[0] = stream; - config = {streams, StreamConfigurationMode::NORMAL_MODE}; - if(session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } - ASSERT_TRUE(ret.isOk()); - - stream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(it.width), - static_cast<uint32_t>(it.height), - static_cast<PixelFormat>(it.format), - GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, - 0, - static_cast<StreamRotation>(UINT32_MAX)}; - streams[0] = stream; - config = {streams, StreamConfigurationMode::NORMAL_MODE}; - if(session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } - ASSERT_TRUE(ret.isOk()); - } - - free_camera_metadata(staticMeta); - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); } - break; + ASSERT_TRUE(ret.isOk()); } + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -2509,107 +2544,207 @@ TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - camera_metadata_t* staticMeta; - Return<void> ret; - sp<ICameraDeviceSession> session; - sp<device::V3_3::ICameraDeviceSession> session3_3; - openEmptyDeviceSession(name, mProvider, - &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } - Status rc = isZSLModeAvailable(staticMeta); - if (Status::METHOD_NOT_SUPPORTED == rc) { - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - continue; - } - ASSERT_EQ(Status::OK, rc); - - inputStreams.clear(); - ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams)); - ASSERT_NE(0u, inputStreams.size()); - - inputOutputMap.clear(); - ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap)); - ASSERT_NE(0u, inputOutputMap.size()); - - int32_t streamId = 0; - for (auto& inputIter : inputOutputMap) { - AvailableStream input; - ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat, - input)); - ASSERT_NE(0u, inputStreams.size()); - - AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, - inputIter.outputFormat}; - std::vector<AvailableStream> outputStreams; - ASSERT_EQ(Status::OK, - getAvailableOutputStreams(staticMeta, outputStreams, - &outputThreshold)); - for (auto& outputIter : outputStreams) { - Stream zslStream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(input.width), - static_cast<uint32_t>(input.height), - static_cast<PixelFormat>(input.format), - GRALLOC_USAGE_HW_CAMERA_ZSL, - 0, - StreamRotation::ROTATION_0}; - Stream inputStream = {streamId++, - StreamType::INPUT, - static_cast<uint32_t>(input.width), - static_cast<uint32_t>(input.height), - static_cast<PixelFormat>(input.format), - 0, - 0, - StreamRotation::ROTATION_0}; - Stream outputStream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(outputIter.width), - static_cast<uint32_t>(outputIter.height), - static_cast<PixelFormat>(outputIter.format), - GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, - 0, - StreamRotation::ROTATION_0}; - - ::android::hardware::hidl_vec<Stream> streams = {inputStream, zslStream, - outputStream}; - StreamConfiguration config = {streams, - StreamConfigurationMode::NORMAL_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(3u, halConfig.streams.size()); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(3u, halConfig.streams.size()); - }); - } - ASSERT_TRUE(ret.isOk()); - } - } + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4); - free_camera_metadata(staticMeta); - ret = session->close(); + Status rc = isZSLModeAvailable(staticMeta); + if (Status::METHOD_NOT_SUPPORTED == rc) { + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + ASSERT_EQ(Status::OK, rc); + + inputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams)); + ASSERT_NE(0u, inputStreams.size()); + + inputOutputMap.clear(); + ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap)); + ASSERT_NE(0u, inputOutputMap.size()); + + int32_t streamId = 0; + for (auto& inputIter : inputOutputMap) { + AvailableStream input; + ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat, + input)); + ASSERT_NE(0u, inputStreams.size()); + + AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, + inputIter.outputFormat}; + std::vector<AvailableStream> outputStreams; + ASSERT_EQ(Status::OK, + getAvailableOutputStreams(staticMeta, outputStreams, + &outputThreshold)); + for (auto& outputIter : outputStreams) { + Stream zslStream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(input.width), + static_cast<uint32_t>(input.height), + static_cast<PixelFormat>(input.format), + GRALLOC_USAGE_HW_CAMERA_ZSL, + 0, + StreamRotation::ROTATION_0}; + Stream inputStream = {streamId++, + StreamType::INPUT, + static_cast<uint32_t>(input.width), + static_cast<uint32_t>(input.height), + static_cast<PixelFormat>(input.format), + 0, + 0, + StreamRotation::ROTATION_0}; + Stream outputStream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(outputIter.width), + static_cast<uint32_t>(outputIter.height), + static_cast<PixelFormat>(outputIter.format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + + ::android::hardware::hidl_vec<Stream> streams = {inputStream, zslStream, + outputStream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(3u, halConfig.streams.size()); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(3u, halConfig.streams.size()); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(3u, halConfig.streams.size()); + }); + } ASSERT_TRUE(ret.isOk()); } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; } + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + } +} + +// Check wehether session parameters are supported. If Hal support for them +// exist, then try to configure a preview stream using them. +TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) { + hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); + std::vector<AvailableStream> outputPreviewStreams; + AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, + static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) { + continue; + } + + camera_metadata_t* staticMetaBuffer; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4); + ASSERT_NE(session3_4, nullptr); + + const android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta( + staticMetaBuffer); + camera_metadata_ro_entry availableSessionKeys = staticMeta.find( + ANDROID_REQUEST_AVAILABLE_SESSION_KEYS); + if (availableSessionKeys.count == 0) { + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + + android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings; + ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW, + [&previewRequestSettings] (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); + previewRequestSettings = metadata; + }); + ASSERT_TRUE(ret.isOk()); + const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings = + previewRequestSettings; + android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams; + for (size_t i = 0; i < availableSessionKeys.count; i++) { + camera_metadata_ro_entry entry = constSettings.find(availableSessionKeys.data.i32[i]); + if (entry.count > 0) { + sessionParams.update(entry); + } + } + if (sessionParams.isEmpty()) { + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams, + &previewThreshold)); + ASSERT_NE(0u, outputPreviewStreams.size()); + + Stream previewStream = {0, + 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}; + ::android::hardware::hidl_vec<Stream> streams = {previewStream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + const camera_metadata_t *sessionParamsBuffer = sessionParams.getAndLock(); + config.sessionParams.setToExternal( + reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (sessionParamsBuffer)), + get_camera_metadata_size(sessionParamsBuffer)); + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + }); + ASSERT_TRUE(ret.isOk()); + + sessionParams.unlock(sessionParamsBuffer); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -2626,82 +2761,82 @@ TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - camera_metadata_t* staticMeta; - Return<void> ret; - sp<ICameraDeviceSession> session; - sp<device::V3_3::ICameraDeviceSession> session3_3; - openEmptyDeviceSession(name, mProvider, - &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/); - - outputBlobStreams.clear(); - ASSERT_EQ(Status::OK, - getAvailableOutputStreams(staticMeta, outputBlobStreams, - &blobThreshold)); - ASSERT_NE(0u, outputBlobStreams.size()); - - outputPreviewStreams.clear(); - ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams, - &previewThreshold)); - ASSERT_NE(0u, outputPreviewStreams.size()); - - int32_t streamId = 0; - for (auto& blobIter : outputBlobStreams) { - for (auto& previewIter : outputPreviewStreams) { - Stream previewStream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(previewIter.width), - static_cast<uint32_t>(previewIter.height), - static_cast<PixelFormat>(previewIter.format), - GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, - 0, - StreamRotation::ROTATION_0}; - Stream blobStream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(blobIter.width), - static_cast<uint32_t>(blobIter.height), - static_cast<PixelFormat>(blobIter.format), - GRALLOC1_CONSUMER_USAGE_CPU_READ, - 0, - StreamRotation::ROTATION_0}; - ::android::hardware::hidl_vec<Stream> streams = {previewStream, - blobStream}; - StreamConfiguration config = {streams, - StreamConfigurationMode::NORMAL_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(2u, halConfig.streams.size()); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(2u, halConfig.streams.size()); - }); - } - ASSERT_TRUE(ret.isOk()); - } + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } + + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4); + + outputBlobStreams.clear(); + ASSERT_EQ(Status::OK, + getAvailableOutputStreams(staticMeta, outputBlobStreams, + &blobThreshold)); + ASSERT_NE(0u, outputBlobStreams.size()); + + outputPreviewStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams, + &previewThreshold)); + ASSERT_NE(0u, outputPreviewStreams.size()); + + int32_t streamId = 0; + for (auto& blobIter : outputBlobStreams) { + for (auto& previewIter : outputPreviewStreams) { + Stream previewStream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(previewIter.width), + static_cast<uint32_t>(previewIter.height), + static_cast<PixelFormat>(previewIter.format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + Stream blobStream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(blobIter.width), + static_cast<uint32_t>(blobIter.height), + static_cast<PixelFormat>(blobIter.format), + GRALLOC1_CONSUMER_USAGE_CPU_READ, + 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec<Stream> streams = {previewStream, + blobStream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); } - - free_camera_metadata(staticMeta); - ret = session->close(); ASSERT_TRUE(ret.isOk()); } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; } + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -2713,143 +2848,160 @@ TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - camera_metadata_t* staticMeta; - Return<void> ret; - sp<ICameraDeviceSession> session; - sp<device::V3_3::ICameraDeviceSession> session3_3; - openEmptyDeviceSession(name, mProvider, - &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/); - - Status rc = isConstrainedModeAvailable(staticMeta); - if (Status::METHOD_NOT_SUPPORTED == rc) { - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - continue; - } - ASSERT_EQ(Status::OK, rc); - - AvailableStream hfrStream; - rc = pickConstrainedModeSize(staticMeta, hfrStream); - ASSERT_EQ(Status::OK, rc); - - int32_t streamId = 0; - Stream stream = {streamId, - StreamType::OUTPUT, - static_cast<uint32_t>(hfrStream.width), - static_cast<uint32_t>(hfrStream.height), - static_cast<PixelFormat>(hfrStream.format), - GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, - 0, - StreamRotation::ROTATION_0}; - ::android::hardware::hidl_vec<Stream> streams = {stream}; - StreamConfiguration config = {streams, - StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [streamId](Status s, HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(1u, halConfig.streams.size()); - ASSERT_EQ(halConfig.streams[0].id, streamId); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(1u, halConfig.streams.size()); - ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); - }); - } - ASSERT_TRUE(ret.isOk()); - - stream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(0), - static_cast<uint32_t>(0), - static_cast<PixelFormat>(hfrStream.format), - GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, - 0, - StreamRotation::ROTATION_0}; - streams[0] = stream; - config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration) { - ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || - (Status::INTERNAL_ERROR == s)); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration) { - ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || - (Status::INTERNAL_ERROR == s)); - }); - } - ASSERT_TRUE(ret.isOk()); - - stream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(UINT32_MAX), - static_cast<uint32_t>(UINT32_MAX), - static_cast<PixelFormat>(hfrStream.format), - GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, - 0, - StreamRotation::ROTATION_0}; - streams[0] = stream; - config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } - ASSERT_TRUE(ret.isOk()); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } - stream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(hfrStream.width), - static_cast<uint32_t>(hfrStream.height), - static_cast<PixelFormat>(UINT32_MAX), - GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, - 0, - StreamRotation::ROTATION_0}; - streams[0] = stream; - config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); - }); - } - ASSERT_TRUE(ret.isOk()); + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4); - free_camera_metadata(staticMeta); - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; + Status rc = isConstrainedModeAvailable(staticMeta); + if (Status::METHOD_NOT_SUPPORTED == rc) { + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + ASSERT_EQ(Status::OK, rc); + + AvailableStream hfrStream; + rc = pickConstrainedModeSize(staticMeta, hfrStream); + ASSERT_EQ(Status::OK, rc); + + int32_t streamId = 0; + Stream stream = {streamId, + StreamType::OUTPUT, + static_cast<uint32_t>(hfrStream.width), + static_cast<uint32_t>(hfrStream.height), + static_cast<PixelFormat>(hfrStream.format), + GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, + 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec<Stream> streams = {stream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); + }); + } else { + ret = session->configureStreams(config.v3_2, + [streamId](Status s, HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].id, streamId); + }); + } + ASSERT_TRUE(ret.isOk()); + + stream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(0), + static_cast<uint32_t>(0), + static_cast<PixelFormat>(hfrStream.format), + GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, + 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); } + ASSERT_TRUE(ret.isOk()); + + stream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(UINT32_MAX), + static_cast<uint32_t>(UINT32_MAX), + static_cast<PixelFormat>(hfrStream.format), + GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, + 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } + ASSERT_TRUE(ret.isOk()); + + stream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(hfrStream.width), + static_cast<uint32_t>(hfrStream.height), + static_cast<PixelFormat>(UINT32_MAX), + GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, + 0, + StreamRotation::ROTATION_0}; + streams[0] = stream; + config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } + ASSERT_TRUE(ret.isOk()); + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -2866,82 +3018,82 @@ TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - camera_metadata_t* staticMeta; - Return<void> ret; - sp<ICameraDeviceSession> session; - sp<device::V3_3::ICameraDeviceSession> session3_3; - openEmptyDeviceSession(name, mProvider, - &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/); - - outputBlobStreams.clear(); - ASSERT_EQ(Status::OK, - getAvailableOutputStreams(staticMeta, outputBlobStreams, - &blobThreshold)); - ASSERT_NE(0u, outputBlobStreams.size()); - - outputVideoStreams.clear(); - ASSERT_EQ(Status::OK, - getAvailableOutputStreams(staticMeta, outputVideoStreams, - &videoThreshold)); - ASSERT_NE(0u, outputVideoStreams.size()); - - int32_t streamId = 0; - for (auto& blobIter : outputBlobStreams) { - for (auto& videoIter : outputVideoStreams) { - Stream videoStream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(videoIter.width), - static_cast<uint32_t>(videoIter.height), - static_cast<PixelFormat>(videoIter.format), - GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, - 0, - StreamRotation::ROTATION_0}; - Stream blobStream = {streamId++, - StreamType::OUTPUT, - static_cast<uint32_t>(blobIter.width), - static_cast<uint32_t>(blobIter.height), - static_cast<PixelFormat>(blobIter.format), - GRALLOC1_CONSUMER_USAGE_CPU_READ, - 0, - StreamRotation::ROTATION_0}; - ::android::hardware::hidl_vec<Stream> streams = {videoStream, blobStream}; - StreamConfiguration config = {streams, - StreamConfigurationMode::NORMAL_MODE}; - if (session3_3 == nullptr) { - ret = session->configureStreams(config, - [](Status s, HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(2u, halConfig.streams.size()); - }); - } else { - ret = session3_3->configureStreams_3_3(config, - [](Status s, device::V3_3::HalStreamConfiguration halConfig) { - ASSERT_EQ(Status::OK, s); - ASSERT_EQ(2u, halConfig.streams.size()); - }); - } - ASSERT_TRUE(ret.isOk()); - } + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } + + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); + castSession(session, deviceVersion, &session3_3, &session3_4); + + outputBlobStreams.clear(); + ASSERT_EQ(Status::OK, + getAvailableOutputStreams(staticMeta, outputBlobStreams, + &blobThreshold)); + ASSERT_NE(0u, outputBlobStreams.size()); + + outputVideoStreams.clear(); + ASSERT_EQ(Status::OK, + getAvailableOutputStreams(staticMeta, outputVideoStreams, + &videoThreshold)); + ASSERT_NE(0u, outputVideoStreams.size()); + + int32_t streamId = 0; + for (auto& blobIter : outputBlobStreams) { + for (auto& videoIter : outputVideoStreams) { + Stream videoStream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(videoIter.width), + static_cast<uint32_t>(videoIter.height), + static_cast<PixelFormat>(videoIter.format), + GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, + 0, + StreamRotation::ROTATION_0}; + Stream blobStream = {streamId++, + StreamType::OUTPUT, + static_cast<uint32_t>(blobIter.width), + static_cast<uint32_t>(blobIter.height), + static_cast<PixelFormat>(blobIter.format), + GRALLOC1_CONSUMER_USAGE_CPU_READ, + 0, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec<Stream> streams = {videoStream, blobStream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, + [](Status s, device::V3_3::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else { + ret = session->configureStreams(config.v3_2, + [](Status s, HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); } - - free_camera_metadata(staticMeta); - ret = session->close(); ASSERT_TRUE(ret.isOk()); } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; } + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -2956,152 +3108,145 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - Stream previewStream; - HalStreamConfiguration halStreamConfig; - sp<ICameraDeviceSession> session; - bool supportsPartialResults = false; - uint32_t partialResultCount = 0; - configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/, - &previewStream /*out*/, &halStreamConfig /*out*/, - &supportsPartialResults /*out*/, - &partialResultCount /*out*/); - - std::shared_ptr<ResultMetadataQueue> resultQueue; - auto resultQueueRet = - session->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()); - - InFlightRequest inflightReq = {1, false, supportsPartialResults, - partialResultCount, resultQueue}; - - RequestTemplate reqTemplate = RequestTemplate::PREVIEW; - Return<void> ret; - ret = session->constructDefaultRequestSettings(reqTemplate, - [&](auto status, const auto& req) { - ASSERT_EQ(Status::OK, status); - settings = req; - }); - ASSERT_TRUE(ret.isOk()); - - sp<GraphicBuffer> gb = new GraphicBuffer( - previewStream.width, previewStream.height, - static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, - android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, - halStreamConfig.streams[0].consumerUsage)); - ASSERT_NE(nullptr, gb.get()); - StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, - bufferId, - hidl_handle(gb->getNativeBuffer()->handle), - BufferStatus::OK, - nullptr, - nullptr}; - ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; - StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, - nullptr}; - CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, - emptyInputBuffer, outputBuffers}; - - { - std::unique_lock<std::mutex> l(mLock); - mInflightMap.clear(); - mInflightMap.add(frameNumber, &inflightReq); - } - - Status status = Status::INTERNAL_ERROR; - uint32_t numRequestProcessed = 0; - hidl_vec<BufferCache> cachesToRemove; - Return<void> returnStatus = session->processCaptureRequest( - {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, - uint32_t n) { - status = s; - numRequestProcessed = n; - }); - ASSERT_TRUE(returnStatus.isOk()); - ASSERT_EQ(Status::OK, status); - 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)); - } + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } - ASSERT_FALSE(inflightReq.errorCodeValid); - ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); - ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); - - request.frameNumber++; - // Empty settings should be supported after the first call - // for repeating requests. - request.settings.setToExternal(nullptr, 0, true); - // The buffer has been registered to HAL by bufferId, so per - // API contract we should send a null handle for this buffer - request.outputBuffers[0].buffer = nullptr; - mInflightMap.clear(); - inflightReq = {1, false, supportsPartialResults, partialResultCount, - resultQueue}; - mInflightMap.add(request.frameNumber, &inflightReq); - } + Stream previewStream; + HalStreamConfiguration halStreamConfig; + sp<ICameraDeviceSession> session; + bool supportsPartialResults = false; + uint32_t partialResultCount = 0; + configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, + &previewStream /*out*/, &halStreamConfig /*out*/, + &supportsPartialResults /*out*/, + &partialResultCount /*out*/); - returnStatus = session->processCaptureRequest( - {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, - uint32_t n) { - status = s; - numRequestProcessed = n; - }); - ASSERT_TRUE(returnStatus.isOk()); - ASSERT_EQ(Status::OK, status); - 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)); + std::shared_ptr<ResultMetadataQueue> resultQueue; + auto resultQueueRet = + session->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()); + + InFlightRequest inflightReq = {1, false, supportsPartialResults, + partialResultCount, resultQueue}; + + RequestTemplate reqTemplate = RequestTemplate::PREVIEW; + Return<void> ret; + ret = session->constructDefaultRequestSettings(reqTemplate, + [&](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + settings = req; + }); + ASSERT_TRUE(ret.isOk()); + + sp<GraphicBuffer> gb = new GraphicBuffer( + previewStream.width, previewStream.height, + static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, + android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, + halStreamConfig.streams[0].consumerUsage)); + ASSERT_NE(nullptr, gb.get()); + StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, + bufferId, + hidl_handle(gb->getNativeBuffer()->handle), + BufferStatus::OK, + nullptr, + nullptr}; + ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; + StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, + nullptr}; + CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, + emptyInputBuffer, outputBuffers}; + + { + std::unique_lock<std::mutex> l(mLock); + mInflightMap.clear(); + mInflightMap.add(frameNumber, &inflightReq); + } + + Status status = Status::INTERNAL_ERROR; + uint32_t numRequestProcessed = 0; + hidl_vec<BufferCache> cachesToRemove; + Return<void> returnStatus = session->processCaptureRequest( + {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, + uint32_t n) { + status = s; + numRequestProcessed = n; + }); + ASSERT_TRUE(returnStatus.isOk()); + ASSERT_EQ(Status::OK, status); + 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); + ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); + + request.frameNumber++; + // Empty settings should be supported after the first call + // for repeating requests. + request.settings.setToExternal(nullptr, 0, true); + // The buffer has been registered to HAL by bufferId, so per + // API contract we should send a null handle for this buffer + request.outputBuffers[0].buffer = nullptr; + mInflightMap.clear(); + inflightReq = {1, false, supportsPartialResults, partialResultCount, + resultQueue}; + mInflightMap.add(request.frameNumber, &inflightReq); + } + + returnStatus = session->processCaptureRequest( + {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, + uint32_t n) { + status = s; + numRequestProcessed = n; + }); + ASSERT_TRUE(returnStatus.isOk()); + ASSERT_EQ(Status::OK, status); + ASSERT_EQ(numRequestProcessed, 1u); - ASSERT_FALSE(inflightReq.errorCodeValid); - ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); - ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); - } - - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); + { + 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)); } - break; + + ASSERT_FALSE(inflightReq.errorCodeValid); + ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); + ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); } + + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -3118,65 +3263,58 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - Stream previewStream; - HalStreamConfiguration halStreamConfig; - sp<ICameraDeviceSession> session; - bool supportsPartialResults = false; - uint32_t partialResultCount = 0; - configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/, - &previewStream /*out*/, &halStreamConfig /*out*/, - &supportsPartialResults /*out*/, - &partialResultCount /*out*/); - - sp<GraphicBuffer> gb = new GraphicBuffer( - previewStream.width, previewStream.height, - static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, - android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, - halStreamConfig.streams[0].consumerUsage)); - - StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, - bufferId, - hidl_handle(gb->getNativeBuffer()->handle), - BufferStatus::OK, - nullptr, - nullptr}; - ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; - StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, - nullptr}; - CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, - emptyInputBuffer, outputBuffers}; - - // Settings were not correctly initialized, we should fail here - Status status = Status::OK; - uint32_t numRequestProcessed = 0; - hidl_vec<BufferCache> cachesToRemove; - Return<void> ret = session->processCaptureRequest( - {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, - uint32_t n) { - status = s; - numRequestProcessed = n; - }); - ASSERT_TRUE(ret.isOk()); - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); - ASSERT_EQ(numRequestProcessed, 0u); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } + + Stream previewStream; + HalStreamConfiguration halStreamConfig; + sp<ICameraDeviceSession> session; + bool supportsPartialResults = false; + uint32_t partialResultCount = 0; + configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, + &previewStream /*out*/, &halStreamConfig /*out*/, + &supportsPartialResults /*out*/, + &partialResultCount /*out*/); + + sp<GraphicBuffer> gb = new GraphicBuffer( + previewStream.width, previewStream.height, + static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, + android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, + halStreamConfig.streams[0].consumerUsage)); + + StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, + bufferId, + hidl_handle(gb->getNativeBuffer()->handle), + BufferStatus::OK, + nullptr, + nullptr}; + ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; + StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, + nullptr}; + CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, + emptyInputBuffer, outputBuffers}; + + // Settings were not correctly initialized, we should fail here + Status status = Status::OK; + uint32_t numRequestProcessed = 0; + hidl_vec<BufferCache> cachesToRemove; + Return<void> ret = session->processCaptureRequest( + {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, + uint32_t n) { + status = s; + numRequestProcessed = n; + }); + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); + ASSERT_EQ(numRequestProcessed, 0u); - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; - } + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -3192,62 +3330,55 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - Stream previewStream; - HalStreamConfiguration halStreamConfig; - sp<ICameraDeviceSession> session; - bool supportsPartialResults = false; - uint32_t partialResultCount = 0; - configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/, - &previewStream /*out*/, &halStreamConfig /*out*/, - &supportsPartialResults /*out*/, - &partialResultCount /*out*/); - - RequestTemplate reqTemplate = RequestTemplate::PREVIEW; - Return<void> ret; - ret = session->constructDefaultRequestSettings(reqTemplate, - [&](auto status, const auto& req) { - ASSERT_EQ(Status::OK, status); - settings = req; - }); - ASSERT_TRUE(ret.isOk()); - - ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers; - StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, - nullptr}; - CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, - emptyInputBuffer, emptyOutputBuffers}; - - // Output buffers are missing, we should fail here - Status status = Status::OK; - uint32_t numRequestProcessed = 0; - hidl_vec<BufferCache> cachesToRemove; - ret = session->processCaptureRequest( - {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, - uint32_t n) { - status = s; - numRequestProcessed = n; - }); - ASSERT_TRUE(ret.isOk()); - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); - ASSERT_EQ(numRequestProcessed, 0u); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } + + Stream previewStream; + HalStreamConfiguration halStreamConfig; + sp<ICameraDeviceSession> session; + bool supportsPartialResults = false; + uint32_t partialResultCount = 0; + configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, + &previewStream /*out*/, &halStreamConfig /*out*/, + &supportsPartialResults /*out*/, + &partialResultCount /*out*/); + + RequestTemplate reqTemplate = RequestTemplate::PREVIEW; + Return<void> ret; + ret = session->constructDefaultRequestSettings(reqTemplate, + [&](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + settings = req; + }); + ASSERT_TRUE(ret.isOk()); + + ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers; + StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, + nullptr}; + CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, + emptyInputBuffer, emptyOutputBuffers}; + + // Output buffers are missing, we should fail here + Status status = Status::OK; + uint32_t numRequestProcessed = 0; + hidl_vec<BufferCache> cachesToRemove; + ret = session->processCaptureRequest( + {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, + uint32_t n) { + status = s; + numRequestProcessed = n; + }); + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); + ASSERT_EQ(numRequestProcessed, 0u); - ret = session->close(); - ASSERT_TRUE(ret.isOk()); - } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; - } + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -3263,130 +3394,123 @@ TEST_F(CameraHidlTest, flushPreviewRequest) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - Stream previewStream; - HalStreamConfiguration halStreamConfig; - sp<ICameraDeviceSession> session; - bool supportsPartialResults = false; - uint32_t partialResultCount = 0; - configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/, - &previewStream /*out*/, &halStreamConfig /*out*/, - &supportsPartialResults /*out*/, - &partialResultCount /*out*/); - - std::shared_ptr<ResultMetadataQueue> resultQueue; - auto resultQueueRet = - session->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()); - - InFlightRequest inflightReq = {1, false, supportsPartialResults, - partialResultCount, resultQueue}; - RequestTemplate reqTemplate = RequestTemplate::PREVIEW; - Return<void> ret; - ret = session->constructDefaultRequestSettings(reqTemplate, - [&](auto status, const auto& req) { - ASSERT_EQ(Status::OK, status); - settings = req; - }); - ASSERT_TRUE(ret.isOk()); - - sp<GraphicBuffer> gb = new GraphicBuffer( - previewStream.width, previewStream.height, - static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, - android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, - halStreamConfig.streams[0].consumerUsage)); - ASSERT_NE(nullptr, gb.get()); - StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, - bufferId, - hidl_handle(gb->getNativeBuffer()->handle), - BufferStatus::OK, - nullptr, - nullptr}; - ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; - const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, - BufferStatus::ERROR, nullptr, nullptr}; - CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, - emptyInputBuffer, outputBuffers}; - - { - std::unique_lock<std::mutex> l(mLock); - mInflightMap.clear(); - mInflightMap.add(frameNumber, &inflightReq); - } - - Status status = Status::INTERNAL_ERROR; - uint32_t numRequestProcessed = 0; - hidl_vec<BufferCache> cachesToRemove; - ret = session->processCaptureRequest( - {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, - uint32_t n) { - status = s; - numRequestProcessed = n; - }); - - ASSERT_TRUE(ret.isOk()); - ASSERT_EQ(Status::OK, status); - ASSERT_EQ(numRequestProcessed, 1u); - // Flush before waiting for request to complete. - Return<Status> returnStatus = session->flush(); - ASSERT_TRUE(returnStatus.isOk()); - ASSERT_EQ(Status::OK, returnStatus); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } - { - 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)); - } + Stream previewStream; + HalStreamConfiguration halStreamConfig; + sp<ICameraDeviceSession> session; + bool supportsPartialResults = false; + uint32_t partialResultCount = 0; + configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, + &previewStream /*out*/, &halStreamConfig /*out*/, + &supportsPartialResults /*out*/, + &partialResultCount /*out*/); - if (!inflightReq.errorCodeValid) { - ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); - ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); - } else { - switch (inflightReq.errorCode) { - case ErrorCode::ERROR_REQUEST: - case ErrorCode::ERROR_RESULT: - case ErrorCode::ERROR_BUFFER: - // Expected - break; - case ErrorCode::ERROR_DEVICE: - default: - FAIL() << "Unexpected error:" - << static_cast<uint32_t>(inflightReq.errorCode); - } + std::shared_ptr<ResultMetadataQueue> resultQueue; + auto resultQueueRet = + session->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()); + + InFlightRequest inflightReq = {1, false, supportsPartialResults, + partialResultCount, resultQueue}; + RequestTemplate reqTemplate = RequestTemplate::PREVIEW; + Return<void> ret; + ret = session->constructDefaultRequestSettings(reqTemplate, + [&](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + settings = req; + }); + ASSERT_TRUE(ret.isOk()); + + sp<GraphicBuffer> gb = new GraphicBuffer( + previewStream.width, previewStream.height, + static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, + android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, + halStreamConfig.streams[0].consumerUsage)); + ASSERT_NE(nullptr, gb.get()); + StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, + bufferId, + hidl_handle(gb->getNativeBuffer()->handle), + BufferStatus::OK, + nullptr, + nullptr}; + ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; + const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, + BufferStatus::ERROR, nullptr, nullptr}; + CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, + emptyInputBuffer, outputBuffers}; + + { + std::unique_lock<std::mutex> l(mLock); + mInflightMap.clear(); + mInflightMap.add(frameNumber, &inflightReq); + } + + Status status = Status::INTERNAL_ERROR; + uint32_t numRequestProcessed = 0; + hidl_vec<BufferCache> cachesToRemove; + ret = session->processCaptureRequest( + {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, + uint32_t n) { + status = s; + numRequestProcessed = n; + }); - ret = session->close(); - ASSERT_TRUE(ret.isOk()); + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(Status::OK, status); + ASSERT_EQ(numRequestProcessed, 1u); + // Flush before waiting for request to complete. + Return<Status> returnStatus = session->flush(); + ASSERT_TRUE(returnStatus.isOk()); + ASSERT_EQ(Status::OK, returnStatus); + + { + 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)); + } + + if (!inflightReq.errorCodeValid) { + ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); + ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); + } else { + switch (inflightReq.errorCode) { + case ErrorCode::ERROR_REQUEST: + case ErrorCode::ERROR_RESULT: + case ErrorCode::ERROR_BUFFER: + // Expected + break; + case ErrorCode::ERROR_DEVICE: + default: + FAIL() << "Unexpected error:" + << static_cast<uint32_t>(inflightReq.errorCode); } } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; + + ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } } @@ -3400,44 +3524,37 @@ TEST_F(CameraHidlTest, flushEmpty) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); - switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_3: - case CAMERA_DEVICE_API_VERSION_3_2: { - Stream previewStream; - HalStreamConfiguration halStreamConfig; - sp<ICameraDeviceSession> session; - bool supportsPartialResults = false; - uint32_t partialResultCount = 0; - configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/, - &previewStream /*out*/, &halStreamConfig /*out*/, - &supportsPartialResults /*out*/, - &partialResultCount /*out*/); - - Return<Status> returnStatus = session->flush(); - ASSERT_TRUE(returnStatus.isOk()); - ASSERT_EQ(Status::OK, returnStatus); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { + continue; + } else if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } - { - std::unique_lock<std::mutex> l(mLock); - auto timeout = std::chrono::system_clock::now() + - std::chrono::milliseconds(kEmptyFlushTimeoutMSec); - ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); - } + Stream previewStream; + HalStreamConfiguration halStreamConfig; + sp<ICameraDeviceSession> session; + bool supportsPartialResults = false; + uint32_t partialResultCount = 0; + configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, + &previewStream /*out*/, &halStreamConfig /*out*/, + &supportsPartialResults /*out*/, + &partialResultCount /*out*/); - Return<void> ret = session->close(); - ASSERT_TRUE(ret.isOk()); - } - break; - case CAMERA_DEVICE_API_VERSION_1_0: { - //Not applicable - } - break; - default: { - ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); - ADD_FAILURE(); - } - break; + Return<Status> returnStatus = session->flush(); + ASSERT_TRUE(returnStatus.isOk()); + ASSERT_EQ(Status::OK, returnStatus); + + { + std::unique_lock<std::mutex> l(mLock); + auto timeout = std::chrono::system_clock::now() + + std::chrono::milliseconds(kEmptyFlushTimeoutMSec); + ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); } + + Return<void> ret = session->close(); + ASSERT_TRUE(ret.isOk()); } } @@ -3625,7 +3742,7 @@ Status CameraHidlTest::isAutoFocusModeAvailable( } // Open a device session and configure a preview stream. -void CameraHidlTest::configurePreviewStream(const std::string &name, +void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, const AvailableStream *previewThreshold, sp<ICameraDeviceSession> *session /*out*/, @@ -3665,9 +3782,9 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, }); ASSERT_TRUE(ret.isOk()); - auto castResult = device::V3_3::ICameraDeviceSession::castFrom(*session); - ASSERT_TRUE(castResult.isOk()); - sp<device::V3_3::ICameraDeviceSession> session3_3 = castResult; + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + castSession(*session, deviceVersion, &session3_3, &session3_4); camera_metadata_t *staticMeta; ret = device3_x->getCameraCharacteristics([&] (Status s, @@ -3700,17 +3817,20 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, static_cast<PixelFormat> (outputPreviewStreams[0].format), GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec<Stream> streams = {*previewStream}; - StreamConfiguration config = {streams, - StreamConfigurationMode::NORMAL_MODE}; - if (session3_3 == nullptr) { - ret = (*session)->configureStreams(config, - [&] (Status s, HalStreamConfiguration halConfig) { + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; + if (session3_4 != nullptr) { + ret = session3_4->configureStreams_3_4(config, + [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); ASSERT_EQ(1u, halConfig.streams.size()); - *halStreamConfig = halConfig; + halStreamConfig->streams.resize(halConfig.streams.size()); + for (size_t i = 0; i < halConfig.streams.size(); i++) { + halStreamConfig->streams[i] = halConfig.streams[i].v3_2; + } }); - } else { - ret = session3_3->configureStreams_3_3(config, + } else if (session3_3 != nullptr) { + ret = session3_3->configureStreams_3_3(config.v3_2, [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); ASSERT_EQ(1u, halConfig.streams.size()); @@ -3719,15 +3839,47 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, halStreamConfig->streams[i] = halConfig.streams[i].v3_2; } }); + } else { + ret = (*session)->configureStreams(config.v3_2, + [&] (Status s, HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + *halStreamConfig = halConfig; + }); } ASSERT_TRUE(ret.isOk()); } +//Cast camera device session to corresponding version +void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion, + sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/, + sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/) { + ASSERT_NE(nullptr, session3_3); + ASSERT_NE(nullptr, session3_4); + + switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_4: { + auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + *session3_4 = castResult; + break; + } + case CAMERA_DEVICE_API_VERSION_3_3: { + auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + *session3_3 = castResult; + break; + } + default: + //no-op + return; + } +} + // Open a device session with empty callbacks and return static metadata. void CameraHidlTest::openEmptyDeviceSession(const std::string &name, sp<ICameraProvider> provider, sp<ICameraDeviceSession> *session /*out*/, - sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/, camera_metadata_t **staticMeta /*out*/) { ASSERT_NE(nullptr, session); ASSERT_NE(nullptr, staticMeta); @@ -3763,12 +3915,6 @@ void CameraHidlTest::openEmptyDeviceSession(const std::string &name, ASSERT_NE(nullptr, *staticMeta); }); ASSERT_TRUE(ret.isOk()); - - if(session3_3 != nullptr) { - auto castResult = device::V3_3::ICameraDeviceSession::castFrom(*session); - ASSERT_TRUE(castResult.isOk()); - *session3_3 = castResult; - } } // Open a particular camera device. |