Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36ad891f authored by Jayant Chowdhary's avatar Jayant Chowdhary Committed by Android (Google) Code Review
Browse files

Merge "camera2: Avoid boxing primitives while unmarshalling primitive arrays."

parents 8faead2a 1a294342
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -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.
     *
     * <p>The following types (whether boxed or unboxed) are considered primitive:
     * <ul>
     * <li>byte
     * <li>int
     * <li>float
     * <li>double
     * </ul>
     * </p>
     *
     * @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.
     *
+68 −3
Original line number Diff line number Diff line
@@ -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<T> implements MarshalQueryable<T> {
    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<T> {
        private final Class<T> mClass;
        private final Marshaler<?> mComponentMarshaler;
@@ -89,10 +148,16 @@ public class MarshalQueryableArray<T> implements MarshalQueryable<T> {
                }

                array = Array.newInstance(mComponentClass, arraySize);
                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.
                ArrayList<Object> arrayList = new ArrayList<Object>();