Merge "Parcel: add new methods for interface list/array"
diff --git a/core/api/current.txt b/core/api/current.txt
index 6a2b9c1..641f71b 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -31427,6 +31427,8 @@
method @Nullable public double[] createDoubleArray();
method @Nullable public float[] createFloatArray();
method @Nullable public int[] createIntArray();
+ method @Nullable public <T extends android.os.IInterface> T[] createInterfaceArray(@NonNull java.util.function.IntFunction<T[]>, @NonNull java.util.function.Function<android.os.IBinder,T>);
+ method @Nullable public <T extends android.os.IInterface> java.util.ArrayList<T> createInterfaceArrayList(@NonNull java.util.function.Function<android.os.IBinder,T>);
method @Nullable public long[] createLongArray();
method @Nullable public String[] createStringArray();
method @Nullable public java.util.ArrayList<java.lang.String> createStringArrayList();
@@ -31467,6 +31469,8 @@
method @Nullable public java.util.HashMap readHashMap(@Nullable ClassLoader);
method public int readInt();
method public void readIntArray(@NonNull int[]);
+ method public <T extends android.os.IInterface> void readInterfaceArray(@NonNull T[], @NonNull java.util.function.Function<android.os.IBinder,T>);
+ method public <T extends android.os.IInterface> void readInterfaceList(@NonNull java.util.List<T>, @NonNull java.util.function.Function<android.os.IBinder,T>);
method public void readList(@NonNull java.util.List, @Nullable ClassLoader);
method public <T> void readList(@NonNull java.util.List<? super T>, @Nullable ClassLoader, @NonNull Class<T>);
method public long readLong();
@@ -31519,6 +31523,8 @@
method public void writeFloatArray(@Nullable float[]);
method public void writeInt(int);
method public void writeIntArray(@Nullable int[]);
+ method public <T extends android.os.IInterface> void writeInterfaceArray(@Nullable T[]);
+ method public <T extends android.os.IInterface> void writeInterfaceList(@Nullable java.util.List<T>);
method public void writeInterfaceToken(@NonNull String);
method public void writeList(@Nullable java.util.List);
method public void writeLong(long);
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index d1e6716..5a2f27d 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -62,6 +62,8 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.function.Function;
+import java.util.function.IntFunction;
import java.util.function.Supplier;
/**
@@ -178,8 +180,12 @@
* {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()},
* {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])},
* {@link #createBinderArray()},
+ * {@link #writeInterfaceArray(T[])}, {@link #readInterfaceArray(T[], Function)},
+ * {@link #createInterfaceArray(IntFunction, Function)},
* {@link #writeBinderList(List)}, {@link #readBinderList(List)},
- * {@link #createBinderArrayList()}.</p>
+ * {@link #createBinderArrayList()},
+ * {@link #writeInterfaceList(List)}, {@link #readInterfaceList(List, Function)},
+ * {@link #createInterfaceArrayList(Function)}.</p>
*
* <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
* can be written and {@link ParcelFileDescriptor} objects returned to operate
@@ -1730,6 +1736,30 @@
}
/**
+ * Flatten a homogeneous array containing an IInterface type into the parcel,
+ * at the current dataPosition() and growing dataCapacity() if needed. The
+ * type of the objects in the array must be one that implements IInterface.
+ *
+ * @param val The array of objects to be written.
+ *
+ * @see #createInterfaceArray
+ * @see #readInterfaceArray
+ * @see IInterface
+ */
+ public final <T extends IInterface> void writeInterfaceArray(
+ @SuppressLint("ArrayReturn") @Nullable T[] val) {
+ if (val != null) {
+ int N = val.length;
+ writeInt(N);
+ for (int i=0; i<N; i++) {
+ writeStrongInterface(val[i]);
+ }
+ } else {
+ writeInt(-1);
+ }
+ }
+
+ /**
* @hide
*/
public final void writeCharSequenceArray(@Nullable CharSequence[] val) {
@@ -1785,6 +1815,50 @@
}
/**
+ * Read and return a new array of T (IInterface) from the parcel.
+ *
+ * @return the IInterface array of type T
+ * @param newArray a function to create an array of T with a given length
+ * @param asInterface a function to convert IBinder object into T (IInterface)
+ */
+ @SuppressLint({"ArrayReturn", "NullableCollection", "SamShouldBeLast"})
+ @Nullable
+ public final <T extends IInterface> T[] createInterfaceArray(
+ @NonNull IntFunction<T[]> newArray, @NonNull Function<IBinder, T> asInterface) {
+ int N = readInt();
+ if (N >= 0) {
+ T[] val = newArray.apply(N);
+ for (int i=0; i<N; i++) {
+ val[i] = asInterface.apply(readStrongBinder());
+ }
+ return val;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Read an array of T (IInterface) from a parcel.
+ *
+ * @param asInterface a function to convert IBinder object into T (IInterface)
+ *
+ * @throws BadParcelableException Throws BadParcelableException if the length of `val`
+ * mismatches the number of items in the parcel.
+ */
+ public final <T extends IInterface> void readInterfaceArray(
+ @SuppressLint("ArrayReturn") @NonNull T[] val,
+ @NonNull Function<IBinder, T> asInterface) {
+ int N = readInt();
+ if (N == val.length) {
+ for (int i=0; i<N; i++) {
+ val[i] = asInterface.apply(readStrongBinder());
+ }
+ } else {
+ throw new BadParcelableException("bad array lengths");
+ }
+ }
+
+ /**
* Flatten a List containing a particular object type into the parcel, at
* the current dataPosition() and growing dataCapacity() if needed. The
* type of the objects in the list must be one that implements Parcelable.
@@ -1898,6 +1972,28 @@
}
/**
+ * Flatten a {@code List} containing T (IInterface) objects into this parcel
+ * at the current position. They can later be retrieved with
+ * {@link #createInterfaceArrayList} or {@link #readInterfaceList}.
+ *
+ * @see #createInterfaceArrayList
+ * @see #readInterfaceList
+ */
+ public final <T extends IInterface> void writeInterfaceList(@Nullable List<T> val) {
+ if (val == null) {
+ writeInt(-1);
+ return;
+ }
+ int N = val.size();
+ int i=0;
+ writeInt(N);
+ while (i < N) {
+ writeStrongInterface(val.get(i));
+ i++;
+ }
+ }
+
+ /**
* Flatten a {@code List} containing arbitrary {@code Parcelable} objects into this parcel
* at the current position. They can later be retrieved using
* {@link #readParcelableList(List, ClassLoader)} if required.
@@ -3380,6 +3476,32 @@
}
/**
+ * Read and return a new ArrayList containing T (IInterface) objects from
+ * the parcel that was written with {@link #writeInterfaceList} at the
+ * current dataPosition(). Returns null if the
+ * previously written list object was null.
+ *
+ * @return A newly created ArrayList containing T (IInterface)
+ *
+ * @see #writeInterfaceList
+ */
+ @SuppressLint({"ConcreteCollection", "NullableCollection"})
+ @Nullable
+ public final <T extends IInterface> ArrayList<T> createInterfaceArrayList(
+ @NonNull Function<IBinder, T> asInterface) {
+ int N = readInt();
+ if (N < 0) {
+ return null;
+ }
+ ArrayList<T> l = new ArrayList<T>(N);
+ while (N > 0) {
+ l.add(asInterface.apply(readStrongBinder()));
+ N--;
+ }
+ return l;
+ }
+
+ /**
* Read into the given List items String objects that were written with
* {@link #writeStringList} at the current dataPosition().
*
@@ -3422,6 +3544,28 @@
}
/**
+ * Read into the given List items IInterface objects that were written with
+ * {@link #writeInterfaceList} at the current dataPosition().
+ *
+ * @see #writeInterfaceList
+ */
+ public final <T extends IInterface> void readInterfaceList(@NonNull List<T> list,
+ @NonNull Function<IBinder, T> asInterface) {
+ int M = list.size();
+ int N = readInt();
+ int i = 0;
+ for (; i < M && i < N; i++) {
+ list.set(i, asInterface.apply(readStrongBinder()));
+ }
+ for (; i<N; i++) {
+ list.add(asInterface.apply(readStrongBinder()));
+ }
+ for (; i<M; i++) {
+ list.remove(N);
+ }
+ }
+
+ /**
* Read the list of {@code Parcelable} objects at the current data position into the
* given {@code list}. The contents of the {@code list} are replaced. If the serialized
* list was {@code null}, {@code list} is cleared.