android_hardware_camera2_CameraMetadata.cpp revision 46d8444631b4b1253a76bfcc78a29d26014d022f
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" 2132ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk#include <utils/Errors.h> 2270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include <utils/Log.h> 2385c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk#include <utils/RefBase.h> 2432ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk#include <utils/Vector.h> 2532ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk#include <utils/SortedVector.h> 2632ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk#include <utils/KeyedVector.h> 2785c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk#include <string.h> 2870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 2970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "jni.h" 3070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "JNIHelp.h" 3170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "android_os_Parcel.h" 3270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include "android_runtime/AndroidRuntime.h" 33f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk#include "android_runtime/android_hardware_camera2_CameraMetadata.h" 3470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 3585c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk#include <binder/IServiceManager.h> 3670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin#include <camera/CameraMetadata.h> 3785c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk#include <camera/ICameraService.h> 3885c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk#include <camera/VendorTagDescriptor.h> 39b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#include <nativehelper/ScopedUtfChars.h> 40b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#include <nativehelper/ScopedPrimitiveArray.h> 41b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 42d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin#include <sys/types.h> // for socketpair 43d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin#include <sys/socket.h> // for socketpair 44d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 45b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#if defined(LOG_NNDEBUG) 46b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#if !LOG_NNDEBUG 47b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#define ALOGVV ALOGV 48b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#endif 49b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#else 50b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#define ALOGVV(...) 51b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#endif 5270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// fully-qualified class name 5470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala#define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative" 5570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinusing namespace android; 5770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstruct fields_t { 5970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID metadata_ptr; 6070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 6170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 6270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic fields_t fields; 6370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 64f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunknamespace android { 65f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk 66f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunkstatus_t CameraMetadata_getNativeMetadata(JNIEnv* env, jobject thiz, 67f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk /*out*/CameraMetadata* metadata) { 68f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk if (!thiz) { 69f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk ALOGE("%s: Invalid java metadata object.", __FUNCTION__); 70f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk return BAD_VALUE; 71f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk } 72f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk 73f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk if (!metadata) { 74f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk ALOGE("%s: Invalid output metadata object.", __FUNCTION__); 75f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk return BAD_VALUE; 76f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk } 77f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk CameraMetadata* nativePtr = reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz, 78f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk fields.metadata_ptr)); 79f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk if (nativePtr == NULL) { 80f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk ALOGE("%s: Invalid native pointer in java metadata object.", __FUNCTION__); 81f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk return BAD_VALUE; 82f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk } 83f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk *metadata = *nativePtr; 84f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk return OK; 85f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk} 86f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk 87f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk} /*namespace android*/ 88f967a5486a78db244624fde4c105aa5e6fa914b9Ruben Brunk 89b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinnamespace { 90b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstruct Helpers { 91b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin static size_t getTypeSize(uint8_t type) { 92b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (type >= NUM_TYPES) { 93b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type); 94b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return static_cast<size_t>(-1); 95b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 96b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 97b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return camera_metadata_type_size[type]; 98b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 99b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 100b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin static status_t updateAny(CameraMetadata *metadata, 101b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin uint32_t tag, 102b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin uint32_t type, 103b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const void *data, 104b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t dataBytes) { 105b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 106b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (type >= NUM_TYPES) { 107b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type); 108b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return INVALID_OPERATION; 109b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 110b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 111b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t typeSize = getTypeSize(type); 112b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 113b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (dataBytes % typeSize != 0) { 11446d8444631b4b1253a76bfcc78a29d26014d022fDan Albert ALOGE("%s: Expected dataBytes (%zu) to be divisible by typeSize " 11546d8444631b4b1253a76bfcc78a29d26014d022fDan Albert "(%zu)", __FUNCTION__, dataBytes, typeSize); 116b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return BAD_VALUE; 117b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 118b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 119b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t dataCount = dataBytes / typeSize; 120b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 121b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin switch(type) { 122b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#define METADATA_UPDATE(runtime_type, compile_type) \ 123b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin case runtime_type: { \ 124b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const compile_type *dataPtr = \ 125b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin static_cast<const compile_type*>(data); \ 126b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return metadata->update(tag, dataPtr, dataCount); \ 127b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } \ 128b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 129b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_BYTE, uint8_t); 130b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_INT32, int32_t); 131b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_FLOAT, float); 132b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_INT64, int64_t); 133b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_DOUBLE, double); 134b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin METADATA_UPDATE(TYPE_RATIONAL, camera_metadata_rational_t); 135b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 136b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin default: { 137b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // unreachable 138b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGE("%s: Unreachable", __FUNCTION__); 139b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return INVALID_OPERATION; 140b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 141b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 142b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 143b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin#undef METADATA_UPDATE 144b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 145b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin}; 146b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} // namespace {} 147b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 14870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinextern "C" { 14970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_classInit(JNIEnv *env, jobject thiz); 151b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName); 152b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag); 15385c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunkstatic jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz); 15470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL. 15670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) { 15770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (thiz == NULL) { 15970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 16070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 16170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 16270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz, fields.metadata_ptr)); 16370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 16470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 16570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Safe access to native pointer from object. Throws if not possible to access. 16670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic CameraMetadata* CameraMetadata_getPointerThrow(JNIEnv *env, jobject thiz, 16770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char* argName = "this") { 16870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 16970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (thiz == NULL) { 17070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Throwing java.lang.NullPointerException for null reference", 17170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 17270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, argName); 17370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 17470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 17570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 17670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz); 17770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 17870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s: Throwing java.lang.IllegalStateException for closed object", 17970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 18070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowException(env, "java/lang/IllegalStateException", 18170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Metadata object was already closed"); 18270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return NULL; 18370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 18470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return metadata; 18670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 18770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 18870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jlong CameraMetadata_allocate(JNIEnv *env, jobject thiz) { 18970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 19070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 19170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return reinterpret_cast<jlong>(new CameraMetadata()); 19270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 19370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 19470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalastatic jlong CameraMetadata_allocateCopy(JNIEnv *env, jobject thiz, 19570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala jobject other) { 19670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala ALOGV("%s", __FUNCTION__); 19770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 19870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala CameraMetadata* otherMetadata = 19970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala CameraMetadata_getPointerThrow(env, other, "other"); 20070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 20170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala // In case of exception, return 20270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala if (otherMetadata == NULL) return NULL; 20370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 20470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala // Clone native metadata and return new pointer 20570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala return reinterpret_cast<jlong>(new CameraMetadata(*otherMetadata)); 20670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala} 20770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 20870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala 20970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jboolean CameraMetadata_isEmpty(JNIEnv *env, jobject thiz) { 21070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 21170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 21270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 21370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 21470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 21570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGW("%s: Returning early due to exception being thrown", 21670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__); 21770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return JNI_TRUE; // actually throws java exc. 21870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 21970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jboolean empty = metadata->isEmpty(); 22170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22246d8444631b4b1253a76bfcc78a29d26014d022fDan Albert ALOGV("%s: Empty returned %d, entry count was %zu", 22370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin __FUNCTION__, empty, metadata->entryCount()); 22470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return empty; 22670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 22770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic jint CameraMetadata_getEntryCount(JNIEnv *env, jobject thiz) { 22970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 23070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 23270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) return 0; // actually throws java exc. 23470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return metadata->entryCount(); 23670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 23770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// idempotent. calling more than once has no effect. 23970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_close(JNIEnv *env, jobject thiz) { 24070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 24170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 24270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz); 24370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 24470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata != NULL) { 24570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin delete metadata; 24670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin env->SetLongField(thiz, fields.metadata_ptr, 0); 24770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 24870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 24970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin LOG_ALWAYS_FATAL_IF(CameraMetadata_getPointerNoThrow(env, thiz) != NULL, 25070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Expected the native ptr to be 0 after #close"); 25170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 25270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 25370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_swap(JNIEnv *env, jobject thiz, jobject other) { 25470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 25570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 25670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 25770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 25870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // order is important: we can't call another JNI method 25970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // if there is an exception pending 26070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) return; 26170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 26270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* otherMetadata = CameraMetadata_getPointerThrow(env, other, "other"); 26370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 26470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (otherMetadata == NULL) return; 26570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 26670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin metadata->swap(*otherMetadata); 26770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 26870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 269b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jbyteArray CameraMetadata_readValues(JNIEnv *env, jobject thiz, jint tag) { 270b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s (tag = %d)", __FUNCTION__, tag); 271b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 272b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 273b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (metadata == NULL) return NULL; 274b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 275b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin int tagType = get_camera_metadata_tag_type(tag); 276b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (tagType == -1) { 277b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 278b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Tag (%d) did not have a type", tag); 279b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return NULL; 280b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 281b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t tagSize = Helpers::getTypeSize(tagType); 282b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 283b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin camera_metadata_entry entry = metadata->find(tag); 284b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (entry.count == 0) { 285b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (!metadata->exists(tag)) { 286b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s: Tag %d does not have any entries", __FUNCTION__, tag); 287b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return NULL; 288b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 289b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // OK: we will return a 0-sized array. 290b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s: Tag %d had an entry, but it had 0 data", __FUNCTION__, 291b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin tag); 292b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 293b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 294b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 295b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jsize byteCount = entry.count * tagSize; 296b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jbyteArray byteArray = env->NewByteArray(byteCount); 297b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (env->ExceptionCheck()) return NULL; 298b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 299b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Copy into java array from native array 300b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ScopedByteArrayRW arrayWriter(env, byteArray); 301b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin memcpy(arrayWriter.get(), entry.data.u8, byteCount); 302b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 303b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return byteArray; 304b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 305b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 306b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic void CameraMetadata_writeValues(JNIEnv *env, jobject thiz, jint tag, jbyteArray src) { 307b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s (tag = %d)", __FUNCTION__, tag); 308b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 309b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 310b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (metadata == NULL) return; 311b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 312b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin int tagType = get_camera_metadata_tag_type(tag); 313b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (tagType == -1) { 314b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 315b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Tag (%d) did not have a type", tag); 316b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return; 317b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 318b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 319b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin status_t res; 320b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 321b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (src == NULL) { 322b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // If array is NULL, delete the entry 3233710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin if (metadata->exists(tag)) { 3243710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin res = metadata->erase(tag); 3253710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin ALOGV("%s: Erase values (res = %d)", __FUNCTION__, res); 3263710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin } else { 3273710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin res = OK; 3283710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin ALOGV("%s: Don't need to erase", __FUNCTION__); 3293710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin } 330b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 331b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Copy from java array into native array 332b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ScopedByteArrayRO arrayReader(env, src); 333b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (arrayReader.get() == NULL) return; 334b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 335b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin res = Helpers::updateAny(metadata, static_cast<uint32_t>(tag), 336b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin tagType, arrayReader.get(), arrayReader.size()); 3373710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin 3383710db80d4b9e573d775790e4c9a2ab6e062201eIgor Murashkin ALOGV("%s: Update values (res = %d)", __FUNCTION__, res); 339b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 340b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 341b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (res == OK) { 342b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return; 343b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else if (res == BAD_VALUE) { 344b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 345b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Src byte array was poorly formed"); 346b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else if (res == INVALID_OPERATION) { 347b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 348b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Internal error while trying to update metadata"); 349b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 350b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 351b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Unknown error (%d) while trying to update " 352b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "metadata", res); 353b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 354b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 355b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 356d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinstruct DumpMetadataParams { 357d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin int writeFd; 358d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin const CameraMetadata* metadata; 359d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin}; 360d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 361d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinstatic void* CameraMetadata_writeMetadataThread(void* arg) { 362d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin DumpMetadataParams* p = static_cast<DumpMetadataParams*>(arg); 363d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 364d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin /* 365d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * Write the dumped data, and close the writing side FD. 366d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin */ 367d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin p->metadata->dump(p->writeFd, /*verbosity*/2); 368d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 369d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin if (close(p->writeFd) < 0) { 370d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin ALOGE("%s: Failed to close writeFd (errno = %#x, message = '%s')", 371d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin __FUNCTION__, errno, strerror(errno)); 372d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 373d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 374d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin return NULL; 375d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin} 376d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 377d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinstatic void CameraMetadata_dump(JNIEnv *env, jobject thiz) { 378d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin ALOGV("%s", __FUNCTION__); 379d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 380d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin if (metadata == NULL) { 381d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin return; 382d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 383d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 384d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin /* 385d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * Create a socket pair for local streaming read/writes. 386d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * 387d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * The metadata will be dumped into the write side, 388d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * and then read back out (and logged) via the read side. 389d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin */ 390d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 391d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin int writeFd, readFd; 392d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin { 393d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 394d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin int sv[2]; 395d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin if (socketpair(AF_LOCAL, SOCK_STREAM, /*protocol*/0, &sv[0]) < 0) { 396d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin jniThrowExceptionFmt(env, "java/io/IOException", 397d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin "Failed to create socketpair (errno = %#x, message = '%s')", 398d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin errno, strerror(errno)); 399d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin return; 400d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 401d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin writeFd = sv[0]; 402d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin readFd = sv[1]; 403d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 404d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 405d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin /* 406d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * Create a thread for doing the writing. 407d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * 408d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * The reading and writing must be concurrent, otherwise 409d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * the write will block forever once it exhausts the capped 410d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * buffer size (from getsockopt). 411d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin */ 412d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin pthread_t writeThread; 413d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin DumpMetadataParams params = { 414d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin writeFd, 415d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin metadata 416d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin }; 417d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 418d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin { 419d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin int threadRet = pthread_create(&writeThread, /*attr*/NULL, 420d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin CameraMetadata_writeMetadataThread, (void*)¶ms); 421d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 422d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin if (threadRet != 0) { 423d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin close(writeFd); 424d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 425d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin jniThrowExceptionFmt(env, "java/io/IOException", 426d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin "Failed to create thread for writing (errno = %#x, message = '%s')", 427d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin threadRet, strerror(threadRet)); 428d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 429d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 430d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 431d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin /* 432d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * Read out a byte until stream is complete. Write completed lines 433d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin * to ALOG. 434d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin */ 435d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin { 436d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin char out[] = {'\0', '\0'}; // large enough to append as a string 437d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin String8 logLine; 438d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 439d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin // Read one byte at a time! Very slow but avoids complicated \n scanning. 440d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin ssize_t res; 441d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin while ((res = TEMP_FAILURE_RETRY(read(readFd, &out[0], /*count*/1))) > 0) { 442d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin if (out[0] == '\n') { 443d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin ALOGD("%s", logLine.string()); 444d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin logLine.clear(); 445d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } else { 446d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin logLine.append(out); 447d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 448d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 449d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 450d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin if (res < 0) { 451d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin jniThrowExceptionFmt(env, "java/io/IOException", 452d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin "Failed to read from fd (errno = %#x, message = '%s')", 453d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin errno, strerror(errno)); 454d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin //return; 455d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } else if (!logLine.isEmpty()) { 456d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin ALOGD("%s", logLine.string()); 457d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 458d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 459d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 460d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin int res; 461d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 462d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin // Join until thread finishes. Ensures params/metadata is valid until then. 463d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin if ((res = pthread_join(writeThread, /*retval*/NULL)) != 0) { 464d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin ALOGE("%s: Failed to join thread (errno = %#x, message = '%s')", 465d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin __FUNCTION__, res, strerror(res)); 466d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin } 467d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin} 468d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin 46970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_readFromParcel(JNIEnv *env, jobject thiz, jobject parcel) { 47070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 47170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 47270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 47370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 47470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 47570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 47670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin Parcel* parcelNative = parcelForJavaObject(env, parcel); 47770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (parcelNative == NULL) { 47870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, "parcel"); 47970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 48070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 48170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 48270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin status_t err; 48370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if ((err = metadata->readFromParcel(parcelNative)) != OK) { 48470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 48570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Failed to read from parcel (error code %d)", err); 48670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 48770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 48870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 48970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 49070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_writeToParcel(JNIEnv *env, jobject thiz, jobject parcel) { 49170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 49270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); 49370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (metadata == NULL) { 49470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 49570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 49670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 49770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin Parcel* parcelNative = parcelForJavaObject(env, parcel); 49870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (parcelNative == NULL) { 49970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowNullPointerException(env, "parcel"); 50070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 50170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 50270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 50370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin status_t err; 50470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if ((err = metadata->writeToParcel(parcelNative)) != OK) { 50570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 50670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "Failed to write to parcel (error code %d)", err); 50770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 50870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 50970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 51070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 51170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} // extern "C" 51270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 51370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin//------------------------------------------------- 51470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 51570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic JNINativeMethod gCameraMetadataMethods[] = { 516b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin// static methods 51770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeClassInit", 51870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()V", 51970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_classInit }, 520b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeGetTagFromKey", 521b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(Ljava/lang/String;)I", 522b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_getTagFromKey }, 523b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeGetTypeFromTag", 524b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(I)I", 525b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_getTypeFromTag }, 52685c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk { "nativeSetupGlobalVendorTagDescriptor", 52785c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk "()I", 52885c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk (void*)CameraMetadata_setupGlobalVendorTagDescriptor }, 529b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin// instance methods 53070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeAllocate", 53170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()J", 53270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_allocate }, 53370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala { "nativeAllocateCopy", 53470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala "(L" CAMERA_METADATA_CLASS_NAME ";)J", 53570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala (void *)CameraMetadata_allocateCopy }, 53670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeIsEmpty", 53770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()Z", 53870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_isEmpty }, 53970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeGetEntryCount", 54070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()I", 54170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_getEntryCount }, 54270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeClose", 54370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "()V", 54470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void*)CameraMetadata_close }, 54570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeSwap", 54670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(L" CAMERA_METADATA_CLASS_NAME ";)V", 54770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_swap }, 548b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeReadValues", 549b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(I)[B", 550b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_readValues }, 551b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin { "nativeWriteValues", 552b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "(I[B)V", 553b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin (void *)CameraMetadata_writeValues }, 554d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin { "nativeDump", 555d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin "()V", 556d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin (void *)CameraMetadata_dump }, 557b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin// Parcelable interface 55870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeReadFromParcel", 55970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(Landroid/os/Parcel;)V", 56070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_readFromParcel }, 56170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { "nativeWriteToParcel", 56270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin "(Landroid/os/Parcel;)V", 56370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin (void *)CameraMetadata_writeToParcel }, 56470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 56570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 56670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstruct field { 56770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *class_name; 56870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *field_name; 56970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin const char *field_type; 57070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID *jfield; 57170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin}; 57270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 57370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic int find_fields(JNIEnv *env, field *fields, int count) 57470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin{ 57570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin for (int i = 0; i < count; i++) { 57670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin field *f = &fields[i]; 57770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jclass clazz = env->FindClass(f->class_name); 57870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (clazz == NULL) { 57970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGE("Can't find %s", f->class_name); 58070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return -1; 58170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 58270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 58370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin jfieldID field = env->GetFieldID(clazz, f->field_name, f->field_type); 58470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (field == NULL) { 58570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGE("Can't find %s.%s", f->class_name, f->field_name); 58670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return -1; 58770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 58870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 58970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin *(f->jfield) = field; 59070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 59170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 59270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return 0; 59370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 59470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 59570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin// Get all the required offsets in java class and register native functions 5962f1a2e423e0fbb64467d6fcfa4e82c6384f31210Eino-Ville Talvalaint register_android_hardware_camera2_CameraMetadata(JNIEnv *env) 59770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin{ 59870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // Register native functions 59970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return AndroidRuntime::registerNativeMethods(env, 60070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin CAMERA_METADATA_CLASS_NAME, 60170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin gCameraMetadataMethods, 60270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin NELEM(gCameraMetadataMethods)); 60370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 60470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 60570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinextern "C" { 60670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinstatic void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { 60770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // XX: Why do this separately instead of doing it in the register function? 60870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin ALOGV("%s", __FUNCTION__); 60970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 61070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin field fields_to_find[] = { 61170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin { CAMERA_METADATA_CLASS_NAME, "mMetadataPtr", "J", &fields.metadata_ptr }, 61270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin }; 61370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 61470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // Do this here instead of in register_native_methods, 61570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // since otherwise it will fail to find the fields. 61670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (find_fields(env, fields_to_find, NELEM(fields_to_find)) < 0) 61770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 61870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 6190f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe env->FindClass(CAMERA_METADATA_CLASS_NAME); 62070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 621b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 622b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) { 623b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 624b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ScopedUtfChars keyScoped(env, keyName); 625b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *key = keyScoped.c_str(); 626b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (key == NULL) { 627b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // exception thrown by ScopedUtfChars 628b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return 0; 629b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 630b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t keyLength = strlen(key); 631b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 632b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGV("%s (key = '%s')", __FUNCTION__, key); 633b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 63432ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor(); 63532ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk 6363c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin SortedVector<String8> vendorSections; 6373c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin size_t vendorSectionCount = 0; 6383c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 639feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (vTags != NULL) { 6403c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin vendorSections = vTags->getAllSectionNames(); 6413c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin vendorSectionCount = vendorSections.size(); 6423c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 64332ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk 644b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // First, find the section by the longest string match 645b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *section = NULL; 646b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t sectionIndex = 0; 647b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t sectionLength = 0; 64832ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount; 64932ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk for (size_t i = 0; i < totalSectionCount; ++i) { 65032ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk 65132ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] : 65232ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk vendorSections[i - ANDROID_SECTION_COUNT].string(); 653b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGVV("%s: Trying to match against section '%s'", 654b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin __FUNCTION__, str); 655b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (strstr(key, str) == key) { // key begins with the section name 656b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin size_t strLength = strlen(str); 657b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 658b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin ALOGVV("%s: Key begins with section name", __FUNCTION__); 659b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 660b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // section name is the longest we've found so far 661b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (section == NULL || sectionLength < strLength) { 662b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin section = str; 663b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin sectionIndex = i; 664b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin sectionLength = strLength; 665b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 66632ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk ALOGVV("%s: Found new best section (%s)", __FUNCTION__, section); 667b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 668b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 669b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 670b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 671b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // TODO: Make above get_camera_metadata_section_from_name ? 672b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 673b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (section == NULL) { 674b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 675b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Could not find section name for key '%s')", key); 676b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return 0; 677b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } else { 67846d8444631b4b1253a76bfcc78a29d26014d022fDan Albert ALOGV("%s: Found matched section '%s' (%zu)", 679b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin __FUNCTION__, section, sectionIndex); 680b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 681b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 682b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Get the tag name component of the key 683b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin const char *keyTagName = key + sectionLength + 1; // x.y.z -> z 684b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (sectionLength + 1 >= keyLength) { 685b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 686b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Key length too short for key '%s')", key); 68732ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk return 0; 688b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 689b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 690b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // Match rest of name against the tag names in that section only 69132ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk uint32_t tag = 0; 69232ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk if (sectionIndex < ANDROID_SECTION_COUNT) { 69332ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk // Match built-in tags (typically android.*) 69432ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd) 69532ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk tagBegin = camera_metadata_section_bounds[sectionIndex][0]; 69632ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk tagEnd = camera_metadata_section_bounds[sectionIndex][1]; 69732ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk 69832ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk for (tag = tagBegin; tag < tagEnd; ++tag) { 69932ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk const char *tagName = get_camera_metadata_tag_name(tag); 70032ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk 70132ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk if (strcmp(keyTagName, tagName) == 0) { 70232ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk ALOGV("%s: Found matched tag '%s' (%d)", 70332ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk __FUNCTION__, tagName, tag); 70432ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk break; 70532ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk } 70632ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk } 70732ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk 70832ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk if (tag == tagEnd) { 70932ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 71032ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk "Could not find tag name for key '%s')", key); 71132ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk return 0; 71232ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk } 713feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else if (vTags != NULL) { 71432ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk // Match vendor tags (typically com.*) 71532ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk const String8 sectionName(section); 71632ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk const String8 tagName(keyTagName); 71732ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk 71832ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk status_t res = OK; 71932ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk if ((res = vTags->lookupTag(tagName, sectionName, &tag)) != OK) { 72032ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 72132ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk "%s: No vendor tag matches key '%s'", __FUNCTION__, key); 72232ef3ae085288597fb86ab97e42ced1da9691362Ruben Brunk return 0; 723b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 724b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 725b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 726b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin // TODO: Make above get_camera_metadata_tag_from_name ? 727b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 728b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return tag; 729b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 730b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 731b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkinstatic jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag) { 732b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin int tagType = get_camera_metadata_tag_type(tag); 733b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin if (tagType == -1) { 734b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 735b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin "Tag (%d) did not have a type", tag); 736b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return -1; 737b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin } 738b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 739b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin return tagType; 740b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin} 741b519cc52ecba8f44da31173c9fc90a7b66d52b79Igor Murashkin 74285c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunkstatic jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz) { 74385c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk const String16 NAME("media.camera"); 74485c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk sp<ICameraService> cameraService; 74585c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk status_t err = getService(NAME, /*out*/&cameraService); 74685c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk 74785c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk if (err != OK) { 74885c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk ALOGE("%s: Failed to get camera service, received error %s (%d)", __FUNCTION__, 74985c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk strerror(-err), err); 75085c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk return err; 75185c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk } 75285c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk 75385c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk sp<VendorTagDescriptor> desc; 75485c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk err = cameraService->getCameraVendorTagDescriptor(/*out*/desc); 75585c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk 7565614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin if (err == -EOPNOTSUPP) { 7575614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin ALOGW("%s: Camera HAL too old; does not support vendor tags", __FUNCTION__); 7585614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin VendorTagDescriptor::clearGlobalVendorTagDescriptor(); 7595614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin 7605614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin return OK; 7615614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin } else if (err != OK) { 7625614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin ALOGE("%s: Failed to setup vendor tag descriptors, received error %s (%d)", 7635614cbe64493308dc5330eac5d5ba17202013dc4Igor Murashkin __FUNCTION__, strerror(-err), err); 76485c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk return err; 76585c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk } 76685c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk 76785c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc); 76885c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk 76985c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk return err; 77085c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk} 77185c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk 77270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} // extern "C" 773