Loading core/java/android/hardware/camera2/CameraMetadata.java +22 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,28 @@ public abstract class CameraMetadata<TKey> { } } ArrayList<TKey> vendorKeys = CameraMetadataNative.getAllVendorKeys(keyClass); if (vendorKeys != null) { for (TKey k : vendorKeys) { String keyName; if (k instanceof CaptureRequest.Key<?>) { keyName = ((CaptureRequest.Key<?>) k).getName(); } else if (k instanceof CaptureResult.Key<?>) { keyName = ((CaptureResult.Key<?>) k).getName(); } else if (k instanceof CameraCharacteristics.Key<?>) { keyName = ((CameraCharacteristics.Key<?>) k).getName(); } else { continue; } if (filterTags == null || Arrays.binarySearch(filterTags, CameraMetadataNative.getTag(keyName)) >= 0) { keyList.add(k); } } } return keyList; } Loading core/java/android/hardware/camera2/impl/CameraMetadataNative.java +14 −0 Original line number Diff line number Diff line Loading @@ -1078,6 +1078,7 @@ public class CameraMetadataNative implements Parcelable { private native synchronized void nativeWriteValues(int tag, byte[] src); private native synchronized void nativeDump() throws IOException; // dump to ALOGD private static native ArrayList nativeGetAllVendorKeys(Class keyClass); private static native int nativeGetTagFromKey(String keyName) throws IllegalArgumentException; private static native int nativeGetTypeFromTag(int tag) Loading Loading @@ -1113,6 +1114,19 @@ public class CameraMetadataNative implements Parcelable { return nativeIsEmpty(); } /** * Return a list containing keys of the given key class for all defined vendor tags. * * @hide */ public static <K> ArrayList<K> getAllVendorKeys(Class<K> keyClass) { if (keyClass == null) { throw new NullPointerException(); } return (ArrayList<K>) nativeGetAllVendorKeys(keyClass); } /** * Convert a key string into the equivalent native tag. * Loading core/jni/android_hardware_camera2_CameraMetadata.cpp +167 −0 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ #include <utils/Vector.h> #include <utils/SortedVector.h> #include <utils/KeyedVector.h> #include <stdio.h> #include <string.h> #include <vector> #include "jni.h" #include "JNIHelp.h" Loading @@ -45,9 +47,30 @@ static const bool kIsDebug = false; // fully-qualified class name #define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative" #define CHARACTERISTICS_KEY_CLASS_NAME "android/hardware/camera2/CameraCharacteristics$Key" #define REQUEST_KEY_CLASS_NAME "android/hardware/camera2/CaptureRequest$Key" #define RESULT_KEY_CLASS_NAME "android/hardware/camera2/CaptureResult$Key" using namespace android; static struct metadata_java_key_offsets_t { jclass mCharacteristicsKey; jclass mResultKey; jclass mRequestKey; jmethodID mCharacteristicsConstr; jmethodID mResultConstr; jmethodID mRequestConstr; jclass mByteArray; jclass mInt32Array; jclass mFloatArray; jclass mInt64Array; jclass mDoubleArray; jclass mRationalArray; jclass mArrayList; jmethodID mArrayListConstr; jmethodID mArrayListAdd; } gMetadataOffsets; struct fields_t { jfieldID metadata_ptr; }; Loading Loading @@ -141,6 +164,7 @@ struct Helpers { extern "C" { static void CameraMetadata_classInit(JNIEnv *env, jobject thiz); static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType); static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName); static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag); static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz); Loading Loading @@ -510,6 +534,9 @@ static JNINativeMethod gCameraMetadataMethods[] = { { "nativeClassInit", "()V", (void *)CameraMetadata_classInit }, { "nativeGetAllVendorKeys", "(Ljava/lang/Class;)Ljava/util/ArrayList;", (void *)CameraMetadata_getAllVendorKeys}, { "nativeGetTagFromKey", "(Ljava/lang/String;)I", (void *)CameraMetadata_getTagFromKey }, Loading Loading @@ -588,6 +615,44 @@ static int find_fields(JNIEnv *env, field *fields, int count) // Get all the required offsets in java class and register native functions int register_android_hardware_camera2_CameraMetadata(JNIEnv *env) { // Store global references to Key-related classes and methods used natively jclass characteristicsKeyClazz = FindClassOrDie(env, CHARACTERISTICS_KEY_CLASS_NAME); jclass requestKeyClazz = FindClassOrDie(env, REQUEST_KEY_CLASS_NAME); jclass resultKeyClazz = FindClassOrDie(env, RESULT_KEY_CLASS_NAME); gMetadataOffsets.mCharacteristicsKey = MakeGlobalRefOrDie(env, characteristicsKeyClazz); gMetadataOffsets.mRequestKey = MakeGlobalRefOrDie(env, requestKeyClazz); gMetadataOffsets.mResultKey = MakeGlobalRefOrDie(env, resultKeyClazz); gMetadataOffsets.mCharacteristicsConstr = GetMethodIDOrDie(env, gMetadataOffsets.mCharacteristicsKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); gMetadataOffsets.mRequestConstr = GetMethodIDOrDie(env, gMetadataOffsets.mRequestKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); gMetadataOffsets.mResultConstr = GetMethodIDOrDie(env, gMetadataOffsets.mResultKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); // Store global references for primitive array types used by Keys jclass byteClazz = FindClassOrDie(env, "[B"); jclass int32Clazz = FindClassOrDie(env, "[I"); jclass floatClazz = FindClassOrDie(env, "[F"); jclass int64Clazz = FindClassOrDie(env, "[J"); jclass doubleClazz = FindClassOrDie(env, "[D"); jclass rationalClazz = FindClassOrDie(env, "[Landroid/util/Rational;"); gMetadataOffsets.mByteArray = MakeGlobalRefOrDie(env, byteClazz); gMetadataOffsets.mInt32Array = MakeGlobalRefOrDie(env, int32Clazz); gMetadataOffsets.mFloatArray = MakeGlobalRefOrDie(env, floatClazz); gMetadataOffsets.mInt64Array = MakeGlobalRefOrDie(env, int64Clazz); gMetadataOffsets.mDoubleArray = MakeGlobalRefOrDie(env, doubleClazz); gMetadataOffsets.mRationalArray = MakeGlobalRefOrDie(env, rationalClazz); // Store global references for ArrayList methods used jclass arrayListClazz = FindClassOrDie(env, "java/util/ArrayList"); gMetadataOffsets.mArrayList = MakeGlobalRefOrDie(env, arrayListClazz); gMetadataOffsets.mArrayListConstr = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList, "<init>", "(I)V"); gMetadataOffsets.mArrayListAdd = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList, "add", "(Ljava/lang/Object;)Z"); // Register native functions return RegisterMethodsOrDie(env, CAMERA_METADATA_CLASS_NAME, Loading @@ -596,6 +661,7 @@ int register_android_hardware_camera2_CameraMetadata(JNIEnv *env) } extern "C" { static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { // XX: Why do this separately instead of doing it in the register function? ALOGV("%s", __FUNCTION__); Loading @@ -612,6 +678,107 @@ static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { env->FindClass(CAMERA_METADATA_CLASS_NAME); } static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType) { // Get all vendor tags sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor(); if (vTags.get() == nullptr) { // No vendor tags. return NULL; } int count = vTags->getTagCount(); if (count <= 0) { // No vendor tags. return NULL; } std::vector<uint32_t> tagIds(count, /*initializer value*/0); vTags->getTagArray(&tagIds[0]); // Which key class/constructor should we use? jclass keyClazz; jmethodID keyConstr; if (env->IsSameObject(keyType, gMetadataOffsets.mCharacteristicsKey)) { keyClazz = gMetadataOffsets.mCharacteristicsKey; keyConstr = gMetadataOffsets.mCharacteristicsConstr; } else if (env->IsSameObject(keyType, gMetadataOffsets.mResultKey)) { keyClazz = gMetadataOffsets.mResultKey; keyConstr = gMetadataOffsets.mResultConstr; } else if (env->IsSameObject(keyType, gMetadataOffsets.mRequestKey)) { keyClazz = gMetadataOffsets.mRequestKey; keyConstr = gMetadataOffsets.mRequestConstr; } else { jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid key class given as argument."); return NULL; } // Allocate arrayList to return jobject arrayList = env->NewObject(gMetadataOffsets.mArrayList, gMetadataOffsets.mArrayListConstr, static_cast<jint>(count)); if (env->ExceptionCheck()) { return NULL; } for (uint32_t id : tagIds) { const char* section = vTags->getSectionName(id); const char* tag = vTags->getTagName(id); int type = vTags->getTagType(id); size_t totalLen = strlen(section) + strlen(tag) + 2; std::vector<char> fullName(totalLen, 0); snprintf(&fullName[0], totalLen, "%s.%s", section, tag); jstring name = env->NewStringUTF(&fullName[0]); if (env->ExceptionCheck()) { return NULL; } jclass valueClazz; switch (type) { case TYPE_BYTE: valueClazz = gMetadataOffsets.mByteArray; break; case TYPE_INT32: valueClazz = gMetadataOffsets.mInt32Array; break; case TYPE_FLOAT: valueClazz = gMetadataOffsets.mFloatArray; break; case TYPE_INT64: valueClazz = gMetadataOffsets.mInt64Array; break; case TYPE_DOUBLE: valueClazz = gMetadataOffsets.mDoubleArray; break; case TYPE_RATIONAL: valueClazz = gMetadataOffsets.mRationalArray; break; default: jniThrowExceptionFmt(env, "java/lang/IllegalStateException", "Invalid type %d given for key %s", type, &fullName[0]); return NULL; } jobject key = env->NewObject(keyClazz, keyConstr, name, valueClazz); if (env->ExceptionCheck()) { return NULL; } env->CallBooleanMethod(arrayList, gMetadataOffsets.mArrayListAdd, key); if (env->ExceptionCheck()) { return NULL; } env->DeleteLocalRef(name); env->DeleteLocalRef(key); } return arrayList; } static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) { ScopedUtfChars keyScoped(env, keyName); Loading Loading
core/java/android/hardware/camera2/CameraMetadata.java +22 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,28 @@ public abstract class CameraMetadata<TKey> { } } ArrayList<TKey> vendorKeys = CameraMetadataNative.getAllVendorKeys(keyClass); if (vendorKeys != null) { for (TKey k : vendorKeys) { String keyName; if (k instanceof CaptureRequest.Key<?>) { keyName = ((CaptureRequest.Key<?>) k).getName(); } else if (k instanceof CaptureResult.Key<?>) { keyName = ((CaptureResult.Key<?>) k).getName(); } else if (k instanceof CameraCharacteristics.Key<?>) { keyName = ((CameraCharacteristics.Key<?>) k).getName(); } else { continue; } if (filterTags == null || Arrays.binarySearch(filterTags, CameraMetadataNative.getTag(keyName)) >= 0) { keyList.add(k); } } } return keyList; } Loading
core/java/android/hardware/camera2/impl/CameraMetadataNative.java +14 −0 Original line number Diff line number Diff line Loading @@ -1078,6 +1078,7 @@ public class CameraMetadataNative implements Parcelable { private native synchronized void nativeWriteValues(int tag, byte[] src); private native synchronized void nativeDump() throws IOException; // dump to ALOGD private static native ArrayList nativeGetAllVendorKeys(Class keyClass); private static native int nativeGetTagFromKey(String keyName) throws IllegalArgumentException; private static native int nativeGetTypeFromTag(int tag) Loading Loading @@ -1113,6 +1114,19 @@ public class CameraMetadataNative implements Parcelable { return nativeIsEmpty(); } /** * Return a list containing keys of the given key class for all defined vendor tags. * * @hide */ public static <K> ArrayList<K> getAllVendorKeys(Class<K> keyClass) { if (keyClass == null) { throw new NullPointerException(); } return (ArrayList<K>) nativeGetAllVendorKeys(keyClass); } /** * Convert a key string into the equivalent native tag. * Loading
core/jni/android_hardware_camera2_CameraMetadata.cpp +167 −0 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ #include <utils/Vector.h> #include <utils/SortedVector.h> #include <utils/KeyedVector.h> #include <stdio.h> #include <string.h> #include <vector> #include "jni.h" #include "JNIHelp.h" Loading @@ -45,9 +47,30 @@ static const bool kIsDebug = false; // fully-qualified class name #define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative" #define CHARACTERISTICS_KEY_CLASS_NAME "android/hardware/camera2/CameraCharacteristics$Key" #define REQUEST_KEY_CLASS_NAME "android/hardware/camera2/CaptureRequest$Key" #define RESULT_KEY_CLASS_NAME "android/hardware/camera2/CaptureResult$Key" using namespace android; static struct metadata_java_key_offsets_t { jclass mCharacteristicsKey; jclass mResultKey; jclass mRequestKey; jmethodID mCharacteristicsConstr; jmethodID mResultConstr; jmethodID mRequestConstr; jclass mByteArray; jclass mInt32Array; jclass mFloatArray; jclass mInt64Array; jclass mDoubleArray; jclass mRationalArray; jclass mArrayList; jmethodID mArrayListConstr; jmethodID mArrayListAdd; } gMetadataOffsets; struct fields_t { jfieldID metadata_ptr; }; Loading Loading @@ -141,6 +164,7 @@ struct Helpers { extern "C" { static void CameraMetadata_classInit(JNIEnv *env, jobject thiz); static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType); static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName); static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag); static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz); Loading Loading @@ -510,6 +534,9 @@ static JNINativeMethod gCameraMetadataMethods[] = { { "nativeClassInit", "()V", (void *)CameraMetadata_classInit }, { "nativeGetAllVendorKeys", "(Ljava/lang/Class;)Ljava/util/ArrayList;", (void *)CameraMetadata_getAllVendorKeys}, { "nativeGetTagFromKey", "(Ljava/lang/String;)I", (void *)CameraMetadata_getTagFromKey }, Loading Loading @@ -588,6 +615,44 @@ static int find_fields(JNIEnv *env, field *fields, int count) // Get all the required offsets in java class and register native functions int register_android_hardware_camera2_CameraMetadata(JNIEnv *env) { // Store global references to Key-related classes and methods used natively jclass characteristicsKeyClazz = FindClassOrDie(env, CHARACTERISTICS_KEY_CLASS_NAME); jclass requestKeyClazz = FindClassOrDie(env, REQUEST_KEY_CLASS_NAME); jclass resultKeyClazz = FindClassOrDie(env, RESULT_KEY_CLASS_NAME); gMetadataOffsets.mCharacteristicsKey = MakeGlobalRefOrDie(env, characteristicsKeyClazz); gMetadataOffsets.mRequestKey = MakeGlobalRefOrDie(env, requestKeyClazz); gMetadataOffsets.mResultKey = MakeGlobalRefOrDie(env, resultKeyClazz); gMetadataOffsets.mCharacteristicsConstr = GetMethodIDOrDie(env, gMetadataOffsets.mCharacteristicsKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); gMetadataOffsets.mRequestConstr = GetMethodIDOrDie(env, gMetadataOffsets.mRequestKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); gMetadataOffsets.mResultConstr = GetMethodIDOrDie(env, gMetadataOffsets.mResultKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); // Store global references for primitive array types used by Keys jclass byteClazz = FindClassOrDie(env, "[B"); jclass int32Clazz = FindClassOrDie(env, "[I"); jclass floatClazz = FindClassOrDie(env, "[F"); jclass int64Clazz = FindClassOrDie(env, "[J"); jclass doubleClazz = FindClassOrDie(env, "[D"); jclass rationalClazz = FindClassOrDie(env, "[Landroid/util/Rational;"); gMetadataOffsets.mByteArray = MakeGlobalRefOrDie(env, byteClazz); gMetadataOffsets.mInt32Array = MakeGlobalRefOrDie(env, int32Clazz); gMetadataOffsets.mFloatArray = MakeGlobalRefOrDie(env, floatClazz); gMetadataOffsets.mInt64Array = MakeGlobalRefOrDie(env, int64Clazz); gMetadataOffsets.mDoubleArray = MakeGlobalRefOrDie(env, doubleClazz); gMetadataOffsets.mRationalArray = MakeGlobalRefOrDie(env, rationalClazz); // Store global references for ArrayList methods used jclass arrayListClazz = FindClassOrDie(env, "java/util/ArrayList"); gMetadataOffsets.mArrayList = MakeGlobalRefOrDie(env, arrayListClazz); gMetadataOffsets.mArrayListConstr = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList, "<init>", "(I)V"); gMetadataOffsets.mArrayListAdd = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList, "add", "(Ljava/lang/Object;)Z"); // Register native functions return RegisterMethodsOrDie(env, CAMERA_METADATA_CLASS_NAME, Loading @@ -596,6 +661,7 @@ int register_android_hardware_camera2_CameraMetadata(JNIEnv *env) } extern "C" { static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { // XX: Why do this separately instead of doing it in the register function? ALOGV("%s", __FUNCTION__); Loading @@ -612,6 +678,107 @@ static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { env->FindClass(CAMERA_METADATA_CLASS_NAME); } static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType) { // Get all vendor tags sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor(); if (vTags.get() == nullptr) { // No vendor tags. return NULL; } int count = vTags->getTagCount(); if (count <= 0) { // No vendor tags. return NULL; } std::vector<uint32_t> tagIds(count, /*initializer value*/0); vTags->getTagArray(&tagIds[0]); // Which key class/constructor should we use? jclass keyClazz; jmethodID keyConstr; if (env->IsSameObject(keyType, gMetadataOffsets.mCharacteristicsKey)) { keyClazz = gMetadataOffsets.mCharacteristicsKey; keyConstr = gMetadataOffsets.mCharacteristicsConstr; } else if (env->IsSameObject(keyType, gMetadataOffsets.mResultKey)) { keyClazz = gMetadataOffsets.mResultKey; keyConstr = gMetadataOffsets.mResultConstr; } else if (env->IsSameObject(keyType, gMetadataOffsets.mRequestKey)) { keyClazz = gMetadataOffsets.mRequestKey; keyConstr = gMetadataOffsets.mRequestConstr; } else { jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid key class given as argument."); return NULL; } // Allocate arrayList to return jobject arrayList = env->NewObject(gMetadataOffsets.mArrayList, gMetadataOffsets.mArrayListConstr, static_cast<jint>(count)); if (env->ExceptionCheck()) { return NULL; } for (uint32_t id : tagIds) { const char* section = vTags->getSectionName(id); const char* tag = vTags->getTagName(id); int type = vTags->getTagType(id); size_t totalLen = strlen(section) + strlen(tag) + 2; std::vector<char> fullName(totalLen, 0); snprintf(&fullName[0], totalLen, "%s.%s", section, tag); jstring name = env->NewStringUTF(&fullName[0]); if (env->ExceptionCheck()) { return NULL; } jclass valueClazz; switch (type) { case TYPE_BYTE: valueClazz = gMetadataOffsets.mByteArray; break; case TYPE_INT32: valueClazz = gMetadataOffsets.mInt32Array; break; case TYPE_FLOAT: valueClazz = gMetadataOffsets.mFloatArray; break; case TYPE_INT64: valueClazz = gMetadataOffsets.mInt64Array; break; case TYPE_DOUBLE: valueClazz = gMetadataOffsets.mDoubleArray; break; case TYPE_RATIONAL: valueClazz = gMetadataOffsets.mRationalArray; break; default: jniThrowExceptionFmt(env, "java/lang/IllegalStateException", "Invalid type %d given for key %s", type, &fullName[0]); return NULL; } jobject key = env->NewObject(keyClazz, keyConstr, name, valueClazz); if (env->ExceptionCheck()) { return NULL; } env->CallBooleanMethod(arrayList, gMetadataOffsets.mArrayListAdd, key); if (env->ExceptionCheck()) { return NULL; } env->DeleteLocalRef(name); env->DeleteLocalRef(key); } return arrayList; } static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) { ScopedUtfChars keyScoped(env, keyName); Loading