summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java23
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java24
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java22
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java20
-rw-r--r--core/java/android/hardware/camera2/impl/CameraMetadataNative.java75
-rw-r--r--core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java67
-rw-r--r--core/jni/Android.mk1
-rw-r--r--core/jni/android_hardware_camera2_CameraMetadata.cpp141
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java12
9 files changed, 337 insertions, 48 deletions
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 2aa6af6f9e3c..46ad3f0eccc9 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -67,6 +67,15 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
*
* @hide
*/
+ public Key(String name, Class<T> type, long vendorId) {
+ mKey = new CameraMetadataNative.Key<T>(name, type, vendorId);
+ }
+
+ /**
+ * Visible for testing and vendor extensions only.
+ *
+ * @hide
+ */
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
@@ -99,6 +108,15 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
}
/**
+ * Return vendor tag id.
+ *
+ * @hide
+ */
+ public long getVendorId() {
+ return mKey.getVendorId();
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -159,6 +177,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
*/
public CameraCharacteristics(CameraMetadataNative properties) {
mProperties = CameraMetadataNative.move(properties);
+ setNativeInstance(mProperties);
}
/**
@@ -227,7 +246,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
}
mKeys = Collections.unmodifiableList(
- getKeysStatic(getClass(), getKeyClass(), this, filterTags));
+ getKeys(getClass(), getKeyClass(), this, filterTags));
return mKeys;
}
@@ -320,7 +339,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
"metadataClass must be a subclass of CameraMetadata");
}
- List<TKey> staticKeyList = CameraCharacteristics.<TKey>getKeysStatic(
+ List<TKey> staticKeyList = getKeys(
metadataClass, keyClass, /*instance*/null, filterTags);
return Collections.unmodifiableList(staticKeyList);
}
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e2896271424b..8c8c49fa6373 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -52,6 +52,7 @@ public abstract class CameraMetadata<TKey> {
private static final String TAG = "CameraMetadataAb";
private static final boolean DEBUG = false;
+ private CameraMetadataNative mNativeInstance = null;
/**
* Set a camera metadata field to a value. The field definitions can be
@@ -89,6 +90,13 @@ public abstract class CameraMetadata<TKey> {
/**
* @hide
*/
+ protected void setNativeInstance(CameraMetadataNative nativeInstance) {
+ mNativeInstance = nativeInstance;
+ }
+
+ /**
+ * @hide
+ */
protected abstract Class<TKey> getKeyClass();
/**
@@ -108,7 +116,7 @@ public abstract class CameraMetadata<TKey> {
public List<TKey> getKeys() {
Class<CameraMetadata<TKey>> thisClass = (Class<CameraMetadata<TKey>>) getClass();
return Collections.unmodifiableList(
- getKeysStatic(thisClass, getKeyClass(), this, /*filterTags*/null));
+ getKeys(thisClass, getKeyClass(), this, /*filterTags*/null));
}
/**
@@ -126,7 +134,7 @@ public abstract class CameraMetadata<TKey> {
* </p>
*/
/*package*/ @SuppressWarnings("unchecked")
- static <TKey> ArrayList<TKey> getKeysStatic(
+ <TKey> ArrayList<TKey> getKeys(
Class<?> type, Class<TKey> keyClass,
CameraMetadata<TKey> instance,
int[] filterTags) {
@@ -173,23 +181,31 @@ public abstract class CameraMetadata<TKey> {
}
}
- ArrayList<TKey> vendorKeys = CameraMetadataNative.getAllVendorKeys(keyClass);
+ if (null == mNativeInstance) {
+ return keyList;
+ }
+
+ ArrayList<TKey> vendorKeys = mNativeInstance.getAllVendorKeys(keyClass);
if (vendorKeys != null) {
for (TKey k : vendorKeys) {
String keyName;
+ long vendorId;
if (k instanceof CaptureRequest.Key<?>) {
keyName = ((CaptureRequest.Key<?>) k).getName();
+ vendorId = ((CaptureRequest.Key<?>) k).getVendorId();
} else if (k instanceof CaptureResult.Key<?>) {
keyName = ((CaptureResult.Key<?>) k).getName();
+ vendorId = ((CaptureResult.Key<?>) k).getVendorId();
} else if (k instanceof CameraCharacteristics.Key<?>) {
keyName = ((CameraCharacteristics.Key<?>) k).getName();
+ vendorId = ((CameraCharacteristics.Key<?>) k).getVendorId();
} else {
continue;
}
if (filterTags == null || Arrays.binarySearch(filterTags,
- CameraMetadataNative.getTag(keyName)) >= 0) {
+ CameraMetadataNative.getTag(keyName, vendorId)) >= 0) {
keyList.add(k);
}
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 12b46c1bf693..1cf8f0314980 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -101,6 +101,15 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
*
* @hide
*/
+ public Key(String name, Class<T> type, long vendorId) {
+ mKey = new CameraMetadataNative.Key<T>(name, type, vendorId);
+ }
+
+ /**
+ * Visible for testing and vendor extensions only.
+ *
+ * @hide
+ */
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
@@ -133,6 +142,15 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
}
/**
+ * Return vendor tag id.
+ *
+ * @hide
+ */
+ public long getVendorId() {
+ return mKey.getVendorId();
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -199,6 +217,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
*/
private CaptureRequest() {
mSettings = new CameraMetadataNative();
+ setNativeInstance(mSettings);
mSurfaceSet = new HashSet<Surface>();
mIsReprocess = false;
mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE;
@@ -212,6 +231,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
@SuppressWarnings("unchecked")
private CaptureRequest(CaptureRequest source) {
mSettings = new CameraMetadataNative(source.mSettings);
+ setNativeInstance(mSettings);
mSurfaceSet = (HashSet<Surface>) source.mSurfaceSet.clone();
mIsReprocess = source.mIsReprocess;
mIsPartOfCHSRequestList = source.mIsPartOfCHSRequestList;
@@ -242,6 +262,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
private CaptureRequest(CameraMetadataNative settings, boolean isReprocess,
int reprocessableSessionId) {
mSettings = CameraMetadataNative.move(settings);
+ setNativeInstance(mSettings);
mSurfaceSet = new HashSet<Surface>();
mIsReprocess = isReprocess;
if (isReprocess) {
@@ -441,6 +462,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
*/
private void readFromParcel(Parcel in) {
mSettings.readFromParcel(in);
+ setNativeInstance(mSettings);
mSurfaceSet.clear();
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3f8b57a3498f..419e3e28d36d 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -78,6 +78,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
*
* @hide
*/
+ public Key(String name, Class<T> type, long vendorId) {
+ mKey = new CameraMetadataNative.Key<T>(name, type, vendorId);
+ }
+
+ /**
+ * Visible for testing and vendor extensions only.
+ *
+ * @hide
+ */
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
@@ -110,6 +119,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
}
/**
+ * Return vendor tag id.
+ *
+ * @hide
+ */
+ public long getVendorId() {
+ return mKey.getVendorId();
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -186,6 +204,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
if (mResults.isEmpty()) {
throw new AssertionError("Results must not be empty");
}
+ setNativeInstance(mResults);
mRequest = parent;
mSequenceId = extras.getRequestId();
mFrameNumber = extras.getFrameNumber();
@@ -215,6 +234,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
throw new AssertionError("Results must not be empty");
}
+ setNativeInstance(mResults);
mRequest = null;
mSequenceId = sequenceId;
mFrameNumber = -1;
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 4d92ab1ccbb9..ebe2fa17a7c2 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -79,10 +79,28 @@ public class CameraMetadataNative implements Parcelable {
public static class Key<T> {
private boolean mHasTag;
private int mTag;
+ private long mVendorId = Long.MAX_VALUE;
private final Class<T> mType;
private final TypeReference<T> mTypeReference;
private final String mName;
private final int mHash;
+
+ /**
+ * @hide
+ */
+ public Key(String name, Class<T> type, long vendorId) {
+ if (name == null) {
+ throw new NullPointerException("Key needs a valid name");
+ } else if (type == null) {
+ throw new NullPointerException("Type needs to be non-null");
+ }
+ mName = name;
+ mType = type;
+ mVendorId = vendorId;
+ mTypeReference = TypeReference.createSpecializedTypeReference(type);
+ mHash = mName.hashCode() ^ mTypeReference.hashCode();
+ }
+
/**
* Visible for testing only.
*
@@ -194,7 +212,7 @@ public class CameraMetadataNative implements Parcelable {
*/
public final int getTag() {
if (!mHasTag) {
- mTag = CameraMetadataNative.getTag(mName);
+ mTag = CameraMetadataNative.getTag(mName, mVendorId);
mHasTag = true;
}
return mTag;
@@ -212,6 +230,15 @@ public class CameraMetadataNative implements Parcelable {
}
/**
+ * Get the vendor tag provider id.
+ *
+ * @hide
+ */
+ public final long getVendorId() {
+ return mVendorId;
+ }
+
+ /**
* Get the type reference backing the type {@code T} for this key.
*
* <p>The distinction is only important if {@code T} is a generic, e.g.
@@ -463,13 +490,14 @@ public class CameraMetadataNative implements Parcelable {
}
private <T> T getBase(Key<T> key) {
- int tag = key.getTag();
+ int tag = nativeGetTagFromKeyLocal(key.getName());
byte[] values = readValues(tag);
if (values == null) {
return null;
}
- Marshaler<T> marshaler = getMarshalerForKey(key);
+ int nativeType = nativeGetTypeFromTagLocal(tag);
+ Marshaler<T> marshaler = getMarshalerForKey(key, nativeType);
ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
return marshaler.unmarshal(buffer);
}
@@ -947,15 +975,15 @@ public class CameraMetadataNative implements Parcelable {
}
private <T> void setBase(Key<T> key, T value) {
- int tag = key.getTag();
-
+ int tag = nativeGetTagFromKeyLocal(key.getName());
if (value == null) {
// Erase the entry
writeValues(tag, /*src*/null);
return;
} // else update the entry to a new value
- Marshaler<T> marshaler = getMarshalerForKey(key);
+ int nativeType = nativeGetTypeFromTagLocal(tag);
+ Marshaler<T> marshaler = getMarshalerForKey(key, nativeType);
int size = marshaler.calculateMarshalSize(value);
// TODO: Optimization. Cache the byte[] and reuse if the size is big enough.
@@ -1092,10 +1120,14 @@ public class CameraMetadataNative implements Parcelable {
private native synchronized void nativeWriteValues(int tag, byte[] src);
private native synchronized void nativeDump() throws IOException; // dump to ALOGD
- private static native ArrayList nativeGetAllVendorKeys(Class keyClass);
- private static native int nativeGetTagFromKey(String keyName)
+ private native synchronized ArrayList nativeGetAllVendorKeys(Class keyClass);
+ private native synchronized int nativeGetTagFromKeyLocal(String keyName)
throws IllegalArgumentException;
- private static native int nativeGetTypeFromTag(int tag)
+ private native synchronized int nativeGetTypeFromTagLocal(int tag)
+ throws IllegalArgumentException;
+ private static native int nativeGetTagFromKey(String keyName, long vendorId)
+ throws IllegalArgumentException;
+ private static native int nativeGetTypeFromTag(int tag, long vendorId)
throws IllegalArgumentException;
/**
@@ -1133,7 +1165,7 @@ public class CameraMetadataNative implements Parcelable {
*
* @hide
*/
- public static <K> ArrayList<K> getAllVendorKeys(Class<K> keyClass) {
+ public <K> ArrayList<K> getAllVendorKeys(Class<K> keyClass) {
if (keyClass == null) {
throw new NullPointerException();
}
@@ -1149,19 +1181,32 @@ public class CameraMetadataNative implements Parcelable {
* @hide
*/
public static int getTag(String key) {
- return nativeGetTagFromKey(key);
+ return nativeGetTagFromKey(key, Long.MAX_VALUE);
+ }
+
+ /**
+ * Convert a key string into the equivalent native tag.
+ *
+ * @throws IllegalArgumentException if the key was not recognized
+ * @throws NullPointerException if the key was null
+ *
+ * @hide
+ */
+ public static int getTag(String key, long vendorId) {
+ return nativeGetTagFromKey(key, vendorId);
}
/**
* Get the underlying native type for a tag.
*
* @param tag An integer tag, see e.g. {@link #getTag}
+ * @param vendorId A vendor tag provider id
* @return An int enum for the metadata type, see e.g. {@link #TYPE_BYTE}
*
* @hide
*/
- public static int getNativeType(int tag) {
- return nativeGetTypeFromTag(tag);
+ public static int getNativeType(int tag, long vendorId) {
+ return nativeGetTypeFromTag(tag, vendorId);
}
/**
@@ -1226,9 +1271,9 @@ public class CameraMetadataNative implements Parcelable {
* @throws UnsupportedOperationException
* if the native/managed type combination for {@code key} is not supported
*/
- private static <T> Marshaler<T> getMarshalerForKey(Key<T> key) {
+ private static <T> Marshaler<T> getMarshalerForKey(Key<T> key, int nativeType) {
return MarshalRegistry.getMarshaler(key.getTypeReference(),
- getNativeType(key.getTag()));
+ nativeType);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
diff --git a/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java b/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java
new file mode 100644
index 000000000000..1f92f6d9ebf1
--- /dev/null
+++ b/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera2.params;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * A class for describing the vendor tag cache declared by a camera HAL module.
+ * Generally only used by the native side of
+ * android.hardware.camera2.impl.CameraMetadataNative
+ *
+ * @hide
+ */
+public final class VendorTagDescriptorCache implements Parcelable {
+
+ private VendorTagDescriptorCache(Parcel source) {
+ }
+
+ public static final Parcelable.Creator<VendorTagDescriptorCache> CREATOR =
+ new Parcelable.Creator<VendorTagDescriptorCache>() {
+ @Override
+ public VendorTagDescriptorCache createFromParcel(Parcel source) {
+ try {
+ VendorTagDescriptorCache vendorDescriptorCache = new VendorTagDescriptorCache(source);
+ return vendorDescriptorCache;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception creating VendorTagDescriptorCache from parcel", e);
+ return null;
+ }
+ }
+
+ @Override
+ public VendorTagDescriptorCache[] newArray(int size) {
+ return new VendorTagDescriptorCache[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (dest == null) {
+ throw new IllegalArgumentException("dest must not be null");
+ }
+ }
+
+ private static final String TAG = "VendorTagDescriptorCache";
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index da5d04d63457..33fabfc4c2a5 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -208,6 +208,7 @@ LOCAL_C_INCLUDES += \
$(TOP)/system/core/include \
$(TOP)/system/core/libappfuse/include \
$(TOP)/system/media/camera/include \
+ $(TOP)/system/media/private/camera/include \
$(TOP)/system/netd/include \
external/giflib \
external/pdfium/public \
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 78a5735279ea..c11ce0fe338e 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -36,6 +36,7 @@
#include <android/hardware/ICameraService.h>
#include <binder/IServiceManager.h>
#include <camera/CameraMetadata.h>
+#include <camera_metadata_hidden.h>
#include <camera/VendorTagDescriptor.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/ScopedPrimitiveArray.h>
@@ -162,8 +163,10 @@ struct Helpers {
extern "C" {
static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType);
-static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
-static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
+static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName, jlong vendorId);
+static jint CameraMetadata_getTagFromKeyLocal(JNIEnv *env, jobject thiz, jstring keyName);
+static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag, jlong vendorId);
+static jint CameraMetadata_getTypeFromTagLocal(JNIEnv *env, jobject thiz, jint tag);
static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz);
// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
@@ -286,7 +289,9 @@ static jbyteArray CameraMetadata_readValues(JNIEnv *env, jobject thiz, jint tag)
CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
if (metadata == NULL) return NULL;
- int tagType = get_camera_metadata_tag_type(tag);
+ const camera_metadata_t *metaBuffer = metadata->getAndLock();
+ int tagType = get_local_camera_metadata_tag_type(tag, metaBuffer);
+ metadata->unlock(metaBuffer);
if (tagType == -1) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
"Tag (%d) did not have a type", tag);
@@ -323,7 +328,9 @@ static void CameraMetadata_writeValues(JNIEnv *env, jobject thiz, jint tag, jbyt
CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
if (metadata == NULL) return;
- int tagType = get_camera_metadata_tag_type(tag);
+ const camera_metadata_t *metaBuffer = metadata->getAndLock();
+ int tagType = get_local_camera_metadata_tag_type(tag, metaBuffer);
+ metadata->unlock(metaBuffer);
if (tagType == -1) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
"Tag (%d) did not have a type", tag);
@@ -528,14 +535,11 @@ static void CameraMetadata_writeToParcel(JNIEnv *env, jobject thiz, jobject parc
static const JNINativeMethod gCameraMetadataMethods[] = {
// static methods
- { "nativeGetAllVendorKeys",
- "(Ljava/lang/Class;)Ljava/util/ArrayList;",
- (void *)CameraMetadata_getAllVendorKeys},
{ "nativeGetTagFromKey",
- "(Ljava/lang/String;)I",
+ "(Ljava/lang/String;J)I",
(void *)CameraMetadata_getTagFromKey },
{ "nativeGetTypeFromTag",
- "(I)I",
+ "(IJ)I",
(void *)CameraMetadata_getTypeFromTag },
{ "nativeSetupGlobalVendorTagDescriptor",
"()I",
@@ -559,6 +563,12 @@ static const JNINativeMethod gCameraMetadataMethods[] = {
{ "nativeSwap",
"(L" CAMERA_METADATA_CLASS_NAME ";)V",
(void *)CameraMetadata_swap },
+ { "nativeGetTagFromKeyLocal",
+ "(Ljava/lang/String;)I",
+ (void *)CameraMetadata_getTagFromKeyLocal },
+ { "nativeGetTypeFromTagLocal",
+ "(I)I",
+ (void *)CameraMetadata_getTypeFromTagLocal },
{ "nativeReadValues",
"(I)[B",
(void *)CameraMetadata_readValues },
@@ -568,6 +578,9 @@ static const JNINativeMethod gCameraMetadataMethods[] = {
{ "nativeDump",
"()V",
(void *)CameraMetadata_dump },
+ { "nativeGetAllVendorKeys",
+ "(Ljava/lang/Class;)Ljava/util/ArrayList;",
+ (void *)CameraMetadata_getAllVendorKeys},
// Parcelable interface
{ "nativeReadFromParcel",
"(Landroid/os/Parcel;)V",
@@ -590,11 +603,11 @@ int register_android_hardware_camera2_CameraMetadata(JNIEnv *env)
gMetadataOffsets.mResultKey = MakeGlobalRefOrDie(env, resultKeyClazz);
gMetadataOffsets.mCharacteristicsConstr = GetMethodIDOrDie(env,
gMetadataOffsets.mCharacteristicsKey, "<init>",
- "(Ljava/lang/String;Ljava/lang/Class;)V");
+ "(Ljava/lang/String;Ljava/lang/Class;J)V");
gMetadataOffsets.mRequestConstr = GetMethodIDOrDie(env,
- gMetadataOffsets.mRequestKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V");
+ gMetadataOffsets.mRequestKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;J)V");
gMetadataOffsets.mResultConstr = GetMethodIDOrDie(env,
- gMetadataOffsets.mResultKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V");
+ gMetadataOffsets.mResultKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;J)V");
// Store global references for primitive array types used by Keys
jclass byteClazz = FindClassOrDie(env, "[B");
@@ -630,13 +643,76 @@ int register_android_hardware_camera2_CameraMetadata(JNIEnv *env)
extern "C" {
-static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType) {
+static jint CameraMetadata_getTypeFromTagLocal(JNIEnv *env, jobject thiz, jint tag) {
+ CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz);
+ metadata_vendor_id_t vendorId = CAMERA_METADATA_INVALID_VENDOR_ID;
+ if (metadata) {
+ const camera_metadata_t *metaBuffer = metadata->getAndLock();
+ vendorId = get_camera_metadata_vendor_id(metaBuffer);
+ metadata->unlock(metaBuffer);
+ }
+
+ int tagType = get_local_camera_metadata_tag_type_vendor_id(tag, vendorId);
+ if (tagType == -1) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "Tag (%d) did not have a type", tag);
+ return -1;
+ }
+
+ return tagType;
+}
+
+static jint CameraMetadata_getTagFromKeyLocal(JNIEnv *env, jobject thiz, jstring keyName) {
+ ScopedUtfChars keyScoped(env, keyName);
+ const char *key = keyScoped.c_str();
+ if (key == NULL) {
+ // exception thrown by ScopedUtfChars
+ return 0;
+ }
+ ALOGV("%s (key = '%s')", __FUNCTION__, key);
+
+ uint32_t tag = 0;
+ sp<VendorTagDescriptor> vTags;
+ CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz);
+ if (metadata) {
+ sp<VendorTagDescriptorCache> cache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+ if (cache.get()) {
+ const camera_metadata_t *metaBuffer = metadata->getAndLock();
+ metadata_vendor_id_t vendorId = get_camera_metadata_vendor_id(metaBuffer);
+ metadata->unlock(metaBuffer);
+ cache->getVendorTagDescriptor(vendorId, &vTags);
+ }
+ }
+ status_t res = CameraMetadata::getTagFromName(key, vTags.get(), &tag);
+ if (res != OK) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "Could not find tag for key '%s')", key);
+ }
+ return tag;
+}
+
+static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType) {
+ metadata_vendor_id_t vendorId = CAMERA_METADATA_INVALID_VENDOR_ID;
// Get all vendor tags
sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
if (vTags.get() == nullptr) {
- // No vendor tags.
- return NULL;
+ sp<VendorTagDescriptorCache> cache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+ if (cache.get() == nullptr) {
+ // No vendor tags.
+ return nullptr;
+ }
+
+ CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+ if (metadata == NULL) return NULL;
+
+ const camera_metadata_t *metaBuffer = metadata->getAndLock();
+ vendorId = get_camera_metadata_vendor_id(metaBuffer);
+ cache->getVendorTagDescriptor(vendorId, &vTags);
+ metadata->unlock(metaBuffer);
+ if (vTags.get() == nullptr) {
+ return nullptr;
+ }
}
int count = vTags->getTagCount();
@@ -714,7 +790,7 @@ static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass
return NULL;
}
- jobject key = env->NewObject(keyClazz, keyConstr, name, valueClazz);
+ jobject key = env->NewObject(keyClazz, keyConstr, name, valueClazz, vendorId);
if (env->ExceptionCheck()) {
return NULL;
}
@@ -731,8 +807,8 @@ static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass
return arrayList;
}
-static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) {
-
+static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName,
+ jlong vendorId) {
ScopedUtfChars keyScoped(env, keyName);
const char *key = keyScoped.c_str();
if (key == NULL) {
@@ -744,6 +820,13 @@ static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyN
uint32_t tag = 0;
sp<VendorTagDescriptor> vTags =
VendorTagDescriptor::getGlobalVendorTagDescriptor();
+ if (vTags.get() == nullptr) {
+ sp<VendorTagDescriptorCache> cache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+ if (cache.get() != nullptr) {
+ cache->getVendorTagDescriptor(vendorId, &vTags);
+ }
+ }
+
status_t res = CameraMetadata::getTagFromName(key, vTags.get(), &tag);
if (res != OK) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
@@ -752,8 +835,8 @@ static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyN
return tag;
}
-static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag) {
- int tagType = get_camera_metadata_tag_type(tag);
+static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag, jlong vendorId) {
+ int tagType = get_local_camera_metadata_tag_type_vendor_id(tag, vendorId);
if (tagType == -1) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
"Tag (%d) did not have a type", tag);
@@ -787,8 +870,24 @@ static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject t
__FUNCTION__, res.toString8().string());
return res.serviceSpecificErrorCode();
}
+ if (0 < desc->getTagCount()) {
+ err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+ } else {
+ sp<VendorTagDescriptorCache> cache = new VendorTagDescriptorCache();
+ binder::Status res = cameraService->getCameraVendorTagCache(/*out*/cache.get());
+ if (res.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_DISCONNECTED) {
+ // No camera module available, not an error on devices with no cameras
+ VendorTagDescriptorCache::clearGlobalVendorTagCache();
+ return OK;
+ } else if (!res.isOk()) {
+ VendorTagDescriptorCache::clearGlobalVendorTagCache();
+ ALOGE("%s: Failed to setup vendor tag cache: %s",
+ __FUNCTION__, res.toString8().string());
+ return res.serviceSpecificErrorCode();
+ }
- err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+ err = VendorTagDescriptorCache::setAsGlobalVendorTagCache(cache);
+ }
if (err != OK) {
return hardware::ICameraService::ERROR_INVALID_OPERATION;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
index cd0e587744ed..54442b37d7d9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
@@ -154,18 +154,18 @@ public class CameraMetadataTest extends junit.framework.TestCase {
@SmallTest
public void testGetTypeFromTag() {
assertEquals(TYPE_BYTE,
- CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_MODE));
+ CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_MODE, Long.MAX_VALUE));
assertEquals(TYPE_RATIONAL,
- CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_TRANSFORM));
+ CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_TRANSFORM, Long.MAX_VALUE));
assertEquals(TYPE_FLOAT,
- CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_GAINS));
+ CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_GAINS, Long.MAX_VALUE));
assertEquals(TYPE_BYTE,
- CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_ANTIBANDING_MODE));
+ CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_ANTIBANDING_MODE, Long.MAX_VALUE));
assertEquals(TYPE_INT32,
- CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION));
+ CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, Long.MAX_VALUE));
try {
- CameraMetadataNative.getNativeType(0xDEADF00D);
+ CameraMetadataNative.getNativeType(0xDEADF00D, Long.MAX_VALUE);
fail("No type should exist for invalid tag 0xDEADF00D");
} catch(IllegalArgumentException e) {
}