diff options
Diffstat (limited to 'camera/provider/aidl/vts/camera_aidl_test.h')
-rw-r--r-- | camera/provider/aidl/vts/camera_aidl_test.h | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h new file mode 100644 index 0000000000..cc381696c7 --- /dev/null +++ b/camera/provider/aidl/vts/camera_aidl_test.h @@ -0,0 +1,528 @@ +/* + * Copyright (C) 2022 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 HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_ +#define HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_ + +#define LOG_TAG "camera_aidl_hal_test" + +#include <string> +#include <unordered_map> +#include <unordered_set> + +#include <CameraMetadata.h> +#include <CameraParameters.h> +#include <HandleImporter.h> +#include <fmq/AidlMessageQueue.h> + +#include <aidl/android/hardware/graphics/common/Dataspace.h> + +#include <aidl/android/hardware/camera/common/Status.h> +#include <aidl/android/hardware/camera/common/TorchModeStatus.h> +#include <aidl/android/hardware/common/NativeHandle.h> + +#include <aidl/android/hardware/camera/device/CaptureResult.h> +#include <aidl/android/hardware/camera/device/ErrorCode.h> +#include <aidl/android/hardware/camera/device/HalStream.h> +#include <aidl/android/hardware/camera/device/ICameraDevice.h> +#include <aidl/android/hardware/camera/device/NotifyMsg.h> +#include <aidl/android/hardware/camera/device/PhysicalCameraMetadata.h> +#include <aidl/android/hardware/camera/device/Stream.h> + +#include <aidl/android/hardware/camera/provider/ICameraProvider.h> + +#include <aidl/android/hardware/graphics/common/PixelFormat.h> + +#include <gtest/gtest.h> + +#include <log/log.h> +#include <system/camera_metadata.h> +#include <utils/KeyedVector.h> +#include <utils/Timers.h> + +using ::aidl::android::hardware::camera::common::Status; +using ::aidl::android::hardware::camera::common::TorchModeStatus; +using ::aidl::android::hardware::camera::device::BufferRequest; +using ::aidl::android::hardware::camera::device::BufferRequestStatus; +using ::aidl::android::hardware::camera::device::CameraMetadata; +using ::aidl::android::hardware::camera::device::CaptureResult; +using ::aidl::android::hardware::camera::device::ErrorCode; +using ::aidl::android::hardware::camera::device::HalStream; +using ::aidl::android::hardware::camera::device::ICameraDevice; +using ::aidl::android::hardware::camera::device::ICameraDeviceSession; +using ::aidl::android::hardware::camera::device::ICameraInjectionSession; +using ::aidl::android::hardware::camera::device::NotifyMsg; +using ::aidl::android::hardware::camera::device::PhysicalCameraMetadata; +using ::aidl::android::hardware::camera::device::RequestTemplate; +using ::aidl::android::hardware::camera::device::Stream; +using ::aidl::android::hardware::camera::device::StreamBuffer; +using ::aidl::android::hardware::camera::device::StreamBufferRet; +using ::aidl::android::hardware::camera::device::StreamConfiguration; +using ::aidl::android::hardware::camera::device::StreamConfigurationMode; +using ::aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination; +using ::aidl::android::hardware::camera::provider::ICameraProvider; + +using ::aidl::android::hardware::common::NativeHandle; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; + +using ::aidl::android::hardware::graphics::common::Dataspace; +using ::aidl::android::hardware::graphics::common::PixelFormat; + +using ::android::hardware::camera::common::V1_0::helper::HandleImporter; +using ::android::hardware::camera::common::V1_0::helper::Size; + +using ResultMetadataQueue = android::AidlMessageQueue<int8_t, SynchronizedReadWrite>; + +using ::ndk::ScopedAStatus; + +class DeviceCb; // Forward declare to break circular header dependency + +class CameraAidlTest : public ::testing::TestWithParam<std::string> { + public: + enum SystemCameraKind { + /** + * These camera devices are visible to all apps and system components alike + */ + PUBLIC = 0, + + /** + * These camera devices are visible only to processes having the + * android.permission.SYSTEM_CAMERA permission. They are not exposed to 3P + * apps. + */ + SYSTEM_ONLY_CAMERA, + + /** + * These camera devices are visible only to HAL clients (that try to connect + * on a hwbinder thread). + */ + HIDDEN_SECURE_CAMERA + }; + + struct AvailableStream { + int32_t width; + int32_t height; + int32_t format; + }; + + enum ReprocessType { + PRIV_REPROCESS, + YUV_REPROCESS, + }; + + struct AvailableZSLInputOutput { + int32_t inputFormat; + int32_t outputFormat; + }; + + virtual void SetUp() override; + virtual void TearDown() override; + + std::vector<std::string> getCameraDeviceNames(std::shared_ptr<ICameraProvider>& provider, + bool addSecureOnly = false); + + static bool isSecureOnly(const std::shared_ptr<ICameraProvider>& provider, + const std::string& name); + + std::map<std::string, std::string> getCameraDeviceIdToNameMap( + std::shared_ptr<ICameraProvider> provider); + + static std::vector<ConcurrentCameraIdCombination> getConcurrentDeviceCombinations( + std::shared_ptr<ICameraProvider>& provider); + + void notifyDeviceState(int64_t state); + + static void allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage, + PixelFormat format, buffer_handle_t* buffer_handle /*out*/); + + static void openEmptyDeviceSession(const std::string& name, + std::shared_ptr<ICameraProvider> provider, + std::shared_ptr<ICameraDeviceSession>* session /*out*/, + CameraMetadata* staticMeta /*out*/, + std::shared_ptr<ICameraDevice>* device /*out*/); + static void openEmptyInjectionSession(const std::string& name, + const std::shared_ptr<ICameraProvider>& provider, + std::shared_ptr<ICameraInjectionSession>* session /*out*/, + CameraMetadata* staticMeta /*out*/, + std::shared_ptr<ICameraDevice>* device /*out*/); + + static void createStreamConfiguration(std::vector<Stream>& streams, + StreamConfigurationMode configMode, + StreamConfiguration* config, int32_t jpegBufferSize = 0); + + void configureOfflineStillStream( + const std::string& name, const std::shared_ptr<ICameraProvider>& provider, + const AvailableStream* threshold, + std::shared_ptr<ICameraDeviceSession>* session /*out*/, Stream* stream /*out*/, + std::vector<HalStream>* halStreams, bool* supportsPartialResults /*out*/, + int32_t* partialResultCount /*out*/, std::shared_ptr<DeviceCb>* outCb /*out*/, + int32_t* jpegBufferSize /*out*/, bool* useHalBufManager /*out*/); + + void configureStreams( + const std::string& name, const std::shared_ptr<ICameraProvider>& provider, + PixelFormat format, std::shared_ptr<ICameraDeviceSession>* session /*out*/, + Stream* previewStream /*out*/, std::vector<HalStream>* halStreams /*out*/, + bool* supportsPartialResults /*out*/, int32_t* partialResultCount /*out*/, + bool* useHalBufManager /*out*/, std::shared_ptr<DeviceCb>* outCb /*out*/, + uint32_t streamConfigCounter, bool maxResolution, + aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap + prof = ::aidl::android::hardware::camera::metadata:: + RequestAvailableDynamicRangeProfilesMap(0)); + + void configurePreviewStreams( + const std::string& name, const std::shared_ptr<ICameraProvider>& provider, + const AvailableStream* previewThreshold, + const std::unordered_set<std::string>& physicalIds, + std::shared_ptr<ICameraDeviceSession>* session /*out*/, Stream* previewStream /*out*/, + std::vector<HalStream>* halStreams /*out*/, bool* supportsPartialResults /*out*/, + int32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, + std::shared_ptr<DeviceCb>* cb /*out*/, int32_t streamConfigCounter = 0); + + void configurePreviewStream( + const std::string& name, const std::shared_ptr<ICameraProvider>& provider, + const AvailableStream* previewThreshold, + std::shared_ptr<ICameraDeviceSession>* session /*out*/, Stream* previewStream /*out*/, + std::vector<HalStream>* halStreams /*out*/, bool* supportsPartialResults /*out*/, + int32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, + std::shared_ptr<DeviceCb>* cb /*out*/, uint32_t streamConfigCounter = 0); + + void configureSingleStream( + const std::string& name, const std::shared_ptr<ICameraProvider>& provider, + const AvailableStream* previewThreshold, uint64_t bufferUsage, + RequestTemplate reqTemplate, std::shared_ptr<ICameraDeviceSession>* session /*out*/, + Stream* previewStream /*out*/, std::vector<HalStream>* halStreams /*out*/, + bool* supportsPartialResults /*out*/, int32_t* partialResultCount /*out*/, + bool* useHalBufManager /*out*/, std::shared_ptr<DeviceCb>* cb /*out*/, + uint32_t streamConfigCounter = 0); + + void verifyLogicalOrUltraHighResCameraMetadata(const std::string& cameraName, + const std::shared_ptr<ICameraDevice>& device, + const CameraMetadata& chars, + const std::vector<std::string>& deviceNames); + + static void verifyCameraCharacteristics(const CameraMetadata& chars); + + static void verifyExtendedSceneModeCharacteristics(const camera_metadata_t* metadata); + + static void verifyZoomCharacteristics(const camera_metadata_t* metadata); + + static void verifyRecommendedConfigs(const CameraMetadata& chars); + + static void verifyMonochromeCharacteristics(const CameraMetadata& chars); + + static void verifyMonochromeCameraResult( + const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata); + + static void verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata); + + static void verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device, + const StreamConfiguration& config, bool expectedStatus, + bool expectStreamCombQuery); + + static void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata, + const std::vector<uint8_t>& resultMetadata); + + static void verifyBuffersReturned(const std::shared_ptr<ICameraDeviceSession>& session, + int32_t streamId, const std::shared_ptr<DeviceCb>& cb, + uint32_t streamConfigCounter = 0); + + void verifyBuffersReturned(const std::shared_ptr<ICameraDeviceSession>& session, + const std::vector<int32_t>& streamIds, std::shared_ptr<DeviceCb> cb, + uint32_t streamConfigCounter = 0); + + static void verifySessionReconfigurationQuery( + const std::shared_ptr<ICameraDeviceSession>& session, camera_metadata* oldSessionParams, + camera_metadata* newSessionParams); + + static void verifyRequestTemplate(const camera_metadata_t* metadata, + RequestTemplate requestTemplate); + + static void overrideRotateAndCrop(CameraMetadata* settings /*in/out*/); + + static bool isDepthOnly(const camera_metadata_t* staticMeta); + + static bool isUltraHighResolution(const camera_metadata_t* staticMeta); + + static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta, + std::vector<AvailableStream>& outputStreams, + const AvailableStream* threshold = nullptr, + bool maxResolution = false); + + static Status getMaxOutputSizeForFormat(const camera_metadata_t* staticMeta, PixelFormat format, + Size* size, bool maxResolution = false); + + static Status getMandatoryConcurrentStreams(const camera_metadata_t* staticMeta, + std::vector<AvailableStream>* outputStreams); + + static bool supportsPreviewStabilization(const std::string& name, + const std::shared_ptr<ICameraProvider>& provider); + + static Status getJpegBufferSize(camera_metadata_t* staticMeta, int32_t* outBufSize); + + static Status isConstrainedModeAvailable(camera_metadata_t* staticMeta); + + static Status isLogicalMultiCamera(const camera_metadata_t* staticMeta); + + static bool isTorchSupported(const camera_metadata_t* staticMeta); + + static bool isTorchStrengthControlSupported(const camera_metadata_t* staticMeta); + + static Status isOfflineSessionSupported(const camera_metadata_t* staticMeta); + + static Status getPhysicalCameraIds(const camera_metadata_t* staticMeta, + std::unordered_set<std::string>* physicalIds /*out*/); + + static Status getSupportedKeys(camera_metadata_t* staticMeta, uint32_t tagId, + std::unordered_set<int32_t>* requestIDs /*out*/); + + static void fillOutputStreams(camera_metadata_ro_entry_t* entry, + std::vector<AvailableStream>& outputStreams, + const AvailableStream* threshold = nullptr, + const int32_t availableConfigOutputTag = 0u); + + static void constructFilteredSettings( + const std::shared_ptr<ICameraDeviceSession>& session, + const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate, + android::hardware::camera::common::V1_0::helper::CameraMetadata* + defaultSettings /*out*/, + android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings + /*out*/); + + static Status pickConstrainedModeSize(camera_metadata_t* staticMeta, + AvailableStream& hfrStream); + + static Status isZSLModeAvailable(const camera_metadata_t* staticMeta); + + static Status isZSLModeAvailable(const camera_metadata_t* staticMeta, ReprocessType reprocType); + + static Status getZSLInputOutputMap(camera_metadata_t* staticMeta, + std::vector<AvailableZSLInputOutput>& inputOutputMap); + + static Status findLargestSize(const std::vector<AvailableStream>& streamSizes, int32_t format, + AvailableStream& result); + + static Status isMonochromeCamera(const camera_metadata_t* staticMeta); + + static Status getSystemCameraKind(const camera_metadata_t* staticMeta, + SystemCameraKind* systemCameraKind); + + static void getMultiResolutionStreamConfigurations( + camera_metadata_ro_entry* multiResStreamConfigs, + camera_metadata_ro_entry* streamConfigs, + camera_metadata_ro_entry* maxResolutionStreamConfigs, + const camera_metadata_t* staticMetadata); + + static void getPrivacyTestPatternModes( + const camera_metadata_t* staticMetadata, + std::unordered_set<int32_t>* privacyTestPatternModes /*out*/); + + static Dataspace getDataspace(PixelFormat format); + + void processCaptureRequestInternal(uint64_t bufferUsage, RequestTemplate reqTemplate, + bool useSecureOnlyCameras); + + void processPreviewStabilizationCaptureRequestInternal( + bool previewStabilizationOn, + /*inout*/ std::unordered_map<std::string, nsecs_t>& cameraDeviceToTimeLag); + + static bool is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta); + + static void get10BitDynamicRangeProfiles( + const camera_metadata_t* staticMeta, + std::vector<aidl::android::hardware::camera::metadata:: + RequestAvailableDynamicRangeProfilesMap>* profiles); + + // Used by switchToOffline where a new result queue is created for offline reqs + void updateInflightResultQueue(const std::shared_ptr<ResultMetadataQueue>& resultQueue); + + static Size getMinSize(Size a, Size b); + + protected: + // In-flight queue for tracking completion of capture requests. + struct InFlightRequest { + // Set by notify() SHUTTER call. + nsecs_t shutterTimestamp; + + bool shutterReadoutTimestampValid; + nsecs_t shutterReadoutTimestamp; + + bool errorCodeValid; + ErrorCode errorCode; + + // Is partial result supported + bool usePartialResult; + + // Partial result count expected + int32_t numPartialResults; + + // Message queue + std::shared_ptr<ResultMetadataQueue> resultQueue; + + // Set by process_capture_result call with valid metadata + bool haveResultMetadata; + + // Decremented by calls to process_capture_result with valid output + // and input buffers + ssize_t numBuffersLeft; + + // A 64bit integer to index the frame number associated with this result. + int64_t frameNumber; + + // The partial result count (index) for this capture result. + int32_t partialResultCount; + + // For buffer drop errors, the stream ID for the stream that lost a buffer. + // For physical sub-camera result errors, the Id of the physical stream + // for the physical sub-camera. + // Otherwise -1. + int32_t errorStreamId; + + // If this request has any input buffer + bool hasInputBuffer; + + // Result metadata + ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult; + + // A copy-able StreamBuffer using buffer_handle_t instead of AIDLs NativeHandle + struct NativeStreamBuffer { + int32_t streamId; + int64_t bufferId; + buffer_handle_t buffer; + aidl::android::hardware::camera::device::BufferStatus status; + buffer_handle_t acquireFence; + buffer_handle_t releaseFence; + }; + + // Buffers are added by process_capture_result when output buffers + // return from HAL but framework. + struct StreamBufferAndTimestamp { + NativeStreamBuffer buffer; + nsecs_t timeStamp; + }; + std::vector<StreamBufferAndTimestamp> resultOutputBuffers; + + std::unordered_set<std::string> expectedPhysicalResults; + + InFlightRequest() + : shutterTimestamp(0), + shutterReadoutTimestampValid(false), + shutterReadoutTimestamp(0), + errorCodeValid(false), + errorCode(ErrorCode::ERROR_BUFFER), + usePartialResult(false), + numPartialResults(0), + resultQueue(nullptr), + haveResultMetadata(false), + numBuffersLeft(0), + frameNumber(0), + partialResultCount(0), + errorStreamId(-1), + hasInputBuffer(false), + collectedResult(1, 10) {} + + InFlightRequest(ssize_t numBuffers, bool hasInput, bool partialResults, + int32_t partialCount, std::shared_ptr<ResultMetadataQueue> queue = nullptr) + : shutterTimestamp(0), + shutterReadoutTimestampValid(false), + shutterReadoutTimestamp(0), + errorCodeValid(false), + errorCode(ErrorCode::ERROR_BUFFER), + usePartialResult(partialResults), + numPartialResults(partialCount), + resultQueue(queue), + haveResultMetadata(false), + numBuffersLeft(numBuffers), + frameNumber(0), + partialResultCount(0), + errorStreamId(-1), + hasInputBuffer(hasInput), + collectedResult(1, 10) {} + + InFlightRequest(ssize_t numBuffers, bool hasInput, bool partialResults, + int32_t partialCount, + const std::unordered_set<std::string>& extraPhysicalResult, + std::shared_ptr<ResultMetadataQueue> queue = nullptr) + : shutterTimestamp(0), + shutterReadoutTimestampValid(false), + shutterReadoutTimestamp(0), + errorCodeValid(false), + errorCode(ErrorCode::ERROR_BUFFER), + usePartialResult(partialResults), + numPartialResults(partialCount), + resultQueue(queue), + haveResultMetadata(false), + numBuffersLeft(numBuffers), + frameNumber(0), + partialResultCount(0), + errorStreamId(-1), + hasInputBuffer(hasInput), + collectedResult(1, 10), + expectedPhysicalResults(extraPhysicalResult) {} + }; + + static bool matchDeviceName(const std::string& deviceName, const std::string& providerType, + std::string* deviceVersion, std::string* cameraId); + + static void verify10BitMetadata( + HandleImporter& importer, const InFlightRequest& request, + aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap + profile); + + // Map from frame number to the in-flight request state + typedef std::unordered_map<uint32_t, std::shared_ptr<InFlightRequest>> InFlightMap; + + std::mutex mLock; // Synchronize access to member variables + std::condition_variable mResultCondition; // Condition variable for incoming results + InFlightMap mInflightMap; // Map of all inflight requests + + std::vector<NotifyMsg> mNotifyMessages; // Current notification message + + std::mutex mTorchLock; // Synchronize access to torch status + std::condition_variable mTorchCond; // Condition variable for torch status + TorchModeStatus mTorchStatus; // Current torch status + + // Camera provider service + std::shared_ptr<ICameraProvider> mProvider; + + // Camera device session used by the tests + // Tests should take care of closing this session and setting it back to nullptr in successful + // case. Declared as a field to allow TeadDown function to close the session if a test assertion + // fails. + std::shared_ptr<ICameraDeviceSession> mSession; + + // Camera provider type. + std::string mProviderType; + + HandleImporter mHandleImporter; + + friend class DeviceCb; + friend class SimpleDeviceCb; + friend class TorchProviderCb; +}; + +namespace { +// device@<major>.<minor>/<type>/id +const char* kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/\\s+/(.+)"; +const int32_t kMaxVideoWidth = 4096; +const int32_t kMaxVideoHeight = 2160; + +const int64_t kStreamBufferTimeoutSec = 3; +const int64_t kTorchTimeoutSec = 1; +const char* kDumpOutput = "/dev/null"; +const uint32_t kMaxPreviewWidth = 1920; +const uint32_t kMaxPreviewHeight = 1080; +} // namespace +#endif // HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_ |