diff --git a/core/java/android/hardware/camera2/marshal/MarshalHelpers.java b/core/java/android/hardware/camera2/marshal/MarshalHelpers.java index 35ecc2a037e91..3a4e1115f3a45 100644 --- a/core/java/android/hardware/camera2/marshal/MarshalHelpers.java +++ b/core/java/android/hardware/camera2/marshal/MarshalHelpers.java @@ -94,6 +94,40 @@ public final class MarshalHelpers { "'; expected a metadata primitive class"); } + /** + * Checks whether or not {@code klass} is one of the unboxed primitive classes. + * + *

The following types (whether boxed or unboxed) are considered primitive: + *

+ *

+ * + * @param klass a {@link Class} instance; using {@code null} will return {@code false} + * @return {@code true} if primitive, {@code false} otherwise + */ + public static boolean isUnwrappedPrimitiveClass(Class klass) { + if (klass == null) { + return false; + } + + if (klass == byte.class) { + return true; + } else if (klass == int.class) { + return true; + } else if (klass == float.class) { + return true; + } else if (klass == long.class) { + return true; + } else if (klass == double.class) { + return true; + } + return false; + } + /** * Checks whether or not {@code klass} is one of the metadata-primitive classes. * @@ -218,6 +252,32 @@ public final class MarshalHelpers { throw new UnsupportedOperationException("Unknown nativeType " + nativeType); } + /** + * Get the unboxed primitive type corresponding to nativeType + * + * @param nativeType the native type (RATIONAL not included) + * + * @return the native type class + * + * @throws UnsupportedOperationException if the native type was invalid + */ + public static Class getPrimitiveTypeClass(int nativeType) { + switch (nativeType) { + case TYPE_BYTE: + return byte.class; + case TYPE_INT32: + return int.class; + case TYPE_FLOAT: + return float.class; + case TYPE_INT64: + return long.class; + case TYPE_DOUBLE: + return double.class; + } + + throw new UnsupportedOperationException("Unknown nativeType " + nativeType); + } + /** * Ensure that the expected and actual native types are equal. * diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java index ebc74f090b4be..6cf5d60acec81 100644 --- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java +++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java @@ -21,6 +21,9 @@ import android.hardware.camera2.marshal.MarshalRegistry; import android.hardware.camera2.utils.TypeReference; import android.util.Log; +import static android.hardware.camera2.marshal.MarshalHelpers.isUnwrappedPrimitiveClass; +import static android.hardware.camera2.marshal.MarshalHelpers.getPrimitiveTypeClass; + import java.lang.reflect.Array; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -41,6 +44,62 @@ public class MarshalQueryableArray implements MarshalQueryable { private static final String TAG = MarshalQueryableArray.class.getSimpleName(); private static final boolean DEBUG = false; + private static interface PrimitiveArrayFiller { + public void fillPosition(Object arr, int index, ByteBuffer buffer); + static PrimitiveArrayFiller getPrimitiveArrayFiller(Class componentType) { + if (componentType == int.class) { + return new PrimitiveArrayFiller() { + @Override + public void fillPosition(Object arr, int index, ByteBuffer buffer) { + int i = buffer.getInt(); + Array.setInt(arr, index, i); + } + }; + } else if (componentType == float.class) { + return new PrimitiveArrayFiller() { + @Override + public void fillPosition(Object arr, int index, ByteBuffer buffer) { + float i = buffer.getFloat(); + Array.setFloat(arr, index, i); + } + }; + } else if (componentType == long.class) { + return new PrimitiveArrayFiller() { + @Override + public void fillPosition(Object arr, int index, ByteBuffer buffer) { + long i = buffer.getLong(); + Array.setLong(arr, index, i); + } + }; + } else if (componentType == double.class) { + return new PrimitiveArrayFiller() { + @Override + public void fillPosition(Object arr, int index, ByteBuffer buffer) { + double i = buffer.getDouble(); + Array.setDouble(arr, index, i); + } + }; + } else if (componentType == byte.class) { + return new PrimitiveArrayFiller() { + @Override + public void fillPosition(Object arr, int index, ByteBuffer buffer) { + byte i = buffer.get(); + Array.setByte(arr, index, i); + } + }; + } + throw new UnsupportedOperationException("PrimitiveArrayFiller of type " + + componentType.getName() + " not supported"); + } + }; + + static void unmarshalPrimitiveArray(Object arr, int size, ByteBuffer buffer, + PrimitiveArrayFiller filler) { + for (int i = 0; i < size; i++) { + filler.fillPosition(arr, i, buffer); + } + } + private class MarshalerArray extends Marshaler { private final Class mClass; private final Marshaler mComponentMarshaler; @@ -89,9 +148,15 @@ public class MarshalQueryableArray implements MarshalQueryable { } array = Array.newInstance(mComponentClass, arraySize); - for (int i = 0; i < arraySize; ++i) { - Object elem = mComponentMarshaler.unmarshal(buffer); - Array.set(array, i, elem); + if (isUnwrappedPrimitiveClass(mComponentClass) && + mComponentClass == getPrimitiveTypeClass(mNativeType)) { + unmarshalPrimitiveArray(array, arraySize, buffer, + PrimitiveArrayFiller.getPrimitiveArrayFiller(mComponentClass)); + } else { + for (int i = 0; i < arraySize; ++i) { + Object elem = mComponentMarshaler.unmarshal(buffer); + Array.set(array, i, elem); + } } } else { // Dynamic size, use an array list.