diff options
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) { } |