2323#include < utils/Vector.h>
2424#include < utils/SortedVector.h>
2525#include < utils/KeyedVector.h>
26+ #include < stdio.h>
2627#include < string.h>
28+ #include < vector>
2729
2830#include " jni.h"
2931#include " JNIHelp.h"
@@ -45,9 +47,30 @@ static const bool kIsDebug = false;
4547
4648// fully-qualified class name
4749#define CAMERA_METADATA_CLASS_NAME " android/hardware/camera2/impl/CameraMetadataNative"
50+ #define CHARACTERISTICS_KEY_CLASS_NAME " android/hardware/camera2/CameraCharacteristics$Key"
51+ #define REQUEST_KEY_CLASS_NAME " android/hardware/camera2/CaptureRequest$Key"
52+ #define RESULT_KEY_CLASS_NAME " android/hardware/camera2/CaptureResult$Key"
4853
4954using namespace android ;
5055
56+ static struct metadata_java_key_offsets_t {
57+ jclass mCharacteristicsKey ;
58+ jclass mResultKey ;
59+ jclass mRequestKey ;
60+ jmethodID mCharacteristicsConstr ;
61+ jmethodID mResultConstr ;
62+ jmethodID mRequestConstr ;
63+ jclass mByteArray ;
64+ jclass mInt32Array ;
65+ jclass mFloatArray ;
66+ jclass mInt64Array ;
67+ jclass mDoubleArray ;
68+ jclass mRationalArray ;
69+ jclass mArrayList ;
70+ jmethodID mArrayListConstr ;
71+ jmethodID mArrayListAdd ;
72+ } gMetadataOffsets ;
73+
5174struct fields_t {
5275 jfieldID metadata_ptr;
5376};
@@ -141,6 +164,7 @@ struct Helpers {
141164extern " C" {
142165
143166static void CameraMetadata_classInit (JNIEnv *env, jobject thiz);
167+ static jobject CameraMetadata_getAllVendorKeys (JNIEnv* env, jobject thiz, jclass keyType);
144168static jint CameraMetadata_getTagFromKey (JNIEnv *env, jobject thiz, jstring keyName);
145169static jint CameraMetadata_getTypeFromTag (JNIEnv *env, jobject thiz, jint tag);
146170static jint CameraMetadata_setupGlobalVendorTagDescriptor (JNIEnv *env, jobject thiz);
@@ -510,6 +534,9 @@ static JNINativeMethod gCameraMetadataMethods[] = {
510534 { " nativeClassInit" ,
511535 " ()V" ,
512536 (void *)CameraMetadata_classInit },
537+ { " nativeGetAllVendorKeys" ,
538+ " (Ljava/lang/Class;)Ljava/util/ArrayList;" ,
539+ (void *)CameraMetadata_getAllVendorKeys},
513540 { " nativeGetTagFromKey" ,
514541 " (Ljava/lang/String;)I" ,
515542 (void *)CameraMetadata_getTagFromKey },
@@ -588,6 +615,44 @@ static int find_fields(JNIEnv *env, field *fields, int count)
588615// Get all the required offsets in java class and register native functions
589616int register_android_hardware_camera2_CameraMetadata (JNIEnv *env)
590617{
618+
619+ // Store global references to Key-related classes and methods used natively
620+ jclass characteristicsKeyClazz = FindClassOrDie (env, CHARACTERISTICS_KEY_CLASS_NAME);
621+ jclass requestKeyClazz = FindClassOrDie (env, REQUEST_KEY_CLASS_NAME);
622+ jclass resultKeyClazz = FindClassOrDie (env, RESULT_KEY_CLASS_NAME);
623+ gMetadataOffsets .mCharacteristicsKey = MakeGlobalRefOrDie (env, characteristicsKeyClazz);
624+ gMetadataOffsets .mRequestKey = MakeGlobalRefOrDie (env, requestKeyClazz);
625+ gMetadataOffsets .mResultKey = MakeGlobalRefOrDie (env, resultKeyClazz);
626+ gMetadataOffsets .mCharacteristicsConstr = GetMethodIDOrDie (env,
627+ gMetadataOffsets .mCharacteristicsKey , " <init>" ,
628+ " (Ljava/lang/String;Ljava/lang/Class;)V" );
629+ gMetadataOffsets .mRequestConstr = GetMethodIDOrDie (env,
630+ gMetadataOffsets .mRequestKey , " <init>" , " (Ljava/lang/String;Ljava/lang/Class;)V" );
631+ gMetadataOffsets .mResultConstr = GetMethodIDOrDie (env,
632+ gMetadataOffsets .mResultKey , " <init>" , " (Ljava/lang/String;Ljava/lang/Class;)V" );
633+
634+ // Store global references for primitive array types used by Keys
635+ jclass byteClazz = FindClassOrDie (env, " [B" );
636+ jclass int32Clazz = FindClassOrDie (env, " [I" );
637+ jclass floatClazz = FindClassOrDie (env, " [F" );
638+ jclass int64Clazz = FindClassOrDie (env, " [J" );
639+ jclass doubleClazz = FindClassOrDie (env, " [D" );
640+ jclass rationalClazz = FindClassOrDie (env, " [Landroid/util/Rational;" );
641+ gMetadataOffsets .mByteArray = MakeGlobalRefOrDie (env, byteClazz);
642+ gMetadataOffsets .mInt32Array = MakeGlobalRefOrDie (env, int32Clazz);
643+ gMetadataOffsets .mFloatArray = MakeGlobalRefOrDie (env, floatClazz);
644+ gMetadataOffsets .mInt64Array = MakeGlobalRefOrDie (env, int64Clazz);
645+ gMetadataOffsets .mDoubleArray = MakeGlobalRefOrDie (env, doubleClazz);
646+ gMetadataOffsets .mRationalArray = MakeGlobalRefOrDie (env, rationalClazz);
647+
648+ // Store global references for ArrayList methods used
649+ jclass arrayListClazz = FindClassOrDie (env, " java/util/ArrayList" );
650+ gMetadataOffsets .mArrayList = MakeGlobalRefOrDie (env, arrayListClazz);
651+ gMetadataOffsets .mArrayListConstr = GetMethodIDOrDie (env, gMetadataOffsets .mArrayList ,
652+ " <init>" , " (I)V" );
653+ gMetadataOffsets .mArrayListAdd = GetMethodIDOrDie (env, gMetadataOffsets .mArrayList ,
654+ " add" , " (Ljava/lang/Object;)Z" );
655+
591656 // Register native functions
592657 return RegisterMethodsOrDie (env,
593658 CAMERA_METADATA_CLASS_NAME,
@@ -596,6 +661,7 @@ int register_android_hardware_camera2_CameraMetadata(JNIEnv *env)
596661}
597662
598663extern " C" {
664+
599665static void CameraMetadata_classInit (JNIEnv *env, jobject thiz) {
600666 // XX: Why do this separately instead of doing it in the register function?
601667 ALOGV (" %s" , __FUNCTION__);
@@ -612,6 +678,107 @@ static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) {
612678 env->FindClass (CAMERA_METADATA_CLASS_NAME);
613679}
614680
681+ static jobject CameraMetadata_getAllVendorKeys (JNIEnv* env, jobject thiz, jclass keyType) {
682+
683+ // Get all vendor tags
684+ sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor ();
685+ if (vTags.get () == nullptr ) {
686+ // No vendor tags.
687+ return NULL ;
688+ }
689+
690+ int count = vTags->getTagCount ();
691+ if (count <= 0 ) {
692+ // No vendor tags.
693+ return NULL ;
694+ }
695+
696+ std::vector<uint32_t > tagIds (count, /* initializer value*/ 0 );
697+ vTags->getTagArray (&tagIds[0 ]);
698+
699+ // Which key class/constructor should we use?
700+ jclass keyClazz;
701+ jmethodID keyConstr;
702+ if (env->IsSameObject (keyType, gMetadataOffsets .mCharacteristicsKey )) {
703+ keyClazz = gMetadataOffsets .mCharacteristicsKey ;
704+ keyConstr = gMetadataOffsets .mCharacteristicsConstr ;
705+ } else if (env->IsSameObject (keyType, gMetadataOffsets .mResultKey )) {
706+ keyClazz = gMetadataOffsets .mResultKey ;
707+ keyConstr = gMetadataOffsets .mResultConstr ;
708+ } else if (env->IsSameObject (keyType, gMetadataOffsets .mRequestKey )) {
709+ keyClazz = gMetadataOffsets .mRequestKey ;
710+ keyConstr = gMetadataOffsets .mRequestConstr ;
711+ } else {
712+ jniThrowException (env, " java/lang/IllegalArgumentException" ,
713+ " Invalid key class given as argument." );
714+ return NULL ;
715+ }
716+
717+ // Allocate arrayList to return
718+ jobject arrayList = env->NewObject (gMetadataOffsets .mArrayList ,
719+ gMetadataOffsets .mArrayListConstr , static_cast <jint>(count));
720+ if (env->ExceptionCheck ()) {
721+ return NULL ;
722+ }
723+
724+ for (uint32_t id : tagIds) {
725+ const char * section = vTags->getSectionName (id);
726+ const char * tag = vTags->getTagName (id);
727+ int type = vTags->getTagType (id);
728+
729+ size_t totalLen = strlen (section) + strlen (tag) + 2 ;
730+ std::vector<char > fullName (totalLen, 0 );
731+ snprintf (&fullName[0 ], totalLen, " %s.%s" , section, tag);
732+
733+ jstring name = env->NewStringUTF (&fullName[0 ]);
734+
735+ if (env->ExceptionCheck ()) {
736+ return NULL ;
737+ }
738+
739+ jclass valueClazz;
740+ switch (type) {
741+ case TYPE_BYTE:
742+ valueClazz = gMetadataOffsets .mByteArray ;
743+ break ;
744+ case TYPE_INT32:
745+ valueClazz = gMetadataOffsets .mInt32Array ;
746+ break ;
747+ case TYPE_FLOAT:
748+ valueClazz = gMetadataOffsets .mFloatArray ;
749+ break ;
750+ case TYPE_INT64:
751+ valueClazz = gMetadataOffsets .mInt64Array ;
752+ break ;
753+ case TYPE_DOUBLE:
754+ valueClazz = gMetadataOffsets .mDoubleArray ;
755+ break ;
756+ case TYPE_RATIONAL:
757+ valueClazz = gMetadataOffsets .mRationalArray ;
758+ break ;
759+ default :
760+ jniThrowExceptionFmt (env, " java/lang/IllegalStateException" ,
761+ " Invalid type %d given for key %s" , type, &fullName[0 ]);
762+ return NULL ;
763+ }
764+
765+ jobject key = env->NewObject (keyClazz, keyConstr, name, valueClazz);
766+ if (env->ExceptionCheck ()) {
767+ return NULL ;
768+ }
769+
770+ env->CallBooleanMethod (arrayList, gMetadataOffsets .mArrayListAdd , key);
771+ if (env->ExceptionCheck ()) {
772+ return NULL ;
773+ }
774+
775+ env->DeleteLocalRef (name);
776+ env->DeleteLocalRef (key);
777+ }
778+
779+ return arrayList;
780+ }
781+
615782static jint CameraMetadata_getTagFromKey (JNIEnv *env, jobject thiz, jstring keyName) {
616783
617784 ScopedUtfChars keyScoped (env, keyName);
0 commit comments