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:
+ *
+ * - byte
+ *
- int
+ *
- float
+ *
- double
+ *
+ *
+ *
+ * @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.