am 7469060e: Merge "Make vendor keys visible in Camera2 java APIs." into mnc-dev

* commit '7469060e7855ca5b32f66fbad1a0a4f88737c754':
  Make vendor keys visible in Camera2 java APIs.
This commit is contained in:
Ruben Brunk
2015-08-03 16:16:12 +00:00
committed by Android Git Automerger
3 changed files with 203 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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)
@@ -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.
*

View File

@@ -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"
@@ -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;
};
@@ -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);
@@ -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 },
@@ -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,
@@ -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__);
@@ -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);