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

Commit 5539926c authored by Bernardo Rufino's avatar Bernardo Rufino
Browse files

Correct Parcel value types

* Bundle supports types char, char[], short[], float[] which were
  falling back to serializable handling in Parcel because readValue()
  didn't have specific support for those types. Adding support in Parcel
  to avoid the need for length-prefixing and to improve performance.
  Curiously some of those had read/write methods already.
* Updated Bundle to just pull the types above from the map since those
  won't be lazy values anymore.
* We were missing a few custom type containers in our list of
  length-prefixed types and we were listing Bundle unnecessarily as
  length-prefixed since Bundle itself is already length-prefixed and
  copies the correspondent section of the parcel internally.

Test: atest -d android.os.cts.ParcelTest android.os.cts.BundleTest android.os.BundleTest android.os.ParcelTest
Bug: 195622897
Change-Id: I1e15d59d883311685ffa32ece1f5a00e01bf6aea
parent d3199a60
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1048,7 +1048,7 @@ public class BaseBundle {
     */
    char getChar(String key, char defaultValue) {
        unparcel();
        Object o = getValue(key);
        Object o = mMap.get(key);
        if (o == null) {
            return defaultValue;
        }
@@ -1451,7 +1451,7 @@ public class BaseBundle {
    @Nullable
    short[] getShortArray(@Nullable String key) {
        unparcel();
        Object o = getValue(key);
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
@@ -1474,7 +1474,7 @@ public class BaseBundle {
    @Nullable
    char[] getCharArray(@Nullable String key) {
        unparcel();
        Object o = getValue(key);
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
@@ -1543,7 +1543,7 @@ public class BaseBundle {
    @Nullable
    float[] getFloatArray(@Nullable String key) {
        unparcel();
        Object o = getValue(key);
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
+91 −2
Original line number Diff line number Diff line
@@ -263,6 +263,10 @@ public final class Parcel {
    private static final int VAL_SIZE = 26;
    private static final int VAL_SIZEF = 27;
    private static final int VAL_DOUBLEARRAY = 28;
    private static final int VAL_CHAR = 29;
    private static final int VAL_SHORTARRAY = 30;
    private static final int VAL_CHARARRAY = 31;
    private static final int VAL_FLOATARRAY = 32;

    // The initial int32 in a Binder call's reply Parcel header:
    // Keep these in sync with libbinder's binder/Status.h.
@@ -1319,6 +1323,46 @@ public final class Parcel {
        }
    }

    /** @hide */
    public void writeShortArray(@Nullable short[] val) {
        if (val != null) {
            int n = val.length;
            writeInt(n);
            for (int i = 0; i < n; i++) {
                writeInt(val[i]);
            }
        } else {
            writeInt(-1);
        }
    }

    /** @hide */
    @Nullable
    public short[] createShortArray() {
        int n = readInt();
        if (n >= 0 && n <= (dataAvail() >> 2)) {
            short[] val = new short[n];
            for (int i = 0; i < n; i++) {
                val[i] = (short) readInt();
            }
            return val;
        } else {
            return null;
        }
    }

    /** @hide */
    public void readShortArray(@NonNull short[] val) {
        int n = readInt();
        if (n == val.length) {
            for (int i = 0; i < n; i++) {
                val[i] = (short) readInt();
            }
        } else {
            throw new RuntimeException("bad array lengths");
        }
    }

    public final void writeCharArray(@Nullable char[] val) {
        if (val != null) {
            int N = val.length;
@@ -1984,6 +2028,14 @@ public final class Parcel {
            return VAL_SIZE;
        } else if (v instanceof double[]) {
            return VAL_DOUBLEARRAY;
        } else if (v instanceof Character) {
            return VAL_CHAR;
        } else if (v instanceof short[]) {
            return VAL_SHORTARRAY;
        } else if (v instanceof char[]) {
            return VAL_CHARARRAY;
        } else  if (v instanceof float[]) {
            return VAL_FLOATARRAY;
        } else {
            Class<?> clazz = v.getClass();
            if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -2086,6 +2138,18 @@ public final class Parcel {
            case VAL_DOUBLEARRAY:
                writeDoubleArray((double[]) v);
                break;
            case VAL_CHAR:
                writeInt((Character) v);
                break;
            case VAL_SHORTARRAY:
                writeShortArray((short[]) v);
                break;
            case VAL_CHARARRAY:
                writeCharArray((char[]) v);
                break;
            case VAL_FLOATARRAY:
                writeFloatArray((float[]) v);
                break;
            case VAL_OBJECTARRAY:
                writeArray((Object[]) v);
                break;
@@ -3696,6 +3760,22 @@ public final class Parcel {
                object = createDoubleArray();
                break;

            case VAL_CHAR:
                object = (char) readInt();
                break;

            case VAL_SHORTARRAY:
                object = createShortArray();
                break;

            case VAL_CHARARRAY:
                object = createCharArray();
                break;

            case VAL_FLOATARRAY:
                object = createFloatArray();
                break;

            default:
                int off = dataPosition() - 4;
                throw new RuntimeException(
@@ -3711,12 +3791,17 @@ public final class Parcel {
    }

    private boolean isLengthPrefixed(int type) {
        // In general, we want custom types and containers of custom types to be length-prefixed,
        // this allows clients (eg. Bundle) to skip their content during deserialization. The
        // exception to this is Bundle, since Bundle is already length-prefixed and already copies
        // the correspondent section of the parcel internally.
        switch (type) {
            case VAL_MAP:
            case VAL_PARCELABLE:
            case VAL_PARCELABLEARRAY:
            case VAL_LIST:
            case VAL_SPARSEARRAY:
            case VAL_BUNDLE:
            case VAL_PARCELABLEARRAY:
            case VAL_OBJECTARRAY:
            case VAL_SERIALIZABLE:
                return true;
            default:
@@ -4249,6 +4334,10 @@ public final class Parcel {
            case VAL_SIZE: return "VAL_SIZE";
            case VAL_SIZEF: return "VAL_SIZEF";
            case VAL_DOUBLEARRAY: return "VAL_DOUBLEARRAY";
            case VAL_CHAR: return "VAL_CHAR";
            case VAL_SHORTARRAY: return "VAL_SHORTARRAY";
            case VAL_CHARARRAY: return "VAL_CHARARRAY";
            case VAL_FLOATARRAY: return "VAL_FLOATARRAY";
            case VAL_OBJECTARRAY: return "VAL_OBJECTARRAY";
            case VAL_SERIALIZABLE: return "VAL_SERIALIZABLE";
            default: return "UNKNOWN(" + type + ")";