diff --git a/camera/metadata/3.5/types.hal b/camera/metadata/3.5/types.hal index 0fec947b97..b9451c852b 100644 --- a/camera/metadata/3.5/types.hal +++ b/camera/metadata/3.5/types.hal @@ -28,10 +28,43 @@ import android.hardware.camera.metadata@3.4; // No new metadata sections added in this revision +/** + * Main enumeration for defining camera metadata tags added in this revision + * + *

Partial documentation is included for each tag; for complete documentation, reference + * '/system/media/camera/docs/docs.html' in the corresponding Android source tree.

+ */ +enum CameraMetadataTag : @3.4::CameraMetadataTag { + /** android.control.availableBokehCapabilities [static, int32[], public] + * + *

The list of bokeh modes that are supported by this camera device, and each bokeh mode's + * maximum streaming (non-stall) size with bokeh effect.

+ */ + ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES = android.hardware.camera.metadata@3.3::CameraMetadataTag:ANDROID_CONTROL_END_3_3, + + /** android.control.bokehMode [dynamic, enum, public] + * + *

Whether bokeh mode is enabled for a particular capture request.

+ */ + ANDROID_CONTROL_BOKEH_MODE, + + ANDROID_CONTROL_END_3_5, + +}; + /* * Enumeration definitions for the various entries that need them */ +/** android.control.bokehMode enumeration values + * @see ANDROID_CONTROL_BOKEH_MODE + */ +enum CameraMetadataEnumAndroidControlBokehMode : uint32_t { + ANDROID_CONTROL_BOKEH_MODE_OFF, + ANDROID_CONTROL_BOKEH_MODE_STILL_CAPTURE, + ANDROID_CONTROL_BOKEH_MODE_CONTINUOUS, +}; + /** android.request.availableCapabilities enumeration values added since v3.4 * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES */ diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index 67d5bbe929..1b0d7cb94f 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -778,6 +778,7 @@ public: const CameraMetadata& chars, int deviceVersion, const hidl_vec& deviceNames); void verifyCameraCharacteristics(Status status, const CameraMetadata& chars); + void verifyBokehCharacteristics(const camera_metadata_t* metadata); void verifyRecommendedConfigs(const CameraMetadata& metadata); void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion); void verifyMonochromeCameraResult( @@ -801,7 +802,7 @@ public: bool isDepthOnly(camera_metadata_t* staticMeta); - static Status getAvailableOutputStreams(camera_metadata_t *staticMeta, + static Status getAvailableOutputStreams(const camera_metadata_t *staticMeta, std::vector &outputStreams, const AvailableStream *threshold = nullptr); static Status getJpegBufferSize(camera_metadata_t *staticMeta, @@ -4856,7 +4857,7 @@ TEST_F(CameraHidlTest, providerDeviceStateNotification) { // Retrieve all valid output stream resolutions from the camera // static characteristics. -Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta, +Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t *staticMeta, std::vector &outputStreams, const AvailableStream *threshold) { AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, @@ -5839,6 +5840,101 @@ void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMeta ADD_FAILURE() << "Get Heic maxJpegAppSegmentsCount failed!"; } } + + verifyBokehCharacteristics(metadata); +} + +void CameraHidlTest::verifyBokehCharacteristics(const camera_metadata_t* metadata) { + camera_metadata_ro_entry entry; + int retcode = 0; + + // Check key availability in capabilities, request and result. + + retcode = find_camera_metadata_ro_entry(metadata, + ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry); + bool hasBokehRequestKey = false; + if ((0 == retcode) && (entry.count > 0)) { + hasBokehRequestKey = std::find(entry.data.i32, entry.data.i32+entry.count, + ANDROID_CONTROL_BOKEH_MODE) != entry.data.i32+entry.count; + } else { + ADD_FAILURE() << "Get camera availableRequestKeys failed!"; + } + + retcode = find_camera_metadata_ro_entry(metadata, + ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry); + bool hasBokehResultKey = false; + if ((0 == retcode) && (entry.count > 0)) { + hasBokehResultKey = std::find(entry.data.i32, entry.data.i32+entry.count, + ANDROID_CONTROL_BOKEH_MODE) != entry.data.i32+entry.count; + } else { + ADD_FAILURE() << "Get camera availableResultKeys failed!"; + } + + retcode = find_camera_metadata_ro_entry(metadata, + ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry); + bool hasBokehCharacteristicsKey = false; + if ((0 == retcode) && (entry.count > 0)) { + hasBokehCharacteristicsKey = std::find(entry.data.i32, entry.data.i32+entry.count, + ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES) != entry.data.i32+entry.count; + } else { + ADD_FAILURE() << "Get camera availableCharacteristicsKeys failed!"; + } + retcode = find_camera_metadata_ro_entry(metadata, + ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES, &entry); + bool hasAvailableBokehCaps = (0 == retcode && entry.count > 0); + + // Bokeh keys must all be available, or all be unavailable. + bool noBokeh = !hasBokehRequestKey && !hasBokehResultKey && !hasBokehCharacteristicsKey && + !hasAvailableBokehCaps; + if (noBokeh) { + return; + } + bool hasBokeh = hasBokehRequestKey && hasBokehResultKey && hasBokehCharacteristicsKey && + hasAvailableBokehCaps; + ASSERT_TRUE(hasBokeh); + + // Must have OFF, and must have one of STILL_CAPTURE and CONTINUOUS. + ASSERT_TRUE(entry.count == 6 || entry.count == 9); + bool hasOffMode = false; + bool hasStillCaptureMode = false; + bool hasContinuousMode = false; + std::vector outputStreams; + ASSERT_EQ(Status::OK, getAvailableOutputStreams(metadata, outputStreams)); + for (int i = 0; i < entry.count; i += 3) { + int32_t mode = entry.data.i32[i]; + int32_t maxWidth = entry.data.i32[i+1]; + int32_t maxHeight = entry.data.i32[i+2]; + switch (mode) { + case ANDROID_CONTROL_BOKEH_MODE_OFF: + hasOffMode = true; + ASSERT_TRUE(maxWidth == 0 && maxHeight == 0); + break; + case ANDROID_CONTROL_BOKEH_MODE_STILL_CAPTURE: + hasStillCaptureMode = true; + break; + case ANDROID_CONTROL_BOKEH_MODE_CONTINUOUS: + hasContinuousMode = true; + break; + default: + ADD_FAILURE() << "Invalid bokehMode advertised: " << mode; + break; + } + + if (mode != ANDROID_CONTROL_BOKEH_MODE_OFF) { + bool sizeSupported = false; + for (const auto& stream : outputStreams) { + if ((stream.format == static_cast(PixelFormat::YCBCR_420_888) || + stream.format == static_cast(PixelFormat::IMPLEMENTATION_DEFINED)) + && stream.width == maxWidth && stream.height == maxHeight) { + sizeSupported = true; + break; + } + } + ASSERT_TRUE(sizeSupported); + } + } + ASSERT_TRUE(hasOffMode); + ASSERT_TRUE(hasStillCaptureMode || hasContinuousMode); } void CameraHidlTest::verifyMonochromeCharacteristics(const CameraMetadata& chars,