android_hardware_camera2_CameraMetadata.cpp revision 70c2207c34cf0e6b3b383b1b1500ff5385aa51a6
170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin/* 270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** 370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** Copyright 2013, The Android Open Source Project 470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** 570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** Licensed under the Apache License, Version 2.0 (the "License"); 670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** you may not use this file except in compliance with the License. 770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** You may obtain a copy of the License at 870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** 970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** http://www.apache.org/licenses/LICENSE-2.0 1070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** 1170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** Unless required by applicable law or agreed to in writing, software 1270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** distributed under the License is distributed on an "AS IS" BASIS, 1370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** See the License for the specific language governing permissions and 1570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin** limitations under the License. 1670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin*/ 1770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 1870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// #define LOG_NDEBUG 0 19b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin// #define LOG_NNDEBUG 0 2070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#define LOG_TAG "CameraMetadata-JNI" 2170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include <utils/Log.h> 2270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 2370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "jni.h" 2470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "JNIHelp.h" 2570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "android_os_Parcel.h" 2670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "android_runtime/AndroidRuntime.h" 2770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 2870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include <camera/CameraMetadata.h> 29b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#include <nativehelper/ScopedUtfChars.h> 30b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#include <nativehelper/ScopedPrimitiveArray.h> 31b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 32b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#if defined(LOG_NNDEBUG) 33b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#if !LOG_NNDEBUG 34b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#define ALOGVV ALOGV 35b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#endif 36b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#else 37b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#define ALOGVV(...) 38b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#endif 3970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// fully-qualified class name 4170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala#define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative" 4270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinusing namespace android; 4470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstruct fields_t { 4670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID metadata_ptr; 4770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 4870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic fields_t fields; 5070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 51b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinnamespace { 52b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstruct Helpers { 53b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin static size_t getTypeSize(uint8_t type) { 54b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (type >= NUM_TYPES) { 55b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type); 56b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return static_cast<size_t>(-1); 57b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 58b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 59b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return camera_metadata_type_size[type]; 60b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 61b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 62b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin static status_t updateAny(CameraMetadata *metadata, 63b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin uint32_t tag, 64b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin uint32_t type, 65b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const void *data, 66b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t dataBytes) { 67b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 68b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (type >= NUM_TYPES) { 69b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type); 70b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return INVALID_OPERATION; 71b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 72b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 73b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t typeSize = getTypeSize(type); 74b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 75b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (dataBytes % typeSize != 0) { 76b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGE("%s: Expected dataBytes (%ud) to be divisible by typeSize " 77b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(%ud)", __FUNCTION__, dataBytes, typeSize); 78b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return BAD_VALUE; 79b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 80b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 81b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t dataCount = dataBytes / typeSize; 82b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 83b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin switch(type) { 84b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#define METADATA_UPDATE(runtime_type, compile_type) \ 85b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin case runtime_type: { \ 86b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const compile_type *dataPtr = \ 87b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin static_cast<const compile_type*>(data); \ 88b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return metadata->update(tag, dataPtr, dataCount); \ 89b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } \ 90b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 91b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_BYTE, uint8_t); 92b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_INT32, int32_t); 93b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_FLOAT, float); 94b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_INT64, int64_t); 95b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_DOUBLE, double); 96b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_RATIONAL, camera_metadata_rational_t); 97b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 98b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin default: { 99b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // unreachable 100b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGE("%s: Unreachable", __FUNCTION__); 101b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return INVALID_OPERATION; 102b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 103b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 104b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 105b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#undef METADATA_UPDATE 106b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 107b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin}; 108b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} // namespace {} 109b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 11070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinextern "C" { 11170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 11270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_classInit(JNIEnv *env, jobject thiz); 113b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName); 114b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag); 11570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 11670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL. 11770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) { 11870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 11970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (thiz == NULL) { 12070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 12170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 12270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 12370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz, fields.metadata_ptr)); 12470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 12570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 12670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Safe access to native pointer from object. Throws if not possible to access. 12770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic CameraMetadata* CameraMetadata_getPointerThrow(JNIEnv *env, jobject thiz, 12870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char* argName = "this") { 12970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 13070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (thiz == NULL) { 13170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Throwing java.lang.NullPointerException for null reference", 13270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 13370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, argName); 13470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 13570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 13670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 13770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz); 13870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 13970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Throwing java.lang.IllegalStateException for closed object", 14070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 14170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowException(env, "java/lang/IllegalStateException", 14270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Metadata object was already closed"); 14370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 14470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 14570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 14670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return metadata; 14770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 14870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 14970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jlong CameraMetadata_allocate(JNIEnv *env, jobject thiz) { 15070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 15170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return reinterpret_cast<jlong>(new CameraMetadata()); 15370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 15470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalastatic jlong CameraMetadata_allocateCopy(JNIEnv *env, jobject thiz, 15670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala jobject other) { 15770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala ALOGV("%s", __FUNCTION__); 15870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 15970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala CameraMetadata* otherMetadata = 16070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala CameraMetadata_getPointerThrow(env, other, "other"); 16170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 16270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala // In case of exception, return 16370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala if (otherMetadata == NULL) return NULL; 16470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 16570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala // Clone native metadata and return new pointer 16670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala return reinterpret_cast<jlong>(new CameraMetadata(*otherMetadata)); 16770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala} 16870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 16970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 17070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jboolean CameraMetadata_isEmpty(JNIEnv *env, jobject thiz) { 17170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 17270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 17370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 17470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 17570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 17670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGW("%s: Returning early due to exception being thrown", 17770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 17870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return JNI_TRUE; // actually throws java exc. 17970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 18070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jboolean empty = metadata->isEmpty(); 18270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Empty returned %d, entry count was %d", 18470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__, empty, metadata->entryCount()); 18570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return empty; 18770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 18870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jint CameraMetadata_getEntryCount(JNIEnv *env, jobject thiz) { 19070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 19170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 19270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 19370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 19470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) return 0; // actually throws java exc. 19570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 19670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return metadata->entryCount(); 19770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 19870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 19970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// idempotent. calling more than once has no effect. 20070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_close(JNIEnv *env, jobject thiz) { 20170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 20270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 20370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz); 20470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 20570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata != NULL) { 20670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin delete metadata; 20770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin env->SetLongField(thiz, fields.metadata_ptr, 0); 20870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 20970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 21070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin LOG_ALWAYS_FATAL_IF(CameraMetadata_getPointerNoThrow(env, thiz) != NULL, 21170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Expected the native ptr to be 0 after #close"); 21270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 21370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 21470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_swap(JNIEnv *env, jobject thiz, jobject other) { 21570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 21670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 21770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 21870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 21970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // order is important: we can't call another JNI method 22070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // if there is an exception pending 22170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) return; 22270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* otherMetadata = CameraMetadata_getPointerThrow(env, other, "other"); 22470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (otherMetadata == NULL) return; 22670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin metadata->swap(*otherMetadata); 22870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 22970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 230b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jbyteArray CameraMetadata_readValues(JNIEnv *env, jobject thiz, jint tag) { 231b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s (tag = %d)", __FUNCTION__, tag); 232b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 233b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 234b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (metadata == NULL) return NULL; 235b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 236b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin int tagType = get_camera_metadata_tag_type(tag); 237b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (tagType == -1) { 238b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 239b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Tag (%d) did not have a type", tag); 240b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return NULL; 241b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 242b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t tagSize = Helpers::getTypeSize(tagType); 243b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 244b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin camera_metadata_entry entry = metadata->find(tag); 245b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (entry.count == 0) { 246b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (!metadata->exists(tag)) { 247b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s: Tag %d does not have any entries", __FUNCTION__, tag); 248b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return NULL; 249b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 250b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // OK: we will return a 0-sized array. 251b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s: Tag %d had an entry, but it had 0 data", __FUNCTION__, 252b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin tag); 253b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 254b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 255b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 256b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jsize byteCount = entry.count * tagSize; 257b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jbyteArray byteArray = env->NewByteArray(byteCount); 258b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (env->ExceptionCheck()) return NULL; 259b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 260b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Copy into java array from native array 261b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ScopedByteArrayRW arrayWriter(env, byteArray); 262b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin memcpy(arrayWriter.get(), entry.data.u8, byteCount); 263b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 264b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return byteArray; 265b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 266b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 267b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic void CameraMetadata_writeValues(JNIEnv *env, jobject thiz, jint tag, jbyteArray src) { 268b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s (tag = %d)", __FUNCTION__, tag); 269b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 270b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 271b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (metadata == NULL) return; 272b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 273b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin int tagType = get_camera_metadata_tag_type(tag); 274b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (tagType == -1) { 275b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 276b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Tag (%d) did not have a type", tag); 277b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return; 278b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 279b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t tagSize = Helpers::getTypeSize(tagType); 280b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 281b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin status_t res; 282b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 283b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (src == NULL) { 284b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // If array is NULL, delete the entry 2853710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin if (metadata->exists(tag)) { 2863710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin res = metadata->erase(tag); 2873710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin ALOGV("%s: Erase values (res = %d)", __FUNCTION__, res); 2883710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin } else { 2893710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin res = OK; 2903710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin ALOGV("%s: Don't need to erase", __FUNCTION__); 2913710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin } 292b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 293b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Copy from java array into native array 294b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ScopedByteArrayRO arrayReader(env, src); 295b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (arrayReader.get() == NULL) return; 296b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 297b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin res = Helpers::updateAny(metadata, static_cast<uint32_t>(tag), 298b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin tagType, arrayReader.get(), arrayReader.size()); 2993710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin 3003710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin ALOGV("%s: Update values (res = %d)", __FUNCTION__, res); 301b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 302b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 303b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (res == OK) { 304b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return; 305b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else if (res == BAD_VALUE) { 306b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 307b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Src byte array was poorly formed"); 308b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else if (res == INVALID_OPERATION) { 309b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 310b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Internal error while trying to update metadata"); 311b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 312b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 313b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Unknown error (%d) while trying to update " 314b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "metadata", res); 315b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 316b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 317b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 31870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_readFromParcel(JNIEnv *env, jobject thiz, jobject parcel) { 31970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 32070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 32170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 32270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 32370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 32470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 32570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin Parcel* parcelNative = parcelForJavaObject(env, parcel); 32670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (parcelNative == NULL) { 32770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, "parcel"); 32870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 32970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 33070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 33170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin status_t err; 33270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if ((err = metadata->readFromParcel(parcelNative)) != OK) { 33370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 33470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Failed to read from parcel (error code %d)", err); 33570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 33670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 33770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 33870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 33970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_writeToParcel(JNIEnv *env, jobject thiz, jobject parcel) { 34070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 34170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 34270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 34370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 34470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 34570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 34670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin Parcel* parcelNative = parcelForJavaObject(env, parcel); 34770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (parcelNative == NULL) { 34870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, "parcel"); 34970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 35070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 35170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 35270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin status_t err; 35370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if ((err = metadata->writeToParcel(parcelNative)) != OK) { 35470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 35570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Failed to write to parcel (error code %d)", err); 35670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 35770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 35870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 35970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 36070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} // extern "C" 36170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 36270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin//------------------------------------------------- 36370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 36470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic JNINativeMethod gCameraMetadataMethods[] = { 365b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin// static methods 36670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeClassInit", 36770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()V", 36870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_classInit }, 369b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeGetTagFromKey", 370b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(Ljava/lang/String;)I", 371b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_getTagFromKey }, 372b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeGetTypeFromTag", 373b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(I)I", 374b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_getTypeFromTag }, 375b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin// instance methods 37670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeAllocate", 37770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()J", 37870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_allocate }, 37970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala { "nativeAllocateCopy", 38070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala "(L" CAMERA_METADATA_CLASS_NAME ";)J", 38170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala (void *)CameraMetadata_allocateCopy }, 38270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeIsEmpty", 38370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()Z", 38470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_isEmpty }, 38570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeGetEntryCount", 38670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()I", 38770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_getEntryCount }, 38870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeClose", 38970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()V", 39070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_close }, 39170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeSwap", 39270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(L" CAMERA_METADATA_CLASS_NAME ";)V", 39370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_swap }, 394b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeReadValues", 395b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(I)[B", 396b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_readValues }, 397b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeWriteValues", 398b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(I[B)V", 399b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_writeValues }, 400b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin// Parcelable interface 40170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeReadFromParcel", 40270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(Landroid/os/Parcel;)V", 40370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_readFromParcel }, 40470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeWriteToParcel", 40570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(Landroid/os/Parcel;)V", 40670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_writeToParcel }, 40770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 40870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 40970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstruct field { 41070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *class_name; 41170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *field_name; 41270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *field_type; 41370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID *jfield; 41470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 41570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 41670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic int find_fields(JNIEnv *env, field *fields, int count) 41770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin{ 41870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin for (int i = 0; i < count; i++) { 41970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin field *f = &fields[i]; 42070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jclass clazz = env->FindClass(f->class_name); 42170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (clazz == NULL) { 42270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGE("Can't find %s", f->class_name); 42370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return -1; 42470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 42570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 42670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID field = env->GetFieldID(clazz, f->field_name, f->field_type); 42770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (field == NULL) { 42870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGE("Can't find %s.%s", f->class_name, f->field_name); 42970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return -1; 43070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 43170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 43270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin *(f->jfield) = field; 43370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 43470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 43570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return 0; 43670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 43770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 43870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Get all the required offsets in java class and register native functions 4392f1a2e423e0fbb64467d6fcfa4e82c6384f31210Eino-Ville Talvalaint register_android_hardware_camera2_CameraMetadata(JNIEnv *env) 44070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin{ 44170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // Register native functions 44270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return AndroidRuntime::registerNativeMethods(env, 44370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CAMERA_METADATA_CLASS_NAME, 44470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin gCameraMetadataMethods, 44570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin NELEM(gCameraMetadataMethods)); 44670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 44770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 44870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinextern "C" { 44970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { 45070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // XX: Why do this separately instead of doing it in the register function? 45170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 45270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 45370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin field fields_to_find[] = { 45470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { CAMERA_METADATA_CLASS_NAME, "mMetadataPtr", "J", &fields.metadata_ptr }, 45570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin }; 45670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 45770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // Do this here instead of in register_native_methods, 45870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // since otherwise it will fail to find the fields. 45970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (find_fields(env, fields_to_find, NELEM(fields_to_find)) < 0) 46070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 46170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 46270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jclass clazz = env->FindClass(CAMERA_METADATA_CLASS_NAME); 46370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 464b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 465b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) { 466b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 467b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ScopedUtfChars keyScoped(env, keyName); 468b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *key = keyScoped.c_str(); 469b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (key == NULL) { 470b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // exception thrown by ScopedUtfChars 471b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return 0; 472b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 473b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t keyLength = strlen(key); 474b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 475b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s (key = '%s')", __FUNCTION__, key); 476b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 477b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // First, find the section by the longest string match 478b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *section = NULL; 479b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t sectionIndex = 0; 480b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t sectionLength = 0; 481b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin for (size_t i = 0; i < ANDROID_SECTION_COUNT; ++i) { 482b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *str = camera_metadata_section_names[i]; 483b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGVV("%s: Trying to match against section '%s'", 484b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin __FUNCTION__, str); 485b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (strstr(key, str) == key) { // key begins with the section name 486b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t strLength = strlen(str); 487b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 488b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGVV("%s: Key begins with section name", __FUNCTION__); 489b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 490b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // section name is the longest we've found so far 491b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (section == NULL || sectionLength < strLength) { 492b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin section = str; 493b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin sectionIndex = i; 494b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin sectionLength = strLength; 495b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 496b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGVV("%s: Found new best section (idx %d)", __FUNCTION__, sectionIndex); 497b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 498b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 499b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 500b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 501b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // TODO: vendor ext 502b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // TODO: Make above get_camera_metadata_section_from_name ? 503b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 504b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (section == NULL) { 505b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 506b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Could not find section name for key '%s')", key); 507b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return 0; 508b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 509b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s: Found matched section '%s' (%d)", 510b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin __FUNCTION__, section, sectionIndex); 511b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 512b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 513b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Get the tag name component of the key 514b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *keyTagName = key + sectionLength + 1; // x.y.z -> z 515b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (sectionLength + 1 >= keyLength) { 516b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 517b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Key length too short for key '%s')", key); 518b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 519b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 520b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Match rest of name against the tag names in that section only 521b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd) 522b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin tagBegin = camera_metadata_section_bounds[sectionIndex][0]; 523b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin tagEnd = camera_metadata_section_bounds[sectionIndex][1]; 524b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 525b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin uint32_t tag; 526b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin for (tag = tagBegin; tag < tagEnd; ++tag) { 527b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *tagName = get_camera_metadata_tag_name(tag); 528b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 529b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (strcmp(keyTagName, tagName) == 0) { 530b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s: Found matched tag '%s' (%d)", 531b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin __FUNCTION__, tagName, tag); 532b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin break; 533b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 534b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 535b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 536b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // TODO: vendor ext 537b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // TODO: Make above get_camera_metadata_tag_from_name ? 538b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 539b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (tag == tagEnd) { 540b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 541b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Could not find tag name for key '%s')", key); 542b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return 0; 543b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 544b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 545b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return tag; 546b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 547b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 548b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag) { 549b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin int tagType = get_camera_metadata_tag_type(tag); 550b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (tagType == -1) { 551b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 552b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Tag (%d) did not have a type", tag); 553b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return -1; 554b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 555b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 556b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return tagType; 557b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 558b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 55970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} // extern "C" 560