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