android_hardware_camera2_CameraMetadata.cpp revision 70725500dcf3b666b43d50563d64705aab58d2d3
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 1970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#define LOG_TAG "CameraMetadata-JNI" 2070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include <utils/Log.h> 2170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 2270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "jni.h" 2370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "JNIHelp.h" 2470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "android_os_Parcel.h" 2570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "android_runtime/AndroidRuntime.h" 2670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 2770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include <camera/CameraMetadata.h> 2870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 2970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// fully-qualified class name 3070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#define CAMERA_METADATA_CLASS_NAME "android/hardware/photography/CameraMetadata" 3170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 3270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinusing namespace android; 3370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 3470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstruct fields_t { 3570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID metadata_ptr; 3670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 3770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 3870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic fields_t fields; 3970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinextern "C" { 4170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_classInit(JNIEnv *env, jobject thiz); 4370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL. 4570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) { 4670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (thiz == NULL) { 4870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 4970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 5070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz, fields.metadata_ptr)); 5270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 5370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Safe access to native pointer from object. Throws if not possible to access. 5570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic CameraMetadata* CameraMetadata_getPointerThrow(JNIEnv *env, jobject thiz, 5670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char* argName = "this") { 5770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (thiz == NULL) { 5970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Throwing java.lang.NullPointerException for null reference", 6070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 6170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, argName); 6270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 6370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 6470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 6570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz); 6670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 6770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Throwing java.lang.IllegalStateException for closed object", 6870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 6970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowException(env, "java/lang/IllegalStateException", 7070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Metadata object was already closed"); 7170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 7270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 7370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 7470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return metadata; 7570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 7670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 7770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jlong CameraMetadata_allocate(JNIEnv *env, jobject thiz) { 7870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 7970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 8070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return reinterpret_cast<jlong>(new CameraMetadata()); 8170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 8270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 8370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jboolean CameraMetadata_isEmpty(JNIEnv *env, jobject thiz) { 8470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 8570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 8670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 8770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 8870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 8970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGW("%s: Returning early due to exception being thrown", 9070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 9170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return JNI_TRUE; // actually throws java exc. 9270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 9370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 9470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jboolean empty = metadata->isEmpty(); 9570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 9670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Empty returned %d, entry count was %d", 9770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__, empty, metadata->entryCount()); 9870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 9970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return empty; 10070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 10170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 10270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jint CameraMetadata_getEntryCount(JNIEnv *env, jobject thiz) { 10370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 10470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 10570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 10670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 10770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) return 0; // actually throws java exc. 10870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 10970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return metadata->entryCount(); 11070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 11170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 11270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// idempotent. calling more than once has no effect. 11370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_close(JNIEnv *env, jobject thiz) { 11470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 11570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 11670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz); 11770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 11870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata != NULL) { 11970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin delete metadata; 12070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin env->SetLongField(thiz, fields.metadata_ptr, 0); 12170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 12270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 12370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin LOG_ALWAYS_FATAL_IF(CameraMetadata_getPointerNoThrow(env, thiz) != NULL, 12470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Expected the native ptr to be 0 after #close"); 12570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 12670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 12770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_swap(JNIEnv *env, jobject thiz, jobject other) { 12870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 12970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 13070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 13170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 13270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // order is important: we can't call another JNI method 13370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // if there is an exception pending 13470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) return; 13570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 13670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* otherMetadata = CameraMetadata_getPointerThrow(env, other, "other"); 13770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 13870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (otherMetadata == NULL) return; 13970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 14070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin metadata->swap(*otherMetadata); 14170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 14270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 14370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_readFromParcel(JNIEnv *env, jobject thiz, jobject parcel) { 14470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 14570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 14670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 14770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 14870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 14970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin Parcel* parcelNative = parcelForJavaObject(env, parcel); 15170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (parcelNative == NULL) { 15270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, "parcel"); 15370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 15470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 15570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin status_t err; 15770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if ((err = metadata->readFromParcel(parcelNative)) != OK) { 15870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 15970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Failed to read from parcel (error code %d)", err); 16070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 16170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 16270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 16370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 16470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_writeToParcel(JNIEnv *env, jobject thiz, jobject parcel) { 16570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 16670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 16770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 16870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 16970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 17070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 17170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin Parcel* parcelNative = parcelForJavaObject(env, parcel); 17270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (parcelNative == NULL) { 17370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, "parcel"); 17470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 17570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 17670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 17770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin status_t err; 17870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if ((err = metadata->writeToParcel(parcelNative)) != OK) { 17970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 18070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Failed to write to parcel (error code %d)", err); 18170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 18270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 18370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 18470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} // extern "C" 18670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin//------------------------------------------------- 18870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic JNINativeMethod gCameraMetadataMethods[] = { 19070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeClassInit", 19170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()V", 19270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_classInit }, 19370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeAllocate", 19470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()J", 19570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_allocate }, 19670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeIsEmpty", 19770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()Z", 19870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_isEmpty }, 19970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeGetEntryCount", 20070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()I", 20170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_getEntryCount }, 20270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeClose", 20370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()V", 20470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_close }, 20570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeSwap", 20670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(L" CAMERA_METADATA_CLASS_NAME ";)V", 20770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_swap }, 20870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeReadFromParcel", 20970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(Landroid/os/Parcel;)V", 21070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_readFromParcel }, 21170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeWriteToParcel", 21270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(Landroid/os/Parcel;)V", 21370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_writeToParcel }, 21470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 21570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 21670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstruct field { 21770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *class_name; 21870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *field_name; 21970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *field_type; 22070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID *jfield; 22170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 22270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic int find_fields(JNIEnv *env, field *fields, int count) 22470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin{ 22570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin for (int i = 0; i < count; i++) { 22670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin field *f = &fields[i]; 22770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jclass clazz = env->FindClass(f->class_name); 22870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (clazz == NULL) { 22970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGE("Can't find %s", f->class_name); 23070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return -1; 23170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 23270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID field = env->GetFieldID(clazz, f->field_name, f->field_type); 23470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (field == NULL) { 23570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGE("Can't find %s.%s", f->class_name, f->field_name); 23670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return -1; 23770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 23870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin *(f->jfield) = field; 24070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 24170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 24270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return 0; 24370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 24470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 24570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Get all the required offsets in java class and register native functions 24670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinint register_android_hardware_photography_CameraMetadata(JNIEnv *env) 24770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin{ 24870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // Register native functions 24970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return AndroidRuntime::registerNativeMethods(env, 25070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CAMERA_METADATA_CLASS_NAME, 25170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin gCameraMetadataMethods, 25270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin NELEM(gCameraMetadataMethods)); 25370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 25470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 25570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinextern "C" { 25670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { 25770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // XX: Why do this separately instead of doing it in the register function? 25870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 25970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 26070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin field fields_to_find[] = { 26170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { CAMERA_METADATA_CLASS_NAME, "mMetadataPtr", "J", &fields.metadata_ptr }, 26270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin }; 26370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 26470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // Do this here instead of in register_native_methods, 26570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // since otherwise it will fail to find the fields. 26670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (find_fields(env, fields_to_find, NELEM(fields_to_find)) < 0) 26770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 26870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 26970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jclass clazz = env->FindClass(CAMERA_METADATA_CLASS_NAME); 27070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 27170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} // extern "C" 272