Expose timestamp source & thumbnail sizes characteristic
... for virtual camera.
Also fix .setAvailableCharacteristicKeys so it takes effect once
the .build() is called so it's not order dependent.
Bug: 301023410
Bug: 322965201
Test: atest android.hardware.cts.CameraGLTest
Test: atest android.hardware.camera2.cts.ImageReaderTest
Test: presubmit
Change-Id: I1fac9c4561c910f128fa67b7ce11d8e4c6c31b09
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.cc b/services/camera/virtualcamera/VirtualCameraDevice.cc
index 52fe272..5a824cc 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.cc
+++ b/services/camera/virtualcamera/VirtualCameraDevice.cc
@@ -76,22 +76,6 @@
PixelFormat::IMPLEMENTATION_DEFINED, PixelFormat::YCBCR_420_888,
PixelFormat::BLOB};
-struct Resolution {
- Resolution(const int w, const int h) : width(w), height(h) {
- }
-
- bool operator<(const Resolution& other) const {
- return width * height < other.width * other.height;
- }
-
- bool operator==(const Resolution& other) const {
- return width == other.width && height == other.height;
- }
-
- const int width;
- const int height;
-};
-
bool isSupportedOutputFormat(const PixelFormat pixelFormat) {
return std::find(kOutputFormats.begin(), kOutputFormats.end(), pixelFormat) !=
kOutputFormats.end();
@@ -159,6 +143,7 @@
.setSensorOrientation(static_cast<int32_t>(sensorOrientation))
.setSensorReadoutTimestamp(
ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED)
+ .setSensorTimestampSource(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN)
.setSensorPhysicalSize(36.0, 24.0)
.setAvailableFaceDetectModes({ANDROID_STATISTICS_FACE_DETECT_MODE_OFF})
.setAvailableMaxDigitalZoom(1.0)
@@ -177,6 +162,8 @@
.setControlAeLockAvailable(false)
.setControlAvailableAwbModes({ANDROID_CONTROL_AWB_MODE_AUTO})
.setControlZoomRatioRange(/*min=*/1.0, /*max=*/1.0)
+ // TODO(b/301023410) Add JPEG Exif + thumbnail support.
+ .setJpegAvailableThumbnailSizes({Resolution(0, 0)})
.setMaxJpegSize(kMaxJpegSize)
.setMaxNumberOutputStreams(
VirtualCameraDevice::kMaxNumberOfRawStreams,
@@ -187,8 +174,7 @@
.setAvailableRequestKeys({ANDROID_CONTROL_AF_MODE})
.setAvailableResultKeys({ANDROID_CONTROL_AF_MODE})
.setAvailableCapabilities(
- {ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE})
- .setAvailableCharacteristicKeys();
+ {ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE});
// Active array size must correspond to largest supported input resolution.
std::optional<Resolution> maxResolution =
@@ -227,7 +213,7 @@
ALOGV("Adding %zu output configurations", outputConfigurations.size());
builder.setAvailableOutputStreamConfigurations(outputConfigurations);
- auto metadata = builder.build();
+ auto metadata = builder.setAvailableCharacteristicKeys().build();
if (metadata == nullptr) {
ALOGE("Failed to build metadata!");
return CameraMetadata();
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.cc b/services/camera/virtualcamera/util/MetadataBuilder.cc
index bf4758f..b30f2b5 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.cc
+++ b/services/camera/virtualcamera/util/MetadataBuilder.cc
@@ -31,6 +31,7 @@
#include "aidl/android/hardware/camera/device/CameraMetadata.h"
#include "log/log.h"
#include "system/camera_metadata.h"
+#include "util/Util.h"
#include "utils/Errors.h"
namespace android {
@@ -95,6 +96,14 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setSensorTimestampSource(
+ const camera_metadata_enum_android_sensor_info_timestamp_source_t
+ timestampSource) {
+ mEntryMap[ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE] =
+ std::vector<uint8_t>({static_cast<uint8_t>(timestampSource)});
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setSensorTimestamp(
std::chrono::nanoseconds timestamp) {
mEntryMap[ANDROID_SENSOR_TIMESTAMP] =
@@ -247,6 +256,18 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setJpegAvailableThumbnailSizes(
+ const std::vector<Resolution>& thumbnailSizes) {
+ std::vector<int32_t> sizes;
+ sizes.reserve(thumbnailSizes.size() * 2);
+ for (const Resolution& resolution : thumbnailSizes) {
+ sizes.push_back(resolution.width);
+ sizes.push_back(resolution.height);
+ }
+ mEntryMap[ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES] = sizes;
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setMaxNumberOutputStreams(
const int32_t maxRawStreams, const int32_t maxProcessedStreams,
const int32_t maxStallStreams) {
@@ -381,19 +402,23 @@
}
MetadataBuilder& MetadataBuilder::setAvailableCharacteristicKeys() {
- std::vector<camera_metadata_tag_t> availableKeys;
- availableKeys.reserve(mEntryMap.size());
- for (const auto& [key, _] : mEntryMap) {
- if (key != ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS) {
- availableKeys.push_back(key);
- }
- }
- setAvailableCharacteristicKeys(availableKeys);
+ mExtendWithAvailableCharacteristicsKeys = true;
return *this;
}
std::unique_ptr<aidl::android::hardware::camera::device::CameraMetadata>
-MetadataBuilder::build() const {
+MetadataBuilder::build() {
+ if (mExtendWithAvailableCharacteristicsKeys) {
+ std::vector<camera_metadata_tag_t> availableKeys;
+ availableKeys.reserve(mEntryMap.size());
+ for (const auto& [key, _] : mEntryMap) {
+ if (key != ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS) {
+ availableKeys.push_back(key);
+ }
+ }
+ setAvailableCharacteristicKeys(availableKeys);
+ }
+
CameraMetadata metadataHelper;
for (const auto& entry : mEntryMap) {
status_t ret = std::visit(
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.h b/services/camera/virtualcamera/util/MetadataBuilder.h
index d35fa3d..71832d9 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.h
+++ b/services/camera/virtualcamera/util/MetadataBuilder.h
@@ -26,6 +26,7 @@
#include "aidl/android/hardware/camera/device/CameraMetadata.h"
#include "system/camera_metadata.h"
+#include "util/Util.h"
namespace android {
namespace companion {
@@ -91,6 +92,10 @@
// See ANDROID_SENSOR_TIMESTAMP in CameraMetadataTag.aidl.
MetadataBuilder& setSensorTimestamp(std::chrono::nanoseconds timestamp);
+ // See SENSOR_INFO_TIMESTAMP_SOURCE in CameraCharacteristic.java.
+ MetadataBuilder& setSensorTimestampSource(
+ camera_metadata_enum_android_sensor_info_timestamp_source_t timestampSource);
+
// See ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE in CameraMetadataTag.aidl.
MetadataBuilder& setSensorActiveArraySize(int x0, int y0, int x1, int y1);
@@ -183,6 +188,10 @@
// See ANDROID_JPEG_SIZE in CameraMetadataTag.aidl.
MetadataBuilder& setMaxJpegSize(int32_t size);
+ // See JPEG_AVAILABLE_THUMBNAIL_SIZES in CameraCharacteristic.java.
+ MetadataBuilder& setJpegAvailableThumbnailSizes(
+ const std::vector<Resolution>& thumbnailSizes);
+
// The maximum numbers of different types of output streams
// that can be configured and used simultaneously by a camera device.
//
@@ -232,14 +241,14 @@
const std::vector<camera_metadata_tag_t>& keys);
// Extends metadata with ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
- // containing all previously set tags.
+ // containing all set tags.
MetadataBuilder& setAvailableCharacteristicKeys();
// Build CameraMetadata instance.
//
// Returns nullptr in case something went wrong.
std::unique_ptr<::aidl::android::hardware::camera::device::CameraMetadata>
- build() const;
+ build();
private:
// Maps metadata tags to vectors of values for the given tag.
@@ -248,6 +257,8 @@
std::vector<uint8_t>, std::vector<float>,
std::vector<camera_metadata_rational_t>>>
mEntryMap;
+ // Extend metadata with ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS.
+ bool mExtendWithAvailableCharacteristicsKeys = false;
};
} // namespace virtualcamera
diff --git a/services/camera/virtualcamera/util/Util.h b/services/camera/virtualcamera/util/Util.h
index e0a31c0..9f81bb1 100644
--- a/services/camera/virtualcamera/util/Util.h
+++ b/services/camera/virtualcamera/util/Util.h
@@ -52,6 +52,27 @@
int width, int height,
::aidl::android::companion::virtualcamera::Format format, int maxFps);
+// Representation of resolution / size.
+struct Resolution {
+ Resolution(const int w, const int h) : width(w), height(h) {
+ }
+
+ // Order by increasing pixel count, and by width for same pixel count.
+ bool operator<(const Resolution& other) const {
+ const int pixCount = width * height;
+ const int otherPixCount = other.width * other.height;
+ return pixCount == otherPixCount ? width < other.width
+ : pixCount < otherPixCount;
+ }
+
+ bool operator==(const Resolution& other) const {
+ return width == other.width && height == other.height;
+ }
+
+ const int width;
+ const int height;
+};
+
} // namespace virtualcamera
} // namespace companion
} // namespace android