camera2 vndk: Set up vendor tags in CameraManager
Bug: 122477622
Test: AImageReaderVendorTest
Change-Id: I3957d8ee5d1b03c263584e1cd79e937a2f8782ac
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 60c9f85..d96f403 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -137,6 +137,7 @@
shared_libs: [
"libhwbinder",
"libcamera2ndk_vendor",
+ "libcamera_metadata",
"libmediandk",
"libnativewindow",
"libutils",
@@ -144,6 +145,9 @@
"libcutils",
"liblog",
],
+ static_libs: [
+ "android.hardware.camera.common@1.0-helper",
+ ],
cflags: [
"-D__ANDROID_VNDK__",
],
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index f395b44..575ee9d 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -34,7 +34,10 @@
namespace android {
namespace acam {
-using CameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+using frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+using frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptor;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
// Static member definitions
const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
@@ -43,6 +46,104 @@
Mutex CameraManagerGlobal::sLock;
CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
+/**
+ * The vendor tag descriptor class that takes HIDL vendor tag information as
+ * input. Not part of vendor available VendorTagDescriptor class because that class is used by
+ * default HAL implementation code as well.
+ */
+class HidlVendorTagDescriptor : public VendorTagDescriptor {
+public:
+ /**
+ * Create a VendorTagDescriptor object from the HIDL VendorTagSection
+ * vector.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ static status_t createDescriptorFromHidl(const hidl_vec<VendorTagSection>& vts,
+ /*out*/ sp<VendorTagDescriptor> *descriptor);
+};
+
+status_t HidlVendorTagDescriptor::createDescriptorFromHidl(const hidl_vec<VendorTagSection> &vts,
+ sp<VendorTagDescriptor> *descriptor) {
+ int tagCount = 0;
+
+ for (size_t s = 0; s < vts.size(); s++) {
+ tagCount += vts[s].tags.size();
+ }
+
+ if (tagCount < 0 || tagCount > INT32_MAX) {
+ ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
+ return BAD_VALUE;
+ }
+
+ Vector<uint32_t> tagArray;
+ LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+ "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+
+ sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
+ desc->mTagCount = tagCount;
+
+ KeyedVector<uint32_t, String8> tagToSectionMap;
+
+ int idx = 0;
+ for (size_t s = 0; s < vts.size(); s++) {
+ const VendorTagSection& section = vts[s];
+ const char *sectionName = section.sectionName.c_str();
+ if (sectionName == NULL) {
+ ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
+ return BAD_VALUE;
+ }
+ String8 sectionString(sectionName);
+ desc->mSections.add(sectionString);
+
+ for (size_t j = 0; j < section.tags.size(); j++) {
+ uint32_t tag = section.tags[j].tagId;
+ if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+ ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+
+ tagArray.editItemAt(idx++) = section.tags[j].tagId;
+
+ const char *tagName = section.tags[j].tagName.c_str();
+ if (tagName == NULL) {
+ ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+ desc->mTagToNameMap.add(tag, String8(tagName));
+ tagToSectionMap.add(tag, sectionString);
+
+ int tagType = (int) section.tags[j].tagType;
+ if (tagType < 0 || tagType >= NUM_TYPES) {
+ ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+ return BAD_VALUE;
+ }
+ desc->mTagToTypeMap.emplace(tag, tagType);
+ }
+ }
+
+ for (size_t i = 0; i < tagArray.size(); ++i) {
+ uint32_t tag = tagArray[i];
+ String8 sectionString = tagToSectionMap.valueFor(tag);
+
+ // Set up tag to section index map
+ ssize_t index = desc->mSections.indexOf(sectionString);
+ LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+ desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+ // Set up reverse mapping
+ ssize_t reverseIndex = -1;
+ if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+ KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+ reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+ }
+ desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+ }
+
+ *descriptor = std::move(desc);
+ return OK;
+}
+
CameraManagerGlobal&
CameraManagerGlobal::getInstance() {
Mutex::Autolock _l(sLock);
@@ -80,8 +181,34 @@
return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
}
-// TODO: Add back when vendor tags are supported for libcamera2ndk_vendor when
-// the HIDL interface supports querying by vendor id.
+bool CameraManagerGlobal::setupVendorTags() {
+ sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
+ Status status = Status::NO_ERROR;
+ std::vector<ProviderIdAndVendorTagSections> providerIdsAndVts;
+ auto remoteRet = mCameraService->getCameraVendorTagSections([&status, &providerIdsAndVts]
+ (Status s,
+ auto &IdsAndVts) {
+ status = s;
+ providerIdsAndVts = IdsAndVts; });
+
+ if (!remoteRet.isOk() || status != Status::NO_ERROR) {
+ ALOGE("Failed to retrieve VendorTagSections %s", remoteRet.description().c_str());
+ return false;
+ }
+ // Convert each providers VendorTagSections into a VendorTagDescriptor and
+ // add it to the cache
+ for (auto &providerIdAndVts : providerIdsAndVts) {
+ sp<VendorTagDescriptor> vendorTagDescriptor;
+ if (HidlVendorTagDescriptor::createDescriptorFromHidl(providerIdAndVts.vendorTagSections,
+ &vendorTagDescriptor) != OK) {
+ ALOGE("Failed to convert from Hidl: VendorTagDescriptor");
+ return false;
+ }
+ tagCache->addVendorDescriptor(providerIdAndVts.providerId, vendorTagDescriptor);
+ }
+ VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
+ return true;
+}
sp<ICameraService> CameraManagerGlobal::getCameraService() {
Mutex::Autolock _l(mLock);
@@ -140,6 +267,13 @@
if (!remoteRet.isOk() || status != Status::NO_ERROR) {
ALOGE("Failed to add listener to camera service %s", remoteRet.description().c_str());
}
+
+ // Setup vendor tags
+ if (!setupVendorTags()) {
+ ALOGE("Unable to set up vendor tags");
+ return nullptr;
+ }
+
for (auto& c : cameraStatuses) {
onStatusChangedLocked(c);
}
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index c8d640f..6b1365a 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -142,6 +142,8 @@
void onStatusChanged(const CameraStatusAndId &statusAndId);
void onStatusChangedLocked(const CameraStatusAndId &statusAndId);
+ bool setupVendorTags();
+
// Utils for status
static bool validStatus(CameraDeviceStatus status);
static bool isStatusAvailable(CameraDeviceStatus status);
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index f9bb3ac..93108b0 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -37,12 +37,7 @@
#include <media/NdkImage.h>
#include <media/NdkImageReader.h>
#include <cutils/native_handle.h>
-
-//#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
-//#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
-#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
-#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#include <VendorTagDescriptor.h>
namespace {
@@ -53,6 +48,8 @@
static constexpr int kTestImageHeight = 480;
static constexpr int kTestImageFormat = AIMAGE_FORMAT_YUV_420_888;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+
class CameraHelper {
public:
CameraHelper(const char* id, ACameraManager *manager) :
@@ -527,6 +524,8 @@
ALOGE("Failed to get cameraIdList: ret=%d", ret);
return;
}
+ // TODO: Add more rigorous tests for vendor tags
+ ASSERT_NE(VendorTagDescriptorCache::getGlobalVendorTagCache(), nullptr);
if (mCameraIdList->numCameras < 1) {
ALOGW("Device has no camera on board.");
return;