camera3: Update CameraMetadata vendor tag handling.
Bug: 12134423
Change-Id: I19380fb5acc3e23a6181d8f858c13457993480fc
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 957f95c..05a99a3 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -18,8 +18,12 @@
// #define LOG_NDEBUG 0
// #define LOG_NNDEBUG 0
#define LOG_TAG "CameraMetadata-JNI"
+#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
#include <string.h>
#include "jni.h"
@@ -483,12 +487,20 @@
ALOGV("%s (key = '%s')", __FUNCTION__, key);
+ sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
+
+ SortedVector<String8> vendorSections = vTags->getAllSectionNames();
+ size_t vendorSectionCount = vendorSections.size();
+
// First, find the section by the longest string match
const char *section = NULL;
size_t sectionIndex = 0;
size_t sectionLength = 0;
- for (size_t i = 0; i < ANDROID_SECTION_COUNT; ++i) {
- const char *str = camera_metadata_section_names[i];
+ size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
+ for (size_t i = 0; i < totalSectionCount; ++i) {
+
+ const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
+ vendorSections[i - ANDROID_SECTION_COUNT].string();
ALOGVV("%s: Trying to match against section '%s'",
__FUNCTION__, str);
if (strstr(key, str) == key) { // key begins with the section name
@@ -502,12 +514,11 @@
sectionIndex = i;
sectionLength = strLength;
- ALOGVV("%s: Found new best section (idx %d)", __FUNCTION__, sectionIndex);
+ ALOGVV("%s: Found new best section (%s)", __FUNCTION__, section);
}
}
}
- // TODO: vendor ext
// TODO: Make above get_camera_metadata_section_from_name ?
if (section == NULL) {
@@ -524,33 +535,47 @@
if (sectionLength + 1 >= keyLength) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
"Key length too short for key '%s')", key);
+ return 0;
}
// Match rest of name against the tag names in that section only
- uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
- tagBegin = camera_metadata_section_bounds[sectionIndex][0];
- tagEnd = camera_metadata_section_bounds[sectionIndex][1];
+ uint32_t tag = 0;
+ if (sectionIndex < ANDROID_SECTION_COUNT) {
+ // Match built-in tags (typically android.*)
+ uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
+ tagBegin = camera_metadata_section_bounds[sectionIndex][0];
+ tagEnd = camera_metadata_section_bounds[sectionIndex][1];
- uint32_t tag;
- for (tag = tagBegin; tag < tagEnd; ++tag) {
- const char *tagName = get_camera_metadata_tag_name(tag);
+ for (tag = tagBegin; tag < tagEnd; ++tag) {
+ const char *tagName = get_camera_metadata_tag_name(tag);
- if (strcmp(keyTagName, tagName) == 0) {
- ALOGV("%s: Found matched tag '%s' (%d)",
- __FUNCTION__, tagName, tag);
- break;
+ if (strcmp(keyTagName, tagName) == 0) {
+ ALOGV("%s: Found matched tag '%s' (%d)",
+ __FUNCTION__, tagName, tag);
+ break;
+ }
+ }
+
+ if (tag == tagEnd) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "Could not find tag name for key '%s')", key);
+ return 0;
+ }
+ } else {
+ // Match vendor tags (typically com.*)
+ const String8 sectionName(section);
+ const String8 tagName(keyTagName);
+
+ status_t res = OK;
+ if ((res = vTags->lookupTag(tagName, sectionName, &tag)) != OK) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "%s: No vendor tag matches key '%s'", __FUNCTION__, key);
+ return 0;
}
}
- // TODO: vendor ext
// TODO: Make above get_camera_metadata_tag_from_name ?
- if (tag == tagEnd) {
- jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
- "Could not find tag name for key '%s')", key);
- return 0;
- }
-
return tag;
}