Loading camera/ndk/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ cc_test { shared_libs: [ "libhwbinder", "libcamera2ndk_vendor", "libcamera_metadata", "libmediandk", "libnativewindow", "libutils", Loading @@ -144,6 +145,9 @@ cc_test { "libcutils", "liblog", ], static_libs: [ "android.hardware.camera.common@1.0-helper", ], cflags: [ "-D__ANDROID_VNDK__", ], Loading camera/ndk/ndk_vendor/impl/ACameraManager.cpp +137 −3 Original line number Diff line number Diff line Loading @@ -34,7 +34,10 @@ using namespace android::acam; 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"; Loading @@ -43,6 +46,104 @@ const char* CameraManagerGlobal::kContextKey = "CallbackContext"; 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); Loading Loading @@ -80,8 +181,34 @@ static bool isCameraServiceDisabled() { 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); Loading Loading @@ -140,6 +267,13 @@ sp<ICameraService> CameraManagerGlobal::getCameraService() { 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); } Loading camera/ndk/ndk_vendor/impl/ACameraManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,8 @@ class CameraManagerGlobal final : public RefBase { 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); Loading camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp +5 −6 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -53,6 +48,8 @@ static constexpr int kTestImageWidth = 640; 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) : Loading Loading @@ -527,6 +524,8 @@ class AImageReaderVendorTest : public ::testing::Test { 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; Loading Loading
camera/ndk/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ cc_test { shared_libs: [ "libhwbinder", "libcamera2ndk_vendor", "libcamera_metadata", "libmediandk", "libnativewindow", "libutils", Loading @@ -144,6 +145,9 @@ cc_test { "libcutils", "liblog", ], static_libs: [ "android.hardware.camera.common@1.0-helper", ], cflags: [ "-D__ANDROID_VNDK__", ], Loading
camera/ndk/ndk_vendor/impl/ACameraManager.cpp +137 −3 Original line number Diff line number Diff line Loading @@ -34,7 +34,10 @@ using namespace android::acam; 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"; Loading @@ -43,6 +46,104 @@ const char* CameraManagerGlobal::kContextKey = "CallbackContext"; 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); Loading Loading @@ -80,8 +181,34 @@ static bool isCameraServiceDisabled() { 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); Loading Loading @@ -140,6 +267,13 @@ sp<ICameraService> CameraManagerGlobal::getCameraService() { 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); } Loading
camera/ndk/ndk_vendor/impl/ACameraManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,8 @@ class CameraManagerGlobal final : public RefBase { 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); Loading
camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp +5 −6 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -53,6 +48,8 @@ static constexpr int kTestImageWidth = 640; 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) : Loading Loading @@ -527,6 +524,8 @@ class AImageReaderVendorTest : public ::testing::Test { 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; Loading