• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import static com.android.internal.util.Preconditions.checkArgument;
20 
21 import static java.util.Objects.requireNonNull;
22 
23 import android.annotation.IntDef;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.annotation.SuppressLint;
27 import android.annotation.TestApi;
28 import android.app.AppOpsManager;
29 import android.compat.annotation.UnsupportedAppUsage;
30 import android.text.TextUtils;
31 import android.util.ArrayMap;
32 import android.util.ArraySet;
33 import android.util.ExceptionUtils;
34 import android.util.Log;
35 import android.util.MathUtils;
36 import android.util.Pair;
37 import android.util.Size;
38 import android.util.SizeF;
39 import android.util.Slog;
40 import android.util.SparseArray;
41 import android.util.SparseBooleanArray;
42 import android.util.SparseIntArray;
43 
44 import com.android.internal.annotations.GuardedBy;
45 import com.android.internal.util.ArrayUtils;
46 
47 import dalvik.annotation.optimization.CriticalNative;
48 import dalvik.annotation.optimization.FastNative;
49 
50 import libcore.util.SneakyThrow;
51 
52 import java.io.ByteArrayInputStream;
53 import java.io.ByteArrayOutputStream;
54 import java.io.FileDescriptor;
55 import java.io.IOException;
56 import java.io.ObjectInputStream;
57 import java.io.ObjectOutputStream;
58 import java.io.ObjectStreamClass;
59 import java.io.Serializable;
60 import java.lang.annotation.Retention;
61 import java.lang.annotation.RetentionPolicy;
62 import java.lang.reflect.Array;
63 import java.lang.reflect.Field;
64 import java.lang.reflect.Modifier;
65 import java.util.ArrayList;
66 import java.util.HashMap;
67 import java.util.List;
68 import java.util.Map;
69 import java.util.Objects;
70 import java.util.Set;
71 import java.util.function.BiFunction;
72 import java.util.function.Function;
73 import java.util.function.IntFunction;
74 
75 /**
76  * Container for a message (data and object references) that can
77  * be sent through an IBinder.  A Parcel can contain both flattened data
78  * that will be unflattened on the other side of the IPC (using the various
79  * methods here for writing specific types, or the general
80  * {@link Parcelable} interface), and references to live {@link IBinder}
81  * objects that will result in the other side receiving a proxy IBinder
82  * connected with the original IBinder in the Parcel.
83  *
84  * <p class="note">Parcel is <strong>not</strong> a general-purpose
85  * serialization mechanism.  This class (and the corresponding
86  * {@link Parcelable} API for placing arbitrary objects into a Parcel) is
87  * designed as a high-performance IPC transport.  As such, it is not
88  * appropriate to place any Parcel data in to persistent storage: changes
89  * in the underlying implementation of any of the data in the Parcel can
90  * render older data unreadable.</p>
91  *
92  * <p>The bulk of the Parcel API revolves around reading and writing data
93  * of various types.  There are six major classes of such functions available.</p>
94  *
95  * <h3>Primitives</h3>
96  *
97  * <p>The most basic data functions are for writing and reading primitive
98  * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
99  * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
100  * {@link #readInt}, {@link #writeLong}, {@link #readLong},
101  * {@link #writeString}, {@link #readString}.  Most other
102  * data operations are built on top of these.  The given data is written and
103  * read using the endianess of the host CPU.</p>
104  *
105  * <h3>Primitive Arrays</h3>
106  *
107  * <p>There are a variety of methods for reading and writing raw arrays
108  * of primitive objects, which generally result in writing a 4-byte length
109  * followed by the primitive data items.  The methods for reading can either
110  * read the data into an existing array, or create and return a new array.
111  * These available types are:</p>
112  *
113  * <ul>
114  * <li> {@link #writeBooleanArray(boolean[])},
115  * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
116  * <li> {@link #writeByteArray(byte[])},
117  * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])},
118  * {@link #createByteArray()}
119  * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])},
120  * {@link #createCharArray()}
121  * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])},
122  * {@link #createDoubleArray()}
123  * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])},
124  * {@link #createFloatArray()}
125  * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])},
126  * {@link #createIntArray()}
127  * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])},
128  * {@link #createLongArray()}
129  * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])},
130  * {@link #createStringArray()}.
131  * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
132  * {@link #readSparseBooleanArray()}.
133  * </ul>
134  *
135  * <h3>Parcelables</h3>
136  *
137  * <p>The {@link Parcelable} protocol provides an extremely efficient (but
138  * low-level) protocol for objects to write and read themselves from Parcels.
139  * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
140  * and {@link #readParcelable(ClassLoader)} or
141  * {@link #writeParcelableArray} and
142  * {@link #readParcelableArray(ClassLoader)} to write or read.  These
143  * methods write both the class type and its data to the Parcel, allowing
144  * that class to be reconstructed from the appropriate class loader when
145  * later reading.</p>
146  *
147  * <p>There are also some methods that provide a more efficient way to work
148  * with Parcelables: {@link #writeTypedObject}, {@link #writeTypedArray},
149  * {@link #writeTypedList}, {@link #readTypedObject},
150  * {@link #createTypedArray} and {@link #createTypedArrayList}.  These methods
151  * do not write the class information of the original object: instead, the
152  * caller of the read function must know what type to expect and pass in the
153  * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
154  * properly construct the new object and read its data.  (To more efficient
155  * write and read a single Parcelable object that is not null, you can directly
156  * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
157  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
158  * yourself.)</p>
159  *
160  * <h3>Bundles</h3>
161  *
162  * <p>A special type-safe container, called {@link Bundle}, is available
163  * for key/value maps of heterogeneous values.  This has many optimizations
164  * for improved performance when reading and writing data, and its type-safe
165  * API avoids difficult to debug type errors when finally marshalling the
166  * data contents into a Parcel.  The methods to use are
167  * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
168  * {@link #readBundle(ClassLoader)}.
169  *
170  * <h3>Active Objects</h3>
171  *
172  * <p>An unusual feature of Parcel is the ability to read and write active
173  * objects.  For these objects the actual contents of the object is not
174  * written, rather a special token referencing the object is written.  When
175  * reading the object back from the Parcel, you do not get a new instance of
176  * the object, but rather a handle that operates on the exact same object that
177  * was originally written.  There are two forms of active objects available.</p>
178  *
179  * <p>{@link Binder} objects are a core facility of Android's general cross-process
180  * communication system.  The {@link IBinder} interface describes an abstract
181  * protocol with a Binder object.  Any such interface can be written in to
182  * a Parcel, and upon reading you will receive either the original object
183  * implementing that interface or a special proxy implementation
184  * that communicates calls back to the original object.  The methods to use are
185  * {@link #writeStrongBinder(IBinder)},
186  * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()},
187  * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])},
188  * {@link #createBinderArray()},
189  * {@link #writeInterfaceArray(T[])}, {@link #readInterfaceArray(T[], Function)},
190  * {@link #createInterfaceArray(IntFunction, Function)},
191  * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
192  * {@link #createBinderArrayList()},
193  * {@link #writeInterfaceList(List)}, {@link #readInterfaceList(List, Function)},
194  * {@link #createInterfaceArrayList(Function)}.</p>
195  *
196  * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
197  * can be written and {@link ParcelFileDescriptor} objects returned to operate
198  * on the original file descriptor.  The returned file descriptor is a dup
199  * of the original file descriptor: the object and fd is different, but
200  * operating on the same underlying file stream, with the same position, etc.
201  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
202  * {@link #readFileDescriptor()}.
203  *
204   * <h3>Parcelable Containers</h3>
205  *
206  * <p>A final class of methods are for writing and reading standard Java
207  * containers of arbitrary types.  These all revolve around the
208  * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
209  * which define the types of objects allowed.  The container methods are
210  * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)},
211  * {@link #writeList(List)}, {@link #readList(List, ClassLoader)},
212  * {@link #readArrayList(ClassLoader)},
213  * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
214  * {@link #writeSparseArray(SparseArray)},
215  * {@link #readSparseArray(ClassLoader)}.
216  *
217  * <h3>Restricted Parcelable Containers</h3>
218  *
219  * <p>A final class of methods are for reading standard Java containers of restricted types.
220  * These methods replace methods for reading containers of arbitrary types from previous section
221  * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. The pairing writing methods are
222  * still the same from previous section.
223  * These methods accepts additional {@code clazz} parameters as the required types.
224  * The Restricted Parcelable container methods are {@link #readArray(ClassLoader, Class)},
225  * {@link #readList(List, ClassLoader, Class)},
226  * {@link #readArrayList(ClassLoader, Class)},
227  * {@link #readMap(Map, ClassLoader, Class, Class)},
228  * {@link #readSparseArray(ClassLoader, Class)}.
229  */
230 public final class Parcel {
231 
232     private static final boolean DEBUG_RECYCLE = false;
233     private static final boolean DEBUG_ARRAY_MAP = false;
234     private static final String TAG = "Parcel";
235 
236     @UnsupportedAppUsage
237     @SuppressWarnings({"UnusedDeclaration"})
238     private long mNativePtr; // used by native code
239 
240     /**
241      * Flag indicating if {@link #mNativePtr} was allocated by this object,
242      * indicating that we're responsible for its lifecycle.
243      */
244     private boolean mOwnsNativeParcelObject;
245     private long mNativeSize;
246 
247     private ArrayMap<Class, Object> mClassCookies;
248 
249     private RuntimeException mStack;
250     private boolean mRecycled = false;
251 
252     /** @hide */
253     @TestApi
254     public static final int FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT = 1 << 0;
255 
256     /** @hide */
257     @TestApi
258     public static final int FLAG_PROPAGATE_ALLOW_BLOCKING = 1 << 1;
259 
260     /** @hide */
261     @IntDef(flag = true, prefix = { "FLAG_" }, value = {
262             FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT,
263             FLAG_PROPAGATE_ALLOW_BLOCKING,
264     })
265     @Retention(RetentionPolicy.SOURCE)
266     public @interface ParcelFlags {}
267 
268     @ParcelFlags
269     private int mFlags;
270 
271     /**
272      * Whether or not to parcel the stack trace of an exception. This has a performance
273      * impact, so should only be included in specific processes and only on debug builds.
274      */
275     private static boolean sParcelExceptionStackTrace;
276 
277     private static final Object sPoolSync = new Object();
278 
279     /** Next item in the linked list pool, if any */
280     @GuardedBy("sPoolSync")
281     private Parcel mPoolNext;
282 
283     /** Head of a linked list pool of {@link Parcel} objects */
284     @GuardedBy("sPoolSync")
285     private static Parcel sOwnedPool;
286     /** Head of a linked list pool of {@link Parcel} objects */
287     @GuardedBy("sPoolSync")
288     private static Parcel sHolderPool;
289 
290     /** Total size of pool with head at {@link #sOwnedPool} */
291     @GuardedBy("sPoolSync")
292     private static int sOwnedPoolSize = 0;
293     /** Total size of pool with head at {@link #sHolderPool} */
294     @GuardedBy("sPoolSync")
295     private static int sHolderPoolSize = 0;
296 
297     /**
298      * We're willing to pool up to 32 objects, which is sized to accommodate
299      * both a data and reply Parcel for the maximum of 16 Binder threads.
300      */
301     private static final int POOL_SIZE = 32;
302 
303     // Keep in sync with frameworks/native/include/private/binder/ParcelValTypes.h.
304     private static final int VAL_NULL = -1;
305     private static final int VAL_STRING = 0;
306     private static final int VAL_INTEGER = 1;
307     private static final int VAL_MAP = 2; // length-prefixed
308     private static final int VAL_BUNDLE = 3;
309     private static final int VAL_PARCELABLE = 4; // length-prefixed
310     private static final int VAL_SHORT = 5;
311     private static final int VAL_LONG = 6;
312     private static final int VAL_FLOAT = 7;
313     private static final int VAL_DOUBLE = 8;
314     private static final int VAL_BOOLEAN = 9;
315     private static final int VAL_CHARSEQUENCE = 10;
316     private static final int VAL_LIST  = 11; // length-prefixed
317     private static final int VAL_SPARSEARRAY = 12; // length-prefixed
318     private static final int VAL_BYTEARRAY = 13;
319     private static final int VAL_STRINGARRAY = 14;
320     private static final int VAL_IBINDER = 15;
321     private static final int VAL_PARCELABLEARRAY = 16; // length-prefixed
322     private static final int VAL_OBJECTARRAY = 17; // length-prefixed
323     private static final int VAL_INTARRAY = 18;
324     private static final int VAL_LONGARRAY = 19;
325     private static final int VAL_BYTE = 20;
326     private static final int VAL_SERIALIZABLE = 21; // length-prefixed
327     private static final int VAL_SPARSEBOOLEANARRAY = 22;
328     private static final int VAL_BOOLEANARRAY = 23;
329     private static final int VAL_CHARSEQUENCEARRAY = 24;
330     private static final int VAL_PERSISTABLEBUNDLE = 25;
331     private static final int VAL_SIZE = 26;
332     private static final int VAL_SIZEF = 27;
333     private static final int VAL_DOUBLEARRAY = 28;
334     private static final int VAL_CHAR = 29;
335     private static final int VAL_SHORTARRAY = 30;
336     private static final int VAL_CHARARRAY = 31;
337     private static final int VAL_FLOATARRAY = 32;
338 
339     // The initial int32 in a Binder call's reply Parcel header:
340     // Keep these in sync with libbinder's binder/Status.h.
341     private static final int EX_SECURITY = -1;
342     private static final int EX_BAD_PARCELABLE = -2;
343     private static final int EX_ILLEGAL_ARGUMENT = -3;
344     private static final int EX_NULL_POINTER = -4;
345     private static final int EX_ILLEGAL_STATE = -5;
346     private static final int EX_NETWORK_MAIN_THREAD = -6;
347     private static final int EX_UNSUPPORTED_OPERATION = -7;
348     private static final int EX_SERVICE_SPECIFIC = -8;
349     private static final int EX_PARCELABLE = -9;
350     /** @hide */
351     // WARNING: DO NOT add more 'reply' headers. These also need to add work to native
352     // code and this encodes extra information in object statuses. If we need to expand
353     // this design, we should add a generic way to attach parcelables/structured parcelables
354     // to transactions which can work across languages.
355     public static final int EX_HAS_NOTED_APPOPS_REPLY_HEADER = -127; // special; see below
356     // WARNING: DO NOT add more 'reply' headers. These also need to add work to native
357     // code and this encodes extra information in object statuses. If we need to expand
358     // this design, we should add a generic way to attach parcelables/structured parcelables
359     // to transactions which can work across languages.
360     private static final int EX_HAS_STRICTMODE_REPLY_HEADER = -128;  // special; see below
361     // EX_TRANSACTION_FAILED is used exclusively in native code.
362     // see libbinder's binder/Status.h
363     private static final int EX_TRANSACTION_FAILED = -129;
364 
365     @CriticalNative
nativeMarkSensitive(long nativePtr)366     private static native void nativeMarkSensitive(long nativePtr);
367     @FastNative
nativeMarkForBinder(long nativePtr, IBinder binder)368     private static native void nativeMarkForBinder(long nativePtr, IBinder binder);
369     @CriticalNative
nativeIsForRpc(long nativePtr)370     private static native boolean nativeIsForRpc(long nativePtr);
371     @CriticalNative
nativeDataSize(long nativePtr)372     private static native int nativeDataSize(long nativePtr);
373     @CriticalNative
nativeDataAvail(long nativePtr)374     private static native int nativeDataAvail(long nativePtr);
375     @CriticalNative
nativeDataPosition(long nativePtr)376     private static native int nativeDataPosition(long nativePtr);
377     @CriticalNative
nativeDataCapacity(long nativePtr)378     private static native int nativeDataCapacity(long nativePtr);
379     @FastNative
nativeSetDataSize(long nativePtr, int size)380     private static native void nativeSetDataSize(long nativePtr, int size);
381     @CriticalNative
nativeSetDataPosition(long nativePtr, int pos)382     private static native void nativeSetDataPosition(long nativePtr, int pos);
383     @FastNative
nativeSetDataCapacity(long nativePtr, int size)384     private static native void nativeSetDataCapacity(long nativePtr, int size);
385 
386     @CriticalNative
nativePushAllowFds(long nativePtr, boolean allowFds)387     private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds);
388     @CriticalNative
nativeRestoreAllowFds(long nativePtr, boolean lastValue)389     private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue);
390 
nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len)391     private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len);
nativeWriteBlob(long nativePtr, byte[] b, int offset, int len)392     private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len);
393     @CriticalNative
nativeWriteInt(long nativePtr, int val)394     private static native int nativeWriteInt(long nativePtr, int val);
395     @CriticalNative
nativeWriteLong(long nativePtr, long val)396     private static native int nativeWriteLong(long nativePtr, long val);
397     @CriticalNative
nativeWriteFloat(long nativePtr, float val)398     private static native int nativeWriteFloat(long nativePtr, float val);
399     @CriticalNative
nativeWriteDouble(long nativePtr, double val)400     private static native int nativeWriteDouble(long nativePtr, double val);
nativeSignalExceptionForError(int error)401     private static native void nativeSignalExceptionForError(int error);
402     @FastNative
nativeWriteString8(long nativePtr, String val)403     private static native void nativeWriteString8(long nativePtr, String val);
404     @FastNative
nativeWriteString16(long nativePtr, String val)405     private static native void nativeWriteString16(long nativePtr, String val);
406     @FastNative
nativeWriteStrongBinder(long nativePtr, IBinder val)407     private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
408     @FastNative
nativeWriteFileDescriptor(long nativePtr, FileDescriptor val)409     private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
410 
nativeCreateByteArray(long nativePtr)411     private static native byte[] nativeCreateByteArray(long nativePtr);
nativeReadByteArray(long nativePtr, byte[] dest, int destLen)412     private static native boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen);
nativeReadBlob(long nativePtr)413     private static native byte[] nativeReadBlob(long nativePtr);
414     @CriticalNative
nativeReadInt(long nativePtr)415     private static native int nativeReadInt(long nativePtr);
416     @CriticalNative
nativeReadLong(long nativePtr)417     private static native long nativeReadLong(long nativePtr);
418     @CriticalNative
nativeReadFloat(long nativePtr)419     private static native float nativeReadFloat(long nativePtr);
420     @CriticalNative
nativeReadDouble(long nativePtr)421     private static native double nativeReadDouble(long nativePtr);
422     @FastNative
nativeReadString8(long nativePtr)423     private static native String nativeReadString8(long nativePtr);
424     @FastNative
nativeReadString16(long nativePtr)425     private static native String nativeReadString16(long nativePtr);
426     @FastNative
nativeReadStrongBinder(long nativePtr)427     private static native IBinder nativeReadStrongBinder(long nativePtr);
428     @FastNative
nativeReadFileDescriptor(long nativePtr)429     private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);
430 
nativeCreate()431     private static native long nativeCreate();
nativeFreeBuffer(long nativePtr)432     private static native void nativeFreeBuffer(long nativePtr);
nativeDestroy(long nativePtr)433     private static native void nativeDestroy(long nativePtr);
434 
nativeMarshall(long nativePtr)435     private static native byte[] nativeMarshall(long nativePtr);
nativeUnmarshall( long nativePtr, byte[] data, int offset, int length)436     private static native void nativeUnmarshall(
437             long nativePtr, byte[] data, int offset, int length);
nativeCompareData(long thisNativePtr, long otherNativePtr)438     private static native int nativeCompareData(long thisNativePtr, long otherNativePtr);
nativeCompareDataInRange( long ptrA, int offsetA, long ptrB, int offsetB, int length)439     private static native boolean nativeCompareDataInRange(
440             long ptrA, int offsetA, long ptrB, int offsetB, int length);
nativeAppendFrom( long thisNativePtr, long otherNativePtr, int offset, int length)441     private static native void nativeAppendFrom(
442             long thisNativePtr, long otherNativePtr, int offset, int length);
443     @CriticalNative
nativeHasFileDescriptors(long nativePtr)444     private static native boolean nativeHasFileDescriptors(long nativePtr);
nativeHasFileDescriptorsInRange( long nativePtr, int offset, int length)445     private static native boolean nativeHasFileDescriptorsInRange(
446             long nativePtr, int offset, int length);
nativeWriteInterfaceToken(long nativePtr, String interfaceName)447     private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName);
nativeEnforceInterface(long nativePtr, String interfaceName)448     private static native void nativeEnforceInterface(long nativePtr, String interfaceName);
449 
450     @CriticalNative
nativeReplaceCallingWorkSourceUid( long nativePtr, int workSourceUid)451     private static native boolean nativeReplaceCallingWorkSourceUid(
452             long nativePtr, int workSourceUid);
453     @CriticalNative
nativeReadCallingWorkSourceUid(long nativePtr)454     private static native int nativeReadCallingWorkSourceUid(long nativePtr);
455 
456     /** Last time exception with a stack trace was written */
457     private static volatile long sLastWriteExceptionStackTrace;
458     /** Used for throttling of writing stack trace, which is costly */
459     private static final int WRITE_EXCEPTION_STACK_TRACE_THRESHOLD_MS = 1000;
460 
461     @CriticalNative
nativeGetOpenAshmemSize(long nativePtr)462     private static native long nativeGetOpenAshmemSize(long nativePtr);
463 
464     public final static Parcelable.Creator<String> STRING_CREATOR
465              = new Parcelable.Creator<String>() {
466         public String createFromParcel(Parcel source) {
467             return source.readString();
468         }
469         public String[] newArray(int size) {
470             return new String[size];
471         }
472     };
473 
474     /**
475      * @hide
476      */
477     public static class ReadWriteHelper {
478 
479         @UnsupportedAppUsage
ReadWriteHelper()480         public ReadWriteHelper() {
481         }
482 
483         public static final ReadWriteHelper DEFAULT = new ReadWriteHelper();
484 
485         /**
486          * Called when writing a string to a parcel. Subclasses wanting to write a string
487          * must use {@link #writeStringNoHelper(String)} to avoid
488          * infinity recursive calls.
489          */
writeString8(Parcel p, String s)490         public void writeString8(Parcel p, String s) {
491             p.writeString8NoHelper(s);
492         }
493 
writeString16(Parcel p, String s)494         public void writeString16(Parcel p, String s) {
495             p.writeString16NoHelper(s);
496         }
497 
498         /**
499          * Called when reading a string to a parcel. Subclasses wanting to read a string
500          * must use {@link #readStringNoHelper()} to avoid
501          * infinity recursive calls.
502          */
readString8(Parcel p)503         public String readString8(Parcel p) {
504             return p.readString8NoHelper();
505         }
506 
readString16(Parcel p)507         public String readString16(Parcel p) {
508             return p.readString16NoHelper();
509         }
510     }
511 
512     private ReadWriteHelper mReadWriteHelper = ReadWriteHelper.DEFAULT;
513 
514     /**
515      * Retrieve a new Parcel object from the pool.
516      */
517     @NonNull
obtain()518     public static Parcel obtain() {
519         Parcel res = null;
520         synchronized (sPoolSync) {
521             if (sOwnedPool != null) {
522                 res = sOwnedPool;
523                 sOwnedPool = res.mPoolNext;
524                 res.mPoolNext = null;
525                 sOwnedPoolSize--;
526             }
527         }
528 
529         // When no cache found above, create from scratch; otherwise prepare the
530         // cached object to be used
531         if (res == null) {
532             res = new Parcel(0);
533         } else {
534             res.mRecycled = false;
535             if (DEBUG_RECYCLE) {
536                 res.mStack = new RuntimeException();
537             }
538             res.mReadWriteHelper = ReadWriteHelper.DEFAULT;
539         }
540         return res;
541     }
542 
543     /**
544      * Retrieve a new Parcel object from the pool for use with a specific binder.
545      *
546      * Associate this parcel with a binder object. This marks the parcel as being prepared for a
547      * transaction on this specific binder object. Based on this, the format of the wire binder
548      * protocol may change. For future compatibility, it is recommended to use this for all
549      * Parcels.
550      */
551     @NonNull
obtain(@onNull IBinder binder)552     public static Parcel obtain(@NonNull IBinder binder) {
553         Parcel parcel = Parcel.obtain();
554         parcel.markForBinder(binder);
555         return parcel;
556     }
557 
558     /**
559      * Put a Parcel object back into the pool.  You must not touch
560      * the object after this call.
561      */
recycle()562     public final void recycle() {
563         if (mRecycled) {
564             Log.wtf(TAG, "Recycle called on unowned Parcel. (recycle twice?) Here: "
565                     + Log.getStackTraceString(new Throwable())
566                     + " Original recycle call (if DEBUG_RECYCLE): ", mStack);
567 
568             return;
569         }
570         mRecycled = true;
571 
572         // We try to reset the entire object here, but in order to be
573         // able to print a stack when a Parcel is recycled twice, that
574         // is cleared in obtain instead.
575 
576         mClassCookies = null;
577         freeBuffer();
578 
579         if (mOwnsNativeParcelObject) {
580             synchronized (sPoolSync) {
581                 if (sOwnedPoolSize < POOL_SIZE) {
582                     mPoolNext = sOwnedPool;
583                     sOwnedPool = this;
584                     sOwnedPoolSize++;
585                 }
586             }
587         } else {
588             mNativePtr = 0;
589             synchronized (sPoolSync) {
590                 if (sHolderPoolSize < POOL_SIZE) {
591                     mPoolNext = sHolderPool;
592                     sHolderPool = this;
593                     sHolderPoolSize++;
594                 }
595             }
596         }
597     }
598 
599     /**
600      * Set a {@link ReadWriteHelper}, which can be used to avoid having duplicate strings, for
601      * example.
602      *
603      * @hide
604      */
setReadWriteHelper(@ullable ReadWriteHelper helper)605     public void setReadWriteHelper(@Nullable ReadWriteHelper helper) {
606         mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT;
607     }
608 
609     /**
610      * @return whether this parcel has a {@link ReadWriteHelper}.
611      *
612      * @hide
613      */
hasReadWriteHelper()614     public boolean hasReadWriteHelper() {
615         return (mReadWriteHelper != null) && (mReadWriteHelper != ReadWriteHelper.DEFAULT);
616     }
617 
618     /** @hide */
619     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getGlobalAllocSize()620     public static native long getGlobalAllocSize();
621 
622     /** @hide */
623     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getGlobalAllocCount()624     public static native long getGlobalAllocCount();
625 
626     /**
627      * Parcel data should be zero'd before realloc'd or deleted.
628      *
629      * Note: currently this feature requires multiple things to work in concert:
630      * - markSensitive must be called on every relative Parcel
631      * - FLAG_CLEAR_BUF must be passed into the kernel
632      * This requires having code which does the right thing in every method and in every backend
633      * of AIDL. Rather than exposing this API, it should be replaced with a single API on
634      * IBinder objects which can be called once, and the information should be fed into the
635      * Parcel using markForBinder APIs. In terms of code size and number of API calls, this is
636      * much more extensible.
637      *
638      * @hide
639      */
markSensitive()640     public final void markSensitive() {
641         nativeMarkSensitive(mNativePtr);
642     }
643 
644     /**
645      * @hide
646      */
markForBinder(@onNull IBinder binder)647     private void markForBinder(@NonNull IBinder binder) {
648         nativeMarkForBinder(mNativePtr, binder);
649     }
650 
651     /**
652      * Whether this Parcel is written for an RPC transaction.
653      *
654      * @hide
655      */
isForRpc()656     public final boolean isForRpc() {
657         return nativeIsForRpc(mNativePtr);
658     }
659 
660     /** @hide */
661     @ParcelFlags
662     @TestApi
getFlags()663     public int getFlags() {
664         return mFlags;
665     }
666 
667     /** @hide */
setFlags(@arcelFlags int flags)668     public void setFlags(@ParcelFlags int flags) {
669         mFlags = flags;
670     }
671 
672     /** @hide */
addFlags(@arcelFlags int flags)673     public void addFlags(@ParcelFlags int flags) {
674         mFlags |= flags;
675     }
676 
677     /** @hide */
hasFlags(@arcelFlags int flags)678     private boolean hasFlags(@ParcelFlags int flags) {
679         return (mFlags & flags) == flags;
680     }
681 
682     /**
683      * This method is used by the AIDL compiler for system components. Not intended to be
684      * used by non-system apps.
685      */
686     // Note: Ideally this method should be @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES),
687     // but we need to make this method public due to the way the aidl compiler is compiled.
688     // We don't really need to protect it; even if 3p / non-system apps, nothing would happen.
689     // This would only work when used on a reply parcel by a binder object that's allowed-blocking.
setPropagateAllowBlocking()690     public void setPropagateAllowBlocking() {
691         addFlags(FLAG_PROPAGATE_ALLOW_BLOCKING);
692     }
693 
694     /**
695      * Returns the total amount of data contained in the parcel.
696      */
dataSize()697     public int dataSize() {
698         return nativeDataSize(mNativePtr);
699     }
700 
701     /**
702      * Returns the amount of data remaining to be read from the
703      * parcel.  That is, {@link #dataSize}-{@link #dataPosition}.
704      */
dataAvail()705     public final int dataAvail() {
706         return nativeDataAvail(mNativePtr);
707     }
708 
709     /**
710      * Returns the current position in the parcel data.  Never
711      * more than {@link #dataSize}.
712      */
dataPosition()713     public final int dataPosition() {
714         return nativeDataPosition(mNativePtr);
715     }
716 
717     /**
718      * Returns the total amount of space in the parcel.  This is always
719      * >= {@link #dataSize}.  The difference between it and dataSize() is the
720      * amount of room left until the parcel needs to re-allocate its
721      * data buffer.
722      */
dataCapacity()723     public final int dataCapacity() {
724         return nativeDataCapacity(mNativePtr);
725     }
726 
727     /**
728      * Change the amount of data in the parcel.  Can be either smaller or
729      * larger than the current size.  If larger than the current capacity,
730      * more memory will be allocated.
731      *
732      * @param size The new number of bytes in the Parcel.
733      */
setDataSize(int size)734     public final void setDataSize(int size) {
735         nativeSetDataSize(mNativePtr, size);
736     }
737 
738     /**
739      * Move the current read/write position in the parcel.
740      * @param pos New offset in the parcel; must be between 0 and
741      * {@link #dataSize}.
742      */
setDataPosition(int pos)743     public final void setDataPosition(int pos) {
744         nativeSetDataPosition(mNativePtr, pos);
745     }
746 
747     /**
748      * Change the capacity (current available space) of the parcel.
749      *
750      * @param size The new capacity of the parcel, in bytes.  Can not be
751      * less than {@link #dataSize} -- that is, you can not drop existing data
752      * with this method.
753      */
setDataCapacity(int size)754     public final void setDataCapacity(int size) {
755         nativeSetDataCapacity(mNativePtr, size);
756     }
757 
758     /** @hide */
pushAllowFds(boolean allowFds)759     public final boolean pushAllowFds(boolean allowFds) {
760         return nativePushAllowFds(mNativePtr, allowFds);
761     }
762 
763     /** @hide */
restoreAllowFds(boolean lastValue)764     public final void restoreAllowFds(boolean lastValue) {
765         nativeRestoreAllowFds(mNativePtr, lastValue);
766     }
767 
768     /**
769      * Returns the raw bytes of the parcel.
770      *
771      * <p class="note">The data you retrieve here <strong>must not</strong>
772      * be placed in any kind of persistent storage (on local disk, across
773      * a network, etc).  For that, you should use standard serialization
774      * or another kind of general serialization mechanism.  The Parcel
775      * marshalled representation is highly optimized for local IPC, and as
776      * such does not attempt to maintain compatibility with data created
777      * in different versions of the platform.
778      */
marshall()779     public final byte[] marshall() {
780         return nativeMarshall(mNativePtr);
781     }
782 
783     /**
784      * Fills the raw bytes of this Parcel with the supplied data.
785      */
unmarshall(@onNull byte[] data, int offset, int length)786     public final void unmarshall(@NonNull byte[] data, int offset, int length) {
787         nativeUnmarshall(mNativePtr, data, offset, length);
788     }
789 
appendFrom(Parcel parcel, int offset, int length)790     public final void appendFrom(Parcel parcel, int offset, int length) {
791         nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
792     }
793 
794     /** @hide */
compareData(Parcel other)795     public int compareData(Parcel other) {
796         return nativeCompareData(mNativePtr, other.mNativePtr);
797     }
798 
799     /** @hide */
compareData(Parcel a, int offsetA, Parcel b, int offsetB, int length)800     public static boolean compareData(Parcel a, int offsetA, Parcel b, int offsetB, int length) {
801         return nativeCompareDataInRange(a.mNativePtr, offsetA, b.mNativePtr, offsetB, length);
802     }
803 
804     /** @hide */
setClassCookie(Class clz, Object cookie)805     public final void setClassCookie(Class clz, Object cookie) {
806         if (mClassCookies == null) {
807             mClassCookies = new ArrayMap<>();
808         }
809         mClassCookies.put(clz, cookie);
810     }
811 
812     /** @hide */
813     @Nullable
getClassCookie(Class clz)814     public final Object getClassCookie(Class clz) {
815         return mClassCookies != null ? mClassCookies.get(clz) : null;
816     }
817 
818     /** @hide */
adoptClassCookies(Parcel from)819     public final void adoptClassCookies(Parcel from) {
820         mClassCookies = from.mClassCookies;
821     }
822 
823     /** @hide */
copyClassCookies()824     public Map<Class, Object> copyClassCookies() {
825         return new ArrayMap<>(mClassCookies);
826     }
827 
828     /** @hide */
putClassCookies(Map<Class, Object> cookies)829     public void putClassCookies(Map<Class, Object> cookies) {
830         if (cookies == null) {
831             return;
832         }
833         if (mClassCookies == null) {
834             mClassCookies = new ArrayMap<>();
835         }
836         mClassCookies.putAll(cookies);
837     }
838 
839     /**
840      * Report whether the parcel contains any marshalled file descriptors.
841      */
hasFileDescriptors()842     public boolean hasFileDescriptors() {
843         return nativeHasFileDescriptors(mNativePtr);
844     }
845 
846     /**
847      * Report whether the parcel contains any marshalled file descriptors in the range defined by
848      * {@code offset} and {@code length}.
849      *
850      * @param offset The offset from which the range starts. Should be between 0 and
851      *     {@link #dataSize()}.
852      * @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
853      *     offset}.
854      * @return whether there are file descriptors or not.
855      * @throws IllegalArgumentException if the parameters are out of the permitted ranges.
856      */
hasFileDescriptors(int offset, int length)857     public boolean hasFileDescriptors(int offset, int length) {
858         return nativeHasFileDescriptorsInRange(mNativePtr, offset, length);
859     }
860 
861     /**
862      * Check if the object has file descriptors.
863      *
864      * <p>Objects supported are {@link Parcel} and objects that can be passed to {@link
865      * #writeValue(Object)}}
866      *
867      * <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method
868      * for that.
869      *
870      * @throws IllegalArgumentException if you provide any object not supported by above methods
871      *     (including if the unsupported object is inside a nested container).
872      *
873      * @hide
874      */
hasFileDescriptors(Object value)875     public static boolean hasFileDescriptors(Object value) {
876         if (value instanceof Parcel) {
877             Parcel parcel = (Parcel) value;
878             if (parcel.hasFileDescriptors()) {
879                 return true;
880             }
881         } else if (value instanceof LazyValue) {
882             LazyValue lazy = (LazyValue) value;
883             if (lazy.hasFileDescriptors()) {
884                 return true;
885             }
886         } else if (value instanceof Parcelable) {
887             Parcelable parcelable = (Parcelable) value;
888             if ((parcelable.describeContents() & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
889                 return true;
890             }
891         } else if (value instanceof ArrayMap<?, ?>) {
892             ArrayMap<?, ?> map = (ArrayMap<?, ?>) value;
893             for (int i = 0, n = map.size(); i < n; i++) {
894                 if (hasFileDescriptors(map.keyAt(i))
895                         || hasFileDescriptors(map.valueAt(i))) {
896                     return true;
897                 }
898             }
899         } else if (value instanceof Map<?, ?>) {
900             Map<?, ?> map = (Map<?, ?>) value;
901             for (Map.Entry<?, ?> entry : map.entrySet()) {
902                 if (hasFileDescriptors(entry.getKey())
903                         || hasFileDescriptors(entry.getValue())) {
904                     return true;
905                 }
906             }
907         } else if (value instanceof List<?>) {
908             List<?> list = (List<?>) value;
909             for (int i = 0, n = list.size(); i < n; i++) {
910                 if (hasFileDescriptors(list.get(i))) {
911                     return true;
912                 }
913             }
914         } else if (value instanceof SparseArray<?>) {
915             SparseArray<?> array = (SparseArray<?>) value;
916             for (int i = 0, n = array.size(); i < n; i++) {
917                 if (hasFileDescriptors(array.valueAt(i))) {
918                     return true;
919                 }
920             }
921         } else if (value instanceof Object[]) {
922             Object[] array = (Object[]) value;
923             for (int i = 0, n = array.length; i < n; i++) {
924                 if (hasFileDescriptors(array[i])) {
925                     return true;
926                 }
927             }
928         } else {
929             getValueType(value); // Will throw if value is not supported
930         }
931         return false;
932     }
933 
934     /**
935      * Store or read an IBinder interface token in the parcel at the current
936      * {@link #dataPosition}. This is used to validate that the marshalled
937      * transaction is intended for the target interface. This is typically written
938      * at the beginning of transactions as a header.
939      */
writeInterfaceToken(@onNull String interfaceName)940     public final void writeInterfaceToken(@NonNull String interfaceName) {
941         nativeWriteInterfaceToken(mNativePtr, interfaceName);
942     }
943 
944     /**
945      * Read the header written by writeInterfaceToken and verify it matches
946      * the interface name in question. If the wrong interface type is present,
947      * {@link SecurityException} is thrown. When used over binder, this exception
948      * should propagate to the caller.
949      */
enforceInterface(@onNull String interfaceName)950     public final void enforceInterface(@NonNull String interfaceName) {
951         nativeEnforceInterface(mNativePtr, interfaceName);
952     }
953 
954     /**
955      * Verify there are no bytes left to be read on the Parcel.
956      *
957      * @throws BadParcelableException If the current position hasn't reached the end of the Parcel.
958      * When used over binder, this exception should propagate to the caller.
959      */
enforceNoDataAvail()960     public void enforceNoDataAvail() {
961         final int n = dataAvail();
962         if (n > 0) {
963             throw new BadParcelableException("Parcel data not fully consumed, unread size: " + n);
964         }
965     }
966 
967     /**
968      * Writes the work source uid to the request headers.
969      *
970      * <p>It requires the headers to have been written/read already to replace the work source.
971      *
972      * @return true if the request headers have been updated.
973      *
974      * @hide
975      */
replaceCallingWorkSourceUid(int workSourceUid)976     public boolean replaceCallingWorkSourceUid(int workSourceUid) {
977         return nativeReplaceCallingWorkSourceUid(mNativePtr, workSourceUid);
978     }
979 
980     /**
981      * Reads the work source uid from the request headers.
982      *
983      * <p>Unlike other read methods, this method does not read the parcel at the current
984      * {@link #dataPosition}. It will set the {@link #dataPosition} before the read and restore the
985      * position after reading the request header.
986      *
987      * @return the work source uid or {@link Binder#UNSET_WORKSOURCE} if headers have not been
988      * written/parsed yet.
989      *
990      * @hide
991      */
readCallingWorkSourceUid()992     public int readCallingWorkSourceUid() {
993         return nativeReadCallingWorkSourceUid(mNativePtr);
994     }
995 
996     /**
997      * Write a byte array into the parcel at the current {@link #dataPosition},
998      * growing {@link #dataCapacity} if needed.
999      * @param b Bytes to place into the parcel.
1000      */
writeByteArray(@ullable byte[] b)1001     public final void writeByteArray(@Nullable byte[] b) {
1002         writeByteArray(b, 0, (b != null) ? b.length : 0);
1003     }
1004 
1005     /**
1006      * Write a byte array into the parcel at the current {@link #dataPosition},
1007      * growing {@link #dataCapacity} if needed.
1008      * @param b Bytes to place into the parcel.
1009      * @param offset Index of first byte to be written.
1010      * @param len Number of bytes to write.
1011      */
writeByteArray(@ullable byte[] b, int offset, int len)1012     public final void writeByteArray(@Nullable byte[] b, int offset, int len) {
1013         if (b == null) {
1014             writeInt(-1);
1015             return;
1016         }
1017         ArrayUtils.throwsIfOutOfBounds(b.length, offset, len);
1018         nativeWriteByteArray(mNativePtr, b, offset, len);
1019     }
1020 
1021     /**
1022      * Write a blob of data into the parcel at the current {@link #dataPosition},
1023      * growing {@link #dataCapacity} if needed.
1024      *
1025      * <p> If the blob is small, then it is stored in-place, otherwise it is transferred by way of
1026      * an anonymous shared memory region. If you prefer send in-place, please use
1027      * {@link #writeByteArray(byte[])}.
1028      *
1029      * @param b Bytes to place into the parcel.
1030      *
1031      * @see #readBlob()
1032      */
writeBlob(@ullable byte[] b)1033     public final void writeBlob(@Nullable byte[] b) {
1034         writeBlob(b, 0, (b != null) ? b.length : 0);
1035     }
1036 
1037     /**
1038      * Write a blob of data into the parcel at the current {@link #dataPosition},
1039      * growing {@link #dataCapacity} if needed.
1040      *
1041      * <p> If the blob is small, then it is stored in-place, otherwise it is transferred by way of
1042      * an anonymous shared memory region. If you prefer send in-place, please use
1043      * {@link #writeByteArray(byte[], int, int)}.
1044      *
1045      * @param b Bytes to place into the parcel.
1046      * @param offset Index of first byte to be written.
1047      * @param len Number of bytes to write.
1048      *
1049      * @see #readBlob()
1050      */
writeBlob(@ullable byte[] b, int offset, int len)1051     public final void writeBlob(@Nullable byte[] b, int offset, int len) {
1052         if (b == null) {
1053             writeInt(-1);
1054             return;
1055         }
1056         ArrayUtils.throwsIfOutOfBounds(b.length, offset, len);
1057         nativeWriteBlob(mNativePtr, b, offset, len);
1058     }
1059 
1060     // The OK status from system/core/libutils/include/utils/Errors.h .
1061     // We shall pass all other error codes back to native for throwing exceptions. The error
1062     // check is done in Java to allow using @CriticalNative calls for the success path.
1063     private static final int OK = 0;
1064 
1065     /**
1066      * Write an integer value into the parcel at the current dataPosition(),
1067      * growing dataCapacity() if needed.
1068      */
writeInt(int val)1069     public final void writeInt(int val) {
1070         int err = nativeWriteInt(mNativePtr, val);
1071         if (err != OK) {
1072             nativeSignalExceptionForError(err);
1073         }
1074     }
1075 
1076     /**
1077      * Write a long integer value into the parcel at the current dataPosition(),
1078      * growing dataCapacity() if needed.
1079      */
writeLong(long val)1080     public final void writeLong(long val) {
1081         int err = nativeWriteLong(mNativePtr, val);
1082         if (err != OK) {
1083             nativeSignalExceptionForError(err);
1084         }
1085     }
1086 
1087     /**
1088      * Write a floating point value into the parcel at the current
1089      * dataPosition(), growing dataCapacity() if needed.
1090      */
writeFloat(float val)1091     public final void writeFloat(float val) {
1092         int err = nativeWriteFloat(mNativePtr, val);
1093         if (err != OK) {
1094             nativeSignalExceptionForError(err);
1095         }
1096     }
1097 
1098     /**
1099      * Write a double precision floating point value into the parcel at the
1100      * current dataPosition(), growing dataCapacity() if needed.
1101      */
writeDouble(double val)1102     public final void writeDouble(double val) {
1103         int err = nativeWriteDouble(mNativePtr, val);
1104         if (err != OK) {
1105             nativeSignalExceptionForError(err);
1106         }
1107     }
1108 
1109     /**
1110      * Write a string value into the parcel at the current dataPosition(),
1111      * growing dataCapacity() if needed.
1112      */
writeString(@ullable String val)1113     public final void writeString(@Nullable String val) {
1114         writeString16(val);
1115     }
1116 
1117     /** {@hide} */
writeString8(@ullable String val)1118     public final void writeString8(@Nullable String val) {
1119         mReadWriteHelper.writeString8(this, val);
1120     }
1121 
1122     /** {@hide} */
writeString16(@ullable String val)1123     public final void writeString16(@Nullable String val) {
1124         mReadWriteHelper.writeString16(this, val);
1125     }
1126 
1127     /**
1128      * Write a string without going though a {@link ReadWriteHelper}.  Subclasses of
1129      * {@link ReadWriteHelper} must use this method instead of {@link #writeString} to avoid
1130      * infinity recursive calls.
1131      *
1132      * @hide
1133      */
writeStringNoHelper(@ullable String val)1134     public void writeStringNoHelper(@Nullable String val) {
1135         writeString16NoHelper(val);
1136     }
1137 
1138     /** {@hide} */
writeString8NoHelper(@ullable String val)1139     public void writeString8NoHelper(@Nullable String val) {
1140         nativeWriteString8(mNativePtr, val);
1141     }
1142 
1143     /** {@hide} */
writeString16NoHelper(@ullable String val)1144     public void writeString16NoHelper(@Nullable String val) {
1145         nativeWriteString16(mNativePtr, val);
1146     }
1147 
1148     /**
1149      * Write a boolean value into the parcel at the current dataPosition(),
1150      * growing dataCapacity() if needed.
1151      *
1152      * <p>Note: This method currently delegates to writeInt with a value of 1 or 0
1153      * for true or false, respectively, but may change in the future.
1154      */
writeBoolean(boolean val)1155     public final void writeBoolean(boolean val) {
1156         writeInt(val ? 1 : 0);
1157     }
1158 
1159     /**
1160      * Write a CharSequence value into the parcel at the current dataPosition(),
1161      * growing dataCapacity() if needed.
1162      * @hide
1163      */
1164     @UnsupportedAppUsage
writeCharSequence(@ullable CharSequence val)1165     public final void writeCharSequence(@Nullable CharSequence val) {
1166         TextUtils.writeToParcel(val, this, 0);
1167     }
1168 
1169     /**
1170      * Write an object into the parcel at the current dataPosition(),
1171      * growing dataCapacity() if needed.
1172      */
writeStrongBinder(IBinder val)1173     public final void writeStrongBinder(IBinder val) {
1174         nativeWriteStrongBinder(mNativePtr, val);
1175     }
1176 
1177     /**
1178      * Write an object into the parcel at the current dataPosition(),
1179      * growing dataCapacity() if needed.
1180      */
writeStrongInterface(IInterface val)1181     public final void writeStrongInterface(IInterface val) {
1182         writeStrongBinder(val == null ? null : val.asBinder());
1183     }
1184 
1185     /**
1186      * Write a FileDescriptor into the parcel at the current dataPosition(),
1187      * growing dataCapacity() if needed.
1188      *
1189      * <p class="caution">The file descriptor will not be closed, which may
1190      * result in file descriptor leaks when objects are returned from Binder
1191      * calls.  Use {@link ParcelFileDescriptor#writeToParcel} instead, which
1192      * accepts contextual flags and will close the original file descriptor
1193      * if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
1194      */
writeFileDescriptor(@onNull FileDescriptor val)1195     public final void writeFileDescriptor(@NonNull FileDescriptor val) {
1196         nativeWriteFileDescriptor(mNativePtr, val);
1197     }
1198 
1199     /**
1200      * {@hide}
1201      * This will be the new name for writeFileDescriptor, for consistency.
1202      **/
writeRawFileDescriptor(@onNull FileDescriptor val)1203     public final void writeRawFileDescriptor(@NonNull FileDescriptor val) {
1204         nativeWriteFileDescriptor(mNativePtr, val);
1205     }
1206 
1207     /**
1208      * {@hide}
1209      * Write an array of FileDescriptor objects into the Parcel.
1210      *
1211      * @param value The array of objects to be written.
1212      */
writeRawFileDescriptorArray(@ullable FileDescriptor[] value)1213     public final void writeRawFileDescriptorArray(@Nullable FileDescriptor[] value) {
1214         if (value != null) {
1215             int N = value.length;
1216             writeInt(N);
1217             for (int i=0; i<N; i++) {
1218                 writeRawFileDescriptor(value[i]);
1219             }
1220         } else {
1221             writeInt(-1);
1222         }
1223     }
1224 
1225     /**
1226      * Write a byte value into the parcel at the current dataPosition(),
1227      * growing dataCapacity() if needed.
1228      *
1229      * <p>Note: This method currently delegates to writeInt but may change in
1230      * the future.
1231      */
writeByte(byte val)1232     public final void writeByte(byte val) {
1233         writeInt(val);
1234     }
1235 
1236     /**
1237      * Please use {@link #writeBundle} instead.  Flattens a Map into the parcel
1238      * at the current dataPosition(),
1239      * growing dataCapacity() if needed.  The Map keys must be String objects.
1240      * The Map values are written using {@link #writeValue} and must follow
1241      * the specification there.
1242      *
1243      * <p>It is strongly recommended to use {@link #writeBundle} instead of
1244      * this method, since the Bundle class provides a type-safe API that
1245      * allows you to avoid mysterious type errors at the point of marshalling.
1246      */
writeMap(@ullable Map val)1247     public final void writeMap(@Nullable Map val) {
1248         writeMapInternal((Map<String, Object>) val);
1249     }
1250 
1251     /**
1252      * Flatten a Map into the parcel at the current dataPosition(),
1253      * growing dataCapacity() if needed.  The Map keys must be String objects.
1254      */
writeMapInternal(@ullable Map<String,Object> val)1255     /* package */ void writeMapInternal(@Nullable Map<String,Object> val) {
1256         if (val == null) {
1257             writeInt(-1);
1258             return;
1259         }
1260         Set<Map.Entry<String,Object>> entries = val.entrySet();
1261         int size = entries.size();
1262         writeInt(size);
1263 
1264         for (Map.Entry<String,Object> e : entries) {
1265             writeValue(e.getKey());
1266             writeValue(e.getValue());
1267             size--;
1268         }
1269 
1270         if (size != 0) {
1271             throw new BadParcelableException("Map size does not match number of entries!");
1272         }
1273 
1274     }
1275 
1276     /**
1277      * Flatten an ArrayMap into the parcel at the current dataPosition(),
1278      * growing dataCapacity() if needed.  The Map keys must be String objects.
1279      */
writeArrayMapInternal(@ullable ArrayMap<String, Object> val)1280     /* package */ void writeArrayMapInternal(@Nullable ArrayMap<String, Object> val) {
1281         if (val == null) {
1282             writeInt(-1);
1283             return;
1284         }
1285         // Keep the format of this Parcel in sync with writeToParcelInner() in
1286         // frameworks/native/libs/binder/PersistableBundle.cpp.
1287         final int N = val.size();
1288         writeInt(N);
1289         if (DEBUG_ARRAY_MAP) {
1290             RuntimeException here =  new RuntimeException("here");
1291             here.fillInStackTrace();
1292             Log.d(TAG, "Writing " + N + " ArrayMap entries", here);
1293         }
1294         int startPos;
1295         for (int i=0; i<N; i++) {
1296             if (DEBUG_ARRAY_MAP) startPos = dataPosition();
1297             writeString(val.keyAt(i));
1298             writeValue(val.valueAt(i));
1299             if (DEBUG_ARRAY_MAP) Log.d(TAG, "  Write #" + i + " "
1300                     + (dataPosition()-startPos) + " bytes: key=0x"
1301                     + Integer.toHexString(val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0)
1302                     + " " + val.keyAt(i));
1303         }
1304     }
1305 
1306     /**
1307      * @hide For testing only.
1308      */
1309     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
writeArrayMap(@ullable ArrayMap<String, Object> val)1310     public void writeArrayMap(@Nullable ArrayMap<String, Object> val) {
1311         writeArrayMapInternal(val);
1312     }
1313 
1314     /**
1315      * Flatten an {@link ArrayMap} with string keys containing a particular object
1316      * type into the parcel at the current dataPosition() and growing dataCapacity()
1317      * if needed. The type of the objects in the array must be one that implements
1318      * Parcelable. Only the raw data of the objects is written and not their type,
1319      * so you must use the corresponding {@link #createTypedArrayMap(Parcelable.Creator)}
1320      *
1321      * @param val The map of objects to be written.
1322      * @param parcelableFlags The parcelable flags to use.
1323      *
1324      * @see #createTypedArrayMap(Parcelable.Creator)
1325      * @see Parcelable
1326      */
writeTypedArrayMap(@ullable ArrayMap<String, T> val, int parcelableFlags)1327     public <T extends Parcelable> void writeTypedArrayMap(@Nullable ArrayMap<String, T> val,
1328             int parcelableFlags) {
1329         if (val == null) {
1330             writeInt(-1);
1331             return;
1332         }
1333         final int count = val.size();
1334         writeInt(count);
1335         for (int i = 0; i < count; i++) {
1336             writeString(val.keyAt(i));
1337             writeTypedObject(val.valueAt(i), parcelableFlags);
1338         }
1339     }
1340 
1341     /**
1342      * Write an array set to the parcel.
1343      *
1344      * @param val The array set to write.
1345      *
1346      * @hide
1347      */
1348     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
writeArraySet(@ullable ArraySet<? extends Object> val)1349     public void writeArraySet(@Nullable ArraySet<? extends Object> val) {
1350         final int size = (val != null) ? val.size() : -1;
1351         writeInt(size);
1352         for (int i = 0; i < size; i++) {
1353             writeValue(val.valueAt(i));
1354         }
1355     }
1356 
1357     /**
1358      * Flatten a Bundle into the parcel at the current dataPosition(),
1359      * growing dataCapacity() if needed.
1360      */
writeBundle(@ullable Bundle val)1361     public final void writeBundle(@Nullable Bundle val) {
1362         if (val == null) {
1363             writeInt(-1);
1364             return;
1365         }
1366 
1367         val.writeToParcel(this, 0);
1368     }
1369 
1370     /**
1371      * Flatten a PersistableBundle into the parcel at the current dataPosition(),
1372      * growing dataCapacity() if needed.
1373      */
writePersistableBundle(@ullable PersistableBundle val)1374     public final void writePersistableBundle(@Nullable PersistableBundle val) {
1375         if (val == null) {
1376             writeInt(-1);
1377             return;
1378         }
1379 
1380         val.writeToParcel(this, 0);
1381     }
1382 
1383     /**
1384      * Flatten a Size into the parcel at the current dataPosition(),
1385      * growing dataCapacity() if needed.
1386      */
writeSize(@onNull Size val)1387     public final void writeSize(@NonNull Size val) {
1388         writeInt(val.getWidth());
1389         writeInt(val.getHeight());
1390     }
1391 
1392     /**
1393      * Flatten a SizeF into the parcel at the current dataPosition(),
1394      * growing dataCapacity() if needed.
1395      */
writeSizeF(@onNull SizeF val)1396     public final void writeSizeF(@NonNull SizeF val) {
1397         writeFloat(val.getWidth());
1398         writeFloat(val.getHeight());
1399     }
1400 
1401     /**
1402      * Flatten a List into the parcel at the current dataPosition(), growing
1403      * dataCapacity() if needed.  The List values are written using
1404      * {@link #writeValue} and must follow the specification there.
1405      */
writeList(@ullable List val)1406     public final void writeList(@Nullable List val) {
1407         if (val == null) {
1408             writeInt(-1);
1409             return;
1410         }
1411         int N = val.size();
1412         int i=0;
1413         writeInt(N);
1414         while (i < N) {
1415             writeValue(val.get(i));
1416             i++;
1417         }
1418     }
1419 
1420     /**
1421      * Flatten an Object array into the parcel at the current dataPosition(),
1422      * growing dataCapacity() if needed.  The array values are written using
1423      * {@link #writeValue} and must follow the specification there.
1424      */
writeArray(@ullable Object[] val)1425     public final void writeArray(@Nullable Object[] val) {
1426         if (val == null) {
1427             writeInt(-1);
1428             return;
1429         }
1430         int N = val.length;
1431         int i=0;
1432         writeInt(N);
1433         while (i < N) {
1434             writeValue(val[i]);
1435             i++;
1436         }
1437     }
1438 
1439     /**
1440      * Flatten a generic SparseArray into the parcel at the current
1441      * dataPosition(), growing dataCapacity() if needed.  The SparseArray
1442      * values are written using {@link #writeValue} and must follow the
1443      * specification there.
1444      */
writeSparseArray(@ullable SparseArray<T> val)1445     public final <T> void writeSparseArray(@Nullable SparseArray<T> val) {
1446         if (val == null) {
1447             writeInt(-1);
1448             return;
1449         }
1450         int N = val.size();
1451         writeInt(N);
1452         int i=0;
1453         while (i < N) {
1454             writeInt(val.keyAt(i));
1455             writeValue(val.valueAt(i));
1456             i++;
1457         }
1458     }
1459 
writeSparseBooleanArray(@ullable SparseBooleanArray val)1460     public final void writeSparseBooleanArray(@Nullable SparseBooleanArray val) {
1461         if (val == null) {
1462             writeInt(-1);
1463             return;
1464         }
1465         int N = val.size();
1466         writeInt(N);
1467         int i=0;
1468         while (i < N) {
1469             writeInt(val.keyAt(i));
1470             writeByte((byte)(val.valueAt(i) ? 1 : 0));
1471             i++;
1472         }
1473     }
1474 
1475     /**
1476      * @hide
1477      */
writeSparseIntArray(@ullable SparseIntArray val)1478     public final void writeSparseIntArray(@Nullable SparseIntArray val) {
1479         if (val == null) {
1480             writeInt(-1);
1481             return;
1482         }
1483         int N = val.size();
1484         writeInt(N);
1485         int i=0;
1486         while (i < N) {
1487             writeInt(val.keyAt(i));
1488             writeInt(val.valueAt(i));
1489             i++;
1490         }
1491     }
1492 
writeBooleanArray(@ullable boolean[] val)1493     public final void writeBooleanArray(@Nullable boolean[] val) {
1494         if (val != null) {
1495             int N = val.length;
1496             writeInt(N);
1497             for (int i=0; i<N; i++) {
1498                 writeInt(val[i] ? 1 : 0);
1499             }
1500         } else {
1501             writeInt(-1);
1502         }
1503     }
1504 
1505     @Nullable
createBooleanArray()1506     public final boolean[] createBooleanArray() {
1507         int N = readInt();
1508         // >>2 as a fast divide-by-4 works in the create*Array() functions
1509         // because dataAvail() will never return a negative number.  4 is
1510         // the size of a stored boolean in the stream.
1511         if (N >= 0 && N <= (dataAvail() >> 2)) {
1512             boolean[] val = new boolean[N];
1513             for (int i=0; i<N; i++) {
1514                 val[i] = readInt() != 0;
1515             }
1516             return val;
1517         } else {
1518             return null;
1519         }
1520     }
1521 
readBooleanArray(@onNull boolean[] val)1522     public final void readBooleanArray(@NonNull boolean[] val) {
1523         int N = readInt();
1524         if (N == val.length) {
1525             for (int i=0; i<N; i++) {
1526                 val[i] = readInt() != 0;
1527             }
1528         } else {
1529             throw new RuntimeException("bad array lengths");
1530         }
1531     }
1532 
1533     /** @hide */
writeShortArray(@ullable short[] val)1534     public void writeShortArray(@Nullable short[] val) {
1535         if (val != null) {
1536             int n = val.length;
1537             writeInt(n);
1538             for (int i = 0; i < n; i++) {
1539                 writeInt(val[i]);
1540             }
1541         } else {
1542             writeInt(-1);
1543         }
1544     }
1545 
1546     /** @hide */
1547     @Nullable
createShortArray()1548     public short[] createShortArray() {
1549         int n = readInt();
1550         if (n >= 0 && n <= (dataAvail() >> 2)) {
1551             short[] val = new short[n];
1552             for (int i = 0; i < n; i++) {
1553                 val[i] = (short) readInt();
1554             }
1555             return val;
1556         } else {
1557             return null;
1558         }
1559     }
1560 
1561     /** @hide */
readShortArray(@onNull short[] val)1562     public void readShortArray(@NonNull short[] val) {
1563         int n = readInt();
1564         if (n == val.length) {
1565             for (int i = 0; i < n; i++) {
1566                 val[i] = (short) readInt();
1567             }
1568         } else {
1569             throw new RuntimeException("bad array lengths");
1570         }
1571     }
1572 
writeCharArray(@ullable char[] val)1573     public final void writeCharArray(@Nullable char[] val) {
1574         if (val != null) {
1575             int N = val.length;
1576             writeInt(N);
1577             for (int i=0; i<N; i++) {
1578                 writeInt((int)val[i]);
1579             }
1580         } else {
1581             writeInt(-1);
1582         }
1583     }
1584 
1585     @Nullable
createCharArray()1586     public final char[] createCharArray() {
1587         int N = readInt();
1588         if (N >= 0 && N <= (dataAvail() >> 2)) {
1589             char[] val = new char[N];
1590             for (int i=0; i<N; i++) {
1591                 val[i] = (char)readInt();
1592             }
1593             return val;
1594         } else {
1595             return null;
1596         }
1597     }
1598 
readCharArray(@onNull char[] val)1599     public final void readCharArray(@NonNull char[] val) {
1600         int N = readInt();
1601         if (N == val.length) {
1602             for (int i=0; i<N; i++) {
1603                 val[i] = (char)readInt();
1604             }
1605         } else {
1606             throw new RuntimeException("bad array lengths");
1607         }
1608     }
1609 
writeIntArray(@ullable int[] val)1610     public final void writeIntArray(@Nullable int[] val) {
1611         if (val != null) {
1612             int N = val.length;
1613             writeInt(N);
1614             for (int i=0; i<N; i++) {
1615                 writeInt(val[i]);
1616             }
1617         } else {
1618             writeInt(-1);
1619         }
1620     }
1621 
1622     @Nullable
createIntArray()1623     public final int[] createIntArray() {
1624         int N = readInt();
1625         if (N >= 0 && N <= (dataAvail() >> 2)) {
1626             int[] val = new int[N];
1627             for (int i=0; i<N; i++) {
1628                 val[i] = readInt();
1629             }
1630             return val;
1631         } else {
1632             return null;
1633         }
1634     }
1635 
readIntArray(@onNull int[] val)1636     public final void readIntArray(@NonNull int[] val) {
1637         int N = readInt();
1638         if (N == val.length) {
1639             for (int i=0; i<N; i++) {
1640                 val[i] = readInt();
1641             }
1642         } else {
1643             throw new RuntimeException("bad array lengths");
1644         }
1645     }
1646 
writeLongArray(@ullable long[] val)1647     public final void writeLongArray(@Nullable long[] val) {
1648         if (val != null) {
1649             int N = val.length;
1650             writeInt(N);
1651             for (int i=0; i<N; i++) {
1652                 writeLong(val[i]);
1653             }
1654         } else {
1655             writeInt(-1);
1656         }
1657     }
1658 
1659     @Nullable
createLongArray()1660     public final long[] createLongArray() {
1661         int N = readInt();
1662         // >>3 because stored longs are 64 bits
1663         if (N >= 0 && N <= (dataAvail() >> 3)) {
1664             long[] val = new long[N];
1665             for (int i=0; i<N; i++) {
1666                 val[i] = readLong();
1667             }
1668             return val;
1669         } else {
1670             return null;
1671         }
1672     }
1673 
readLongArray(@onNull long[] val)1674     public final void readLongArray(@NonNull long[] val) {
1675         int N = readInt();
1676         if (N == val.length) {
1677             for (int i=0; i<N; i++) {
1678                 val[i] = readLong();
1679             }
1680         } else {
1681             throw new RuntimeException("bad array lengths");
1682         }
1683     }
1684 
writeFloatArray(@ullable float[] val)1685     public final void writeFloatArray(@Nullable float[] val) {
1686         if (val != null) {
1687             int N = val.length;
1688             writeInt(N);
1689             for (int i=0; i<N; i++) {
1690                 writeFloat(val[i]);
1691             }
1692         } else {
1693             writeInt(-1);
1694         }
1695     }
1696 
1697     @Nullable
createFloatArray()1698     public final float[] createFloatArray() {
1699         int N = readInt();
1700         // >>2 because stored floats are 4 bytes
1701         if (N >= 0 && N <= (dataAvail() >> 2)) {
1702             float[] val = new float[N];
1703             for (int i=0; i<N; i++) {
1704                 val[i] = readFloat();
1705             }
1706             return val;
1707         } else {
1708             return null;
1709         }
1710     }
1711 
readFloatArray(@onNull float[] val)1712     public final void readFloatArray(@NonNull float[] val) {
1713         int N = readInt();
1714         if (N == val.length) {
1715             for (int i=0; i<N; i++) {
1716                 val[i] = readFloat();
1717             }
1718         } else {
1719             throw new RuntimeException("bad array lengths");
1720         }
1721     }
1722 
writeDoubleArray(@ullable double[] val)1723     public final void writeDoubleArray(@Nullable double[] val) {
1724         if (val != null) {
1725             int N = val.length;
1726             writeInt(N);
1727             for (int i=0; i<N; i++) {
1728                 writeDouble(val[i]);
1729             }
1730         } else {
1731             writeInt(-1);
1732         }
1733     }
1734 
1735     @Nullable
createDoubleArray()1736     public final double[] createDoubleArray() {
1737         int N = readInt();
1738         // >>3 because stored doubles are 8 bytes
1739         if (N >= 0 && N <= (dataAvail() >> 3)) {
1740             double[] val = new double[N];
1741             for (int i=0; i<N; i++) {
1742                 val[i] = readDouble();
1743             }
1744             return val;
1745         } else {
1746             return null;
1747         }
1748     }
1749 
readDoubleArray(@onNull double[] val)1750     public final void readDoubleArray(@NonNull double[] val) {
1751         int N = readInt();
1752         if (N == val.length) {
1753             for (int i=0; i<N; i++) {
1754                 val[i] = readDouble();
1755             }
1756         } else {
1757             throw new RuntimeException("bad array lengths");
1758         }
1759     }
1760 
writeStringArray(@ullable String[] val)1761     public final void writeStringArray(@Nullable String[] val) {
1762         writeString16Array(val);
1763     }
1764 
1765     @Nullable
createStringArray()1766     public final String[] createStringArray() {
1767         return createString16Array();
1768     }
1769 
readStringArray(@onNull String[] val)1770     public final void readStringArray(@NonNull String[] val) {
1771         readString16Array(val);
1772     }
1773 
1774     /** {@hide} */
writeString8Array(@ullable String[] val)1775     public final void writeString8Array(@Nullable String[] val) {
1776         if (val != null) {
1777             int N = val.length;
1778             writeInt(N);
1779             for (int i=0; i<N; i++) {
1780                 writeString8(val[i]);
1781             }
1782         } else {
1783             writeInt(-1);
1784         }
1785     }
1786 
1787     /** {@hide} */
1788     @Nullable
createString8Array()1789     public final String[] createString8Array() {
1790         int N = readInt();
1791         if (N >= 0) {
1792             String[] val = new String[N];
1793             for (int i=0; i<N; i++) {
1794                 val[i] = readString8();
1795             }
1796             return val;
1797         } else {
1798             return null;
1799         }
1800     }
1801 
1802     /** {@hide} */
readString8Array(@onNull String[] val)1803     public final void readString8Array(@NonNull String[] val) {
1804         int N = readInt();
1805         if (N == val.length) {
1806             for (int i=0; i<N; i++) {
1807                 val[i] = readString8();
1808             }
1809         } else {
1810             throw new RuntimeException("bad array lengths");
1811         }
1812     }
1813 
1814     /** {@hide} */
writeString16Array(@ullable String[] val)1815     public final void writeString16Array(@Nullable String[] val) {
1816         if (val != null) {
1817             int N = val.length;
1818             writeInt(N);
1819             for (int i=0; i<N; i++) {
1820                 writeString16(val[i]);
1821             }
1822         } else {
1823             writeInt(-1);
1824         }
1825     }
1826 
1827     /** {@hide} */
1828     @Nullable
createString16Array()1829     public final String[] createString16Array() {
1830         int N = readInt();
1831         if (N >= 0) {
1832             String[] val = new String[N];
1833             for (int i=0; i<N; i++) {
1834                 val[i] = readString16();
1835             }
1836             return val;
1837         } else {
1838             return null;
1839         }
1840     }
1841 
1842     /** {@hide} */
readString16Array(@onNull String[] val)1843     public final void readString16Array(@NonNull String[] val) {
1844         int N = readInt();
1845         if (N == val.length) {
1846             for (int i=0; i<N; i++) {
1847                 val[i] = readString16();
1848             }
1849         } else {
1850             throw new RuntimeException("bad array lengths");
1851         }
1852     }
1853 
writeBinderArray(@ullable IBinder[] val)1854     public final void writeBinderArray(@Nullable IBinder[] val) {
1855         if (val != null) {
1856             int N = val.length;
1857             writeInt(N);
1858             for (int i=0; i<N; i++) {
1859                 writeStrongBinder(val[i]);
1860             }
1861         } else {
1862             writeInt(-1);
1863         }
1864     }
1865 
1866     /**
1867      * Flatten a homogeneous array containing an IInterface type into the parcel,
1868      * at the current dataPosition() and growing dataCapacity() if needed.  The
1869      * type of the objects in the array must be one that implements IInterface.
1870      *
1871      * @param val The array of objects to be written.
1872      *
1873      * @see #createInterfaceArray
1874      * @see #readInterfaceArray
1875      * @see IInterface
1876      */
writeInterfaceArray( @uppressLint"ArrayReturn") @ullable T[] val)1877     public final <T extends IInterface> void writeInterfaceArray(
1878             @SuppressLint("ArrayReturn") @Nullable T[] val) {
1879         if (val != null) {
1880             int N = val.length;
1881             writeInt(N);
1882             for (int i=0; i<N; i++) {
1883                 writeStrongInterface(val[i]);
1884             }
1885         } else {
1886             writeInt(-1);
1887         }
1888     }
1889 
1890     /**
1891      * @hide
1892      */
writeCharSequenceArray(@ullable CharSequence[] val)1893     public final void writeCharSequenceArray(@Nullable CharSequence[] val) {
1894         if (val != null) {
1895             int N = val.length;
1896             writeInt(N);
1897             for (int i=0; i<N; i++) {
1898                 writeCharSequence(val[i]);
1899             }
1900         } else {
1901             writeInt(-1);
1902         }
1903     }
1904 
1905     /**
1906      * @hide
1907      */
writeCharSequenceList(@ullable ArrayList<CharSequence> val)1908     public final void writeCharSequenceList(@Nullable ArrayList<CharSequence> val) {
1909         if (val != null) {
1910             int N = val.size();
1911             writeInt(N);
1912             for (int i=0; i<N; i++) {
1913                 writeCharSequence(val.get(i));
1914             }
1915         } else {
1916             writeInt(-1);
1917         }
1918     }
1919 
1920     @Nullable
createBinderArray()1921     public final IBinder[] createBinderArray() {
1922         int N = readInt();
1923         if (N >= 0) {
1924             IBinder[] val = new IBinder[N];
1925             for (int i=0; i<N; i++) {
1926                 val[i] = readStrongBinder();
1927             }
1928             return val;
1929         } else {
1930             return null;
1931         }
1932     }
1933 
readBinderArray(@onNull IBinder[] val)1934     public final void readBinderArray(@NonNull IBinder[] val) {
1935         int N = readInt();
1936         if (N == val.length) {
1937             for (int i=0; i<N; i++) {
1938                 val[i] = readStrongBinder();
1939             }
1940         } else {
1941             throw new RuntimeException("bad array lengths");
1942         }
1943     }
1944 
1945     /**
1946      * Read and return a new array of T (IInterface) from the parcel.
1947      *
1948      * @return the IInterface array of type T
1949      * @param newArray a function to create an array of T with a given length
1950      * @param asInterface a function to convert IBinder object into T (IInterface)
1951      */
1952     @SuppressLint({"ArrayReturn", "NullableCollection", "SamShouldBeLast"})
1953     @Nullable
createInterfaceArray( @onNull IntFunction<T[]> newArray, @NonNull Function<IBinder, T> asInterface)1954     public final <T extends IInterface> T[] createInterfaceArray(
1955             @NonNull IntFunction<T[]> newArray, @NonNull Function<IBinder, T> asInterface) {
1956         int N = readInt();
1957         if (N >= 0) {
1958             T[] val = newArray.apply(N);
1959             for (int i=0; i<N; i++) {
1960                 val[i] = asInterface.apply(readStrongBinder());
1961             }
1962             return val;
1963         } else {
1964             return null;
1965         }
1966     }
1967 
1968     /**
1969      * Read an array of T (IInterface) from a parcel.
1970      *
1971      * @param asInterface a function to convert IBinder object into T (IInterface)
1972      *
1973      * @throws BadParcelableException Throws BadParcelableException if the length of `val`
1974      *    mismatches the number of items in the parcel.
1975      */
readInterfaceArray( @uppressLint"ArrayReturn") @onNull T[] val, @NonNull Function<IBinder, T> asInterface)1976     public final <T extends IInterface> void readInterfaceArray(
1977             @SuppressLint("ArrayReturn") @NonNull T[] val,
1978             @NonNull Function<IBinder, T> asInterface) {
1979         int N = readInt();
1980         if (N == val.length) {
1981             for (int i=0; i<N; i++) {
1982                 val[i] = asInterface.apply(readStrongBinder());
1983             }
1984         } else {
1985             throw new BadParcelableException("bad array lengths");
1986         }
1987     }
1988 
1989     /**
1990      * Flatten a List containing a particular object type into the parcel, at
1991      * the current dataPosition() and growing dataCapacity() if needed.  The
1992      * type of the objects in the list must be one that implements Parcelable.
1993      * Unlike the generic writeList() method, however, only the raw data of the
1994      * objects is written and not their type, so you must use the corresponding
1995      * readTypedList() to unmarshall them.
1996      *
1997      * @param val The list of objects to be written.
1998      *
1999      * @see #createTypedArrayList
2000      * @see #readTypedList
2001      * @see Parcelable
2002      */
writeTypedList(@ullable List<T> val)2003     public final <T extends Parcelable> void writeTypedList(@Nullable List<T> val) {
2004         writeTypedList(val, 0);
2005     }
2006 
2007     /**
2008      * Flatten a {@link SparseArray} containing a particular object type into the parcel
2009      * at the current dataPosition() and growing dataCapacity() if needed. The
2010      * type of the objects in the array must be one that implements Parcelable.
2011      * Unlike the generic {@link #writeSparseArray(SparseArray)} method, however, only
2012      * the raw data of the objects is written and not their type, so you must use the
2013      * corresponding {@link #createTypedSparseArray(Parcelable.Creator)}.
2014      *
2015      * @param val The list of objects to be written.
2016      * @param parcelableFlags The parcelable flags to use.
2017      *
2018      * @see #createTypedSparseArray(Parcelable.Creator)
2019      * @see Parcelable
2020      */
writeTypedSparseArray(@ullable SparseArray<T> val, int parcelableFlags)2021     public final <T extends Parcelable> void writeTypedSparseArray(@Nullable SparseArray<T> val,
2022             int parcelableFlags) {
2023         if (val == null) {
2024             writeInt(-1);
2025             return;
2026         }
2027         final int count = val.size();
2028         writeInt(count);
2029         for (int i = 0; i < count; i++) {
2030             writeInt(val.keyAt(i));
2031             writeTypedObject(val.valueAt(i), parcelableFlags);
2032         }
2033     }
2034 
2035     /**
2036      * Flatten a List containing a particular object type into the parcel, at
2037      * the current dataPosition() and growing dataCapacity() if needed.  The
2038      * type of the objects in the list must be one that implements Parcelable.
2039      * Unlike the generic writeList() method, however, only the raw data of the
2040      * objects is written and not their type, so you must use the corresponding
2041      * readTypedList() to unmarshall them.
2042      *
2043      * @param val The list of objects to be written.
2044      * @param parcelableFlags Contextual flags as per
2045      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
2046      *
2047      * @see #createTypedArrayList
2048      * @see #readTypedList
2049      * @see Parcelable
2050      */
writeTypedList(@ullable List<T> val, int parcelableFlags)2051     public <T extends Parcelable> void writeTypedList(@Nullable List<T> val, int parcelableFlags) {
2052         if (val == null) {
2053             writeInt(-1);
2054             return;
2055         }
2056         int N = val.size();
2057         int i=0;
2058         writeInt(N);
2059         while (i < N) {
2060             writeTypedObject(val.get(i), parcelableFlags);
2061             i++;
2062         }
2063     }
2064 
2065     /**
2066      * Flatten a List containing String objects into the parcel, at
2067      * the current dataPosition() and growing dataCapacity() if needed.  They
2068      * can later be retrieved with {@link #createStringArrayList} or
2069      * {@link #readStringList}.
2070      *
2071      * @param val The list of strings to be written.
2072      *
2073      * @see #createStringArrayList
2074      * @see #readStringList
2075      */
writeStringList(@ullable List<String> val)2076     public final void writeStringList(@Nullable List<String> val) {
2077         if (val == null) {
2078             writeInt(-1);
2079             return;
2080         }
2081         int N = val.size();
2082         int i=0;
2083         writeInt(N);
2084         while (i < N) {
2085             writeString(val.get(i));
2086             i++;
2087         }
2088     }
2089 
2090     /**
2091      * Flatten a List containing IBinder objects into the parcel, at
2092      * the current dataPosition() and growing dataCapacity() if needed.  They
2093      * can later be retrieved with {@link #createBinderArrayList} or
2094      * {@link #readBinderList}.
2095      *
2096      * @param val The list of strings to be written.
2097      *
2098      * @see #createBinderArrayList
2099      * @see #readBinderList
2100      */
writeBinderList(@ullable List<IBinder> val)2101     public final void writeBinderList(@Nullable List<IBinder> val) {
2102         if (val == null) {
2103             writeInt(-1);
2104             return;
2105         }
2106         int N = val.size();
2107         int i=0;
2108         writeInt(N);
2109         while (i < N) {
2110             writeStrongBinder(val.get(i));
2111             i++;
2112         }
2113     }
2114 
2115     /**
2116      * Flatten a {@code List} containing T (IInterface) objects into this parcel
2117      * at the current position. They can later be retrieved with
2118      * {@link #createInterfaceArrayList} or {@link #readInterfaceList}.
2119      *
2120      * @see #createInterfaceArrayList
2121      * @see #readInterfaceList
2122      */
writeInterfaceList(@ullable List<T> val)2123     public final <T extends IInterface> void writeInterfaceList(@Nullable List<T> val) {
2124         if (val == null) {
2125             writeInt(-1);
2126             return;
2127         }
2128         int N = val.size();
2129         int i=0;
2130         writeInt(N);
2131         while (i < N) {
2132             writeStrongInterface(val.get(i));
2133             i++;
2134         }
2135     }
2136 
2137     /**
2138      * Flatten a {@code List} containing arbitrary {@code Parcelable} objects into this parcel
2139      * at the current position. They can later be retrieved using
2140      * {@link #readParcelableList(List, ClassLoader)} if required.
2141      *
2142      * @see #readParcelableList(List, ClassLoader)
2143      */
writeParcelableList(@ullable List<T> val, int flags)2144     public final <T extends Parcelable> void writeParcelableList(@Nullable List<T> val, int flags) {
2145         if (val == null) {
2146             writeInt(-1);
2147             return;
2148         }
2149 
2150         int N = val.size();
2151         int i=0;
2152         writeInt(N);
2153         while (i < N) {
2154             writeParcelable(val.get(i), flags);
2155             i++;
2156         }
2157     }
2158 
2159     /**
2160      * Flatten a homogeneous array containing a particular object type into
2161      * the parcel, at
2162      * the current dataPosition() and growing dataCapacity() if needed.  The
2163      * type of the objects in the array must be one that implements Parcelable.
2164      * Unlike the {@link #writeParcelableArray} method, however, only the
2165      * raw data of the objects is written and not their type, so you must use
2166      * {@link #readTypedArray} with the correct corresponding
2167      * {@link Parcelable.Creator} implementation to unmarshall them.
2168      *
2169      * @param val The array of objects to be written.
2170      * @param parcelableFlags Contextual flags as per
2171      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
2172      *
2173      * @see #readTypedArray
2174      * @see #writeParcelableArray
2175      * @see Parcelable.Creator
2176      */
writeTypedArray(@ullable T[] val, int parcelableFlags)2177     public final <T extends Parcelable> void writeTypedArray(@Nullable T[] val,
2178             int parcelableFlags) {
2179         if (val != null) {
2180             int N = val.length;
2181             writeInt(N);
2182             for (int i = 0; i < N; i++) {
2183                 writeTypedObject(val[i], parcelableFlags);
2184             }
2185         } else {
2186             writeInt(-1);
2187         }
2188     }
2189 
2190     /**
2191      * Flatten the Parcelable object into the parcel.
2192      *
2193      * @param val The Parcelable object to be written.
2194      * @param parcelableFlags Contextual flags as per
2195      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
2196      *
2197      * @see #readTypedObject
2198      */
writeTypedObject(@ullable T val, int parcelableFlags)2199     public final <T extends Parcelable> void writeTypedObject(@Nullable T val,
2200             int parcelableFlags) {
2201         if (val != null) {
2202             writeInt(1);
2203             val.writeToParcel(this, parcelableFlags);
2204         } else {
2205             writeInt(0);
2206         }
2207     }
2208 
2209     /**
2210      * Flatten a homogeneous multi-dimensional array with fixed-size.  This delegates to other
2211      * APIs to write a one-dimensional array.  Use {@link #readFixedArray(Object)} or
2212      * {@link #createFixedArray(Class, int[])} with the same dimensions to unmarshal.
2213      *
2214      * @param val The array to be written.
2215      * @param parcelableFlags Contextual flags as per
2216      *   {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
2217      *   Used only if val is an array of Parcelable objects.
2218      * @param dimensions an array of int representing length of each dimension. The array should be
2219      *   sized with the exact size of dimensions.
2220      *
2221      * @see #readFixedArray
2222      * @see #createFixedArray createFixedArray(Class&lt;T&gt;, Parcelable.Creator&lt;S&gt;, int...)
2223      * @see #writeBooleanArray
2224      * @see #writeByteArray
2225      * @see #writeCharArray
2226      * @see #writeIntArray
2227      * @see #writeLongArray
2228      * @see #writeFloatArray
2229      * @see #writeDoubleArray
2230      * @see #writeBinderArray
2231      * @see #writeInterfaceArray
2232      * @see #writeTypedArray
2233      * @throws BadParcelableException If the array's component type is not supported or if its
2234      *   size doesn't match with the given dimensions.
2235      */
writeFixedArray(@ullable T val, int parcelableFlags, @NonNull int... dimensions)2236     public <T> void writeFixedArray(@Nullable T val, int parcelableFlags,
2237             @NonNull int... dimensions) {
2238         if (val == null) {
2239             writeInt(-1);
2240             return;
2241         }
2242         writeFixedArrayInternal(val, parcelableFlags, /*index=*/0, dimensions);
2243     }
2244 
writeFixedArrayInternal(T val, int parcelableFlags, int index, int[] dimensions)2245     private <T> void writeFixedArrayInternal(T val, int parcelableFlags, int index,
2246             int[] dimensions) {
2247         if (index >= dimensions.length) {
2248             throw new BadParcelableException("Array has more dimensions than expected: "
2249                 + dimensions.length);
2250         }
2251 
2252         int length = dimensions[index];
2253 
2254         // val should be an array of length N
2255         if (val == null) {
2256             throw new BadParcelableException("Non-null array shouldn't have a null array.");
2257         }
2258         if (!val.getClass().isArray()) {
2259             throw new BadParcelableException("Not an array: " + val);
2260         }
2261         if (Array.getLength(val) != length) {
2262             throw new BadParcelableException("bad length: expected " + length + ", but got "
2263                 + Array.getLength(val));
2264         }
2265 
2266         // Delegates to other writers if this is a one-dimensional array.
2267         // Otherwise, write component arrays with recursive calls.
2268 
2269         final Class<?> componentType = val.getClass().getComponentType();
2270         if (!componentType.isArray() && index + 1 != dimensions.length) {
2271             throw new BadParcelableException("Array has fewer dimensions than expected: "
2272                 + dimensions.length);
2273         }
2274         if (componentType == boolean.class) {
2275             writeBooleanArray((boolean[]) val);
2276         } else if (componentType == byte.class) {
2277             writeByteArray((byte[]) val);
2278         } else if (componentType == char.class) {
2279             writeCharArray((char[]) val);
2280         } else if (componentType == int.class) {
2281             writeIntArray((int[]) val);
2282         } else if (componentType == long.class) {
2283             writeLongArray((long[]) val);
2284         } else if (componentType == float.class) {
2285             writeFloatArray((float[]) val);
2286         } else if (componentType == double.class) {
2287             writeDoubleArray((double[]) val);
2288         } else if (componentType == IBinder.class) {
2289             writeBinderArray((IBinder[]) val);
2290         } else if (IInterface.class.isAssignableFrom(componentType)) {
2291             writeInterfaceArray((IInterface[]) val);
2292         } else if (Parcelable.class.isAssignableFrom(componentType)) {
2293             writeTypedArray((Parcelable[]) val, parcelableFlags);
2294         } else if (componentType.isArray()) {
2295             writeInt(length);
2296             for (int i = 0; i < length; i++) {
2297                 writeFixedArrayInternal(Array.get(val, i), parcelableFlags, index + 1,
2298                         dimensions);
2299             }
2300         } else {
2301             throw new BadParcelableException("unknown type for fixed-size array: " + componentType);
2302         }
2303     }
2304 
2305     /**
2306      * Flatten a generic object in to a parcel.  The given Object value may
2307      * currently be one of the following types:
2308      *
2309      * <ul>
2310      * <li> null
2311      * <li> String
2312      * <li> Byte
2313      * <li> Short
2314      * <li> Integer
2315      * <li> Long
2316      * <li> Float
2317      * <li> Double
2318      * <li> Boolean
2319      * <li> String[]
2320      * <li> boolean[]
2321      * <li> byte[]
2322      * <li> int[]
2323      * <li> long[]
2324      * <li> Object[] (supporting objects of the same type defined here).
2325      * <li> {@link Bundle}
2326      * <li> Map (as supported by {@link #writeMap}).
2327      * <li> Any object that implements the {@link Parcelable} protocol.
2328      * <li> Parcelable[]
2329      * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}).
2330      * <li> List (as supported by {@link #writeList}).
2331      * <li> {@link SparseArray} (as supported by {@link #writeSparseArray(SparseArray)}).
2332      * <li> {@link IBinder}
2333      * <li> Any object that implements Serializable (but see
2334      *      {@link #writeSerializable} for caveats).  Note that all of the
2335      *      previous types have relatively efficient implementations for
2336      *      writing to a Parcel; having to rely on the generic serialization
2337      *      approach is much less efficient and should be avoided whenever
2338      *      possible.
2339      * </ul>
2340      *
2341      * <p class="caution">{@link Parcelable} objects are written with
2342      * {@link Parcelable#writeToParcel} using contextual flags of 0.  When
2343      * serializing objects containing {@link ParcelFileDescriptor}s,
2344      * this may result in file descriptor leaks when they are returned from
2345      * Binder calls (where {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}
2346      * should be used).</p>
2347      */
writeValue(@ullable Object v)2348     public final void writeValue(@Nullable Object v) {
2349         if (v instanceof LazyValue) {
2350             LazyValue value = (LazyValue) v;
2351             value.writeToParcel(this);
2352             return;
2353         }
2354         int type = getValueType(v);
2355         writeInt(type);
2356         if (isLengthPrefixed(type)) {
2357             // Length
2358             int length = dataPosition();
2359             writeInt(-1); // Placeholder
2360             // Object
2361             int start = dataPosition();
2362             writeValue(type, v);
2363             int end = dataPosition();
2364             // Backpatch length
2365             setDataPosition(length);
2366             writeInt(end - start);
2367             setDataPosition(end);
2368         } else {
2369             writeValue(type, v);
2370         }
2371     }
2372 
2373     /** @hide */
getValueType(@ullable Object v)2374     public static int getValueType(@Nullable Object v) {
2375         if (v == null) {
2376             return VAL_NULL;
2377         } else if (v instanceof String) {
2378             return VAL_STRING;
2379         } else if (v instanceof Integer) {
2380             return VAL_INTEGER;
2381         } else if (v instanceof Map) {
2382             return VAL_MAP;
2383         } else if (v instanceof Bundle) {
2384             // Must be before Parcelable
2385             return VAL_BUNDLE;
2386         } else if (v instanceof PersistableBundle) {
2387             // Must be before Parcelable
2388             return VAL_PERSISTABLEBUNDLE;
2389         } else if (v instanceof SizeF) {
2390             // Must be before Parcelable
2391             return VAL_SIZEF;
2392         } else if (v instanceof Parcelable) {
2393             // IMPOTANT: cases for classes that implement Parcelable must
2394             // come before the Parcelable case, so that their speci fic VAL_*
2395             // types will be written.
2396             return VAL_PARCELABLE;
2397         } else if (v instanceof Short) {
2398             return VAL_SHORT;
2399         } else if (v instanceof Long) {
2400             return VAL_LONG;
2401         } else if (v instanceof Float) {
2402             return VAL_FLOAT;
2403         } else if (v instanceof Double) {
2404             return VAL_DOUBLE;
2405         } else if (v instanceof Boolean) {
2406             return VAL_BOOLEAN;
2407         } else if (v instanceof CharSequence) {
2408             // Must be after String
2409             return VAL_CHARSEQUENCE;
2410         } else if (v instanceof List) {
2411             return VAL_LIST;
2412         } else if (v instanceof SparseArray) {
2413             return VAL_SPARSEARRAY;
2414         } else if (v instanceof boolean[]) {
2415             return VAL_BOOLEANARRAY;
2416         } else if (v instanceof byte[]) {
2417             return VAL_BYTEARRAY;
2418         } else if (v instanceof String[]) {
2419             return VAL_STRINGARRAY;
2420         } else if (v instanceof CharSequence[]) {
2421             // Must be after String[] and before Object[]
2422             return VAL_CHARSEQUENCEARRAY;
2423         } else if (v instanceof IBinder) {
2424             return VAL_IBINDER;
2425         } else if (v instanceof Parcelable[]) {
2426             return VAL_PARCELABLEARRAY;
2427         } else if (v instanceof int[]) {
2428             return VAL_INTARRAY;
2429         } else if (v instanceof long[]) {
2430             return VAL_LONGARRAY;
2431         } else if (v instanceof Byte) {
2432             return VAL_BYTE;
2433         } else if (v instanceof Size) {
2434             return VAL_SIZE;
2435         } else if (v instanceof double[]) {
2436             return VAL_DOUBLEARRAY;
2437         } else if (v instanceof Character) {
2438             return VAL_CHAR;
2439         } else if (v instanceof short[]) {
2440             return VAL_SHORTARRAY;
2441         } else if (v instanceof char[]) {
2442             return VAL_CHARARRAY;
2443         } else  if (v instanceof float[]) {
2444             return VAL_FLOATARRAY;
2445         } else {
2446             Class<?> clazz = v.getClass();
2447             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
2448                 // Only pure Object[] are written here, Other arrays of non-primitive types are
2449                 // handled by serialization as this does not record the component type.
2450                 return VAL_OBJECTARRAY;
2451             } else if (v instanceof Serializable) {
2452                 // Must be last
2453                 return VAL_SERIALIZABLE;
2454             } else {
2455                 throw new IllegalArgumentException("Parcel: unknown type for value " + v);
2456             }
2457         }
2458     }
2459     /**
2460      * Writes value {@code v} in the parcel. This does NOT write the int representing the type
2461      * first.
2462      *
2463      * @hide
2464      */
writeValue(int type, @Nullable Object v)2465     public void writeValue(int type, @Nullable Object v) {
2466         switch (type) {
2467             case VAL_NULL:
2468                 break;
2469             case VAL_STRING:
2470                 writeString((String) v);
2471                 break;
2472             case VAL_INTEGER:
2473                 writeInt((Integer) v);
2474                 break;
2475             case VAL_MAP:
2476                 writeMap((Map) v);
2477                 break;
2478             case VAL_BUNDLE:
2479                 writeBundle((Bundle) v);
2480                 break;
2481             case VAL_PERSISTABLEBUNDLE:
2482                 writePersistableBundle((PersistableBundle) v);
2483                 break;
2484             case VAL_PARCELABLE:
2485                 writeParcelable((Parcelable) v, 0);
2486                 break;
2487             case VAL_SHORT:
2488                 writeInt(((Short) v).intValue());
2489                 break;
2490             case VAL_LONG:
2491                 writeLong((Long) v);
2492                 break;
2493             case VAL_FLOAT:
2494                 writeFloat((Float) v);
2495                 break;
2496             case VAL_DOUBLE:
2497                 writeDouble((Double) v);
2498                 break;
2499             case VAL_BOOLEAN:
2500                 writeInt((Boolean) v ? 1 : 0);
2501                 break;
2502             case VAL_CHARSEQUENCE:
2503                 writeCharSequence((CharSequence) v);
2504                 break;
2505             case VAL_LIST:
2506                 writeList((List) v);
2507                 break;
2508             case VAL_SPARSEARRAY:
2509                 writeSparseArray((SparseArray) v);
2510                 break;
2511             case VAL_BOOLEANARRAY:
2512                 writeBooleanArray((boolean[]) v);
2513                 break;
2514             case VAL_BYTEARRAY:
2515                 writeByteArray((byte[]) v);
2516                 break;
2517             case VAL_STRINGARRAY:
2518                 writeStringArray((String[]) v);
2519                 break;
2520             case VAL_CHARSEQUENCEARRAY:
2521                 writeCharSequenceArray((CharSequence[]) v);
2522                 break;
2523             case VAL_IBINDER:
2524                 writeStrongBinder((IBinder) v);
2525                 break;
2526             case VAL_PARCELABLEARRAY:
2527                 writeParcelableArray((Parcelable[]) v, 0);
2528                 break;
2529             case VAL_INTARRAY:
2530                 writeIntArray((int[]) v);
2531                 break;
2532             case VAL_LONGARRAY:
2533                 writeLongArray((long[]) v);
2534                 break;
2535             case VAL_BYTE:
2536                 writeInt((Byte) v);
2537                 break;
2538             case VAL_SIZE:
2539                 writeSize((Size) v);
2540                 break;
2541             case VAL_SIZEF:
2542                 writeSizeF((SizeF) v);
2543                 break;
2544             case VAL_DOUBLEARRAY:
2545                 writeDoubleArray((double[]) v);
2546                 break;
2547             case VAL_CHAR:
2548                 writeInt((Character) v);
2549                 break;
2550             case VAL_SHORTARRAY:
2551                 writeShortArray((short[]) v);
2552                 break;
2553             case VAL_CHARARRAY:
2554                 writeCharArray((char[]) v);
2555                 break;
2556             case VAL_FLOATARRAY:
2557                 writeFloatArray((float[]) v);
2558                 break;
2559             case VAL_OBJECTARRAY:
2560                 writeArray((Object[]) v);
2561                 break;
2562             case VAL_SERIALIZABLE:
2563                 writeSerializable((Serializable) v);
2564                 break;
2565             default:
2566                 throw new RuntimeException("Parcel: unable to marshal value " + v);
2567         }
2568     }
2569 
2570     /**
2571      * Flatten the name of the class of the Parcelable and its contents
2572      * into the parcel.
2573      *
2574      * @param p The Parcelable object to be written.
2575      * @param parcelableFlags Contextual flags as per
2576      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
2577      */
writeParcelable(@ullable Parcelable p, int parcelableFlags)2578     public final void writeParcelable(@Nullable Parcelable p, int parcelableFlags) {
2579         if (p == null) {
2580             writeString(null);
2581             return;
2582         }
2583         writeParcelableCreator(p);
2584         p.writeToParcel(this, parcelableFlags);
2585     }
2586 
2587     /**
2588      * Flatten the name of the class of the Parcelable into this Parcel.
2589      *
2590      * @param p The Parcelable object to be written.
2591      * @see #readParcelableCreator
2592      */
writeParcelableCreator(@onNull Parcelable p)2593     public final void writeParcelableCreator(@NonNull Parcelable p) {
2594         String name = p.getClass().getName();
2595         writeString(name);
2596     }
2597 
2598     /**
2599      * A map used by {@link #maybeWriteSquashed} to keep track of what parcelables have
2600      * been seen, and what positions they were written. The value is the absolute position of
2601      * each parcelable.
2602      */
2603     private ArrayMap<Parcelable, Integer> mWrittenSquashableParcelables;
2604 
ensureWrittenSquashableParcelables()2605     private void ensureWrittenSquashableParcelables() {
2606         if (mWrittenSquashableParcelables != null) {
2607             return;
2608         }
2609         mWrittenSquashableParcelables = new ArrayMap<>();
2610     }
2611 
2612     private boolean mAllowSquashing = false;
2613 
2614     /**
2615      * Allow "squashing" writes in {@link #maybeWriteSquashed}. This allows subsequent calls to
2616      * {@link #maybeWriteSquashed(Parcelable)} to "squash" the same instances into one in a Parcel.
2617      *
2618      * Typically, this method is called at the beginning of {@link Parcelable#writeToParcel}. The
2619      * caller must retain the return value from this method and call {@link #restoreAllowSquashing}
2620      * with it.
2621      *
2622      * See {@link #maybeWriteSquashed(Parcelable)} for the details.
2623      *
2624      * @see #restoreAllowSquashing(boolean)
2625      * @see #maybeWriteSquashed(Parcelable)
2626      * @see #readSquashed(SquashReadHelper)
2627      *
2628      * @hide
2629      */
2630     @TestApi
allowSquashing()2631     public boolean allowSquashing() {
2632         boolean previous = mAllowSquashing;
2633         mAllowSquashing = true;
2634         return previous;
2635     }
2636 
2637     /**
2638      * @see #allowSquashing()
2639      * @hide
2640      */
2641     @TestApi
restoreAllowSquashing(boolean previous)2642     public void restoreAllowSquashing(boolean previous) {
2643         mAllowSquashing = previous;
2644         if (!mAllowSquashing) {
2645             mWrittenSquashableParcelables = null;
2646         }
2647     }
2648 
resetSqaushingState()2649     private void resetSqaushingState() {
2650         if (mAllowSquashing) {
2651             Slog.wtf(TAG, "allowSquashing wasn't restored.");
2652         }
2653         mWrittenSquashableParcelables = null;
2654         mReadSquashableParcelables = null;
2655         mAllowSquashing = false;
2656     }
2657 
2658     /**
2659      * A map used by {@link #readSquashed} to cache parcelables. It's a map from
2660      * an absolute position in a Parcel to the parcelable stored at the position.
2661      */
2662     private SparseArray<Parcelable> mReadSquashableParcelables;
2663 
ensureReadSquashableParcelables()2664     private void ensureReadSquashableParcelables() {
2665         if (mReadSquashableParcelables != null) {
2666             return;
2667         }
2668         mReadSquashableParcelables = new SparseArray<>();
2669     }
2670 
2671     /**
2672      * Write a parcelable with "squash" -- that is, when the same instance is written to the
2673      * same Parcelable multiple times, instead of writing the entire instance multiple times,
2674      * only write it once, and in subsequent writes we'll only write the offset to the original
2675      * object.
2676      *
2677      * This approach does not work of the resulting Parcel is copied with {@link #appendFrom} with
2678      * a non-zero offset, so we do not enable this behavior by default. Instead, we only enable
2679      * it between {@link #allowSquashing} and {@link #restoreAllowSquashing}, in order to make sure
2680      * we only do so within each "top level" Parcelable.
2681      *
2682      * Usage: Use this method in {@link Parcelable#writeToParcel}.
2683      * If this method returns TRUE, it's a subsequent call, and the offset is already written,
2684      * so the caller doesn't have to do anything. If this method returns FALSE, it's the first
2685      * time for the instance to be written to this parcel. The caller has to proceed with its
2686      * {@link Parcelable#writeToParcel}.
2687      *
2688      * (See {@code ApplicationInfo} for the example.)
2689      *
2690      * @param p the target Parcelable to write.
2691      *
2692      * @see #allowSquashing()
2693      * @see #restoreAllowSquashing(boolean)
2694      * @see #readSquashed(SquashReadHelper)
2695      *
2696      * @hide
2697      */
maybeWriteSquashed(@onNull Parcelable p)2698     public boolean maybeWriteSquashed(@NonNull Parcelable p) {
2699         if (!mAllowSquashing) {
2700             // Don't squash, and don't put it in the map either.
2701             writeInt(0);
2702             return false;
2703         }
2704         ensureWrittenSquashableParcelables();
2705         final Integer firstPos = mWrittenSquashableParcelables.get(p);
2706         if (firstPos != null) {
2707             // Already written.
2708             // Write the relative offset from the current position to the first position.
2709             final int pos = dataPosition();
2710 
2711             // We want the offset from the next byte of this integer, so we need to +4.
2712             writeInt(pos - firstPos + 4);
2713             return true;
2714         }
2715         // First time seen, write a marker.
2716         writeInt(0);
2717 
2718         // Remember the position.
2719         final int pos = dataPosition();
2720         mWrittenSquashableParcelables.put(p, pos);
2721 
2722         // Return false and let the caller actually write the content.
2723         return false;
2724     }
2725 
2726     /**
2727      * Helper function that's used by {@link #readSquashed(SquashReadHelper)}
2728      * @hide
2729      */
2730     public interface SquashReadHelper<T> {
2731         /** Read and instantiate {@code T} from a Parcel. */
2732         @NonNull
readRawParceled(@onNull Parcel p)2733         T readRawParceled(@NonNull Parcel p);
2734     }
2735 
2736     /**
2737      * Read a {@link Parcelable} that's written with {@link #maybeWriteSquashed}.
2738      *
2739      * @param reader a callback function that instantiates an instance from a parcel.
2740      * Typicallly, a lambda to the instructor that takes a {@link Parcel} is passed.
2741      *
2742      * @see #maybeWriteSquashed(Parcelable)
2743      *
2744      * @hide
2745      */
2746     @SuppressWarnings("unchecked")
2747     @Nullable
readSquashed(SquashReadHelper<T> reader)2748     public <T extends Parcelable> T readSquashed(SquashReadHelper<T> reader) {
2749         final int offset = readInt();
2750         final int pos = dataPosition();
2751 
2752         if (offset == 0) {
2753             // First time read. Unparcel, and remember it.
2754             final T p = reader.readRawParceled(this);
2755             ensureReadSquashableParcelables();
2756             mReadSquashableParcelables.put(pos, p);
2757             return p;
2758         }
2759         // Subsequent read.
2760         final int firstAbsolutePos = pos - offset;
2761 
2762         final Parcelable p = mReadSquashableParcelables.get(firstAbsolutePos);
2763         if (p == null) {
2764             final StringBuilder sb = new StringBuilder();
2765             for (int i = 0; i < mReadSquashableParcelables.size(); i++) {
2766                 sb.append(mReadSquashableParcelables.keyAt(i)).append(' ');
2767             }
2768             Slog.wtfStack(TAG, "Map doesn't contain offset "
2769                     + firstAbsolutePos
2770                     + " : contains=" + sb.toString());
2771         }
2772         return (T) p;
2773     }
2774 
2775     /**
2776      * Write a generic serializable object in to a Parcel.  It is strongly
2777      * recommended that this method be avoided, since the serialization
2778      * overhead is extremely large, and this approach will be much slower than
2779      * using the other approaches to writing data in to a Parcel.
2780      */
writeSerializable(@ullable Serializable s)2781     public final void writeSerializable(@Nullable Serializable s) {
2782         if (s == null) {
2783             writeString(null);
2784             return;
2785         }
2786         String name = s.getClass().getName();
2787         writeString(name);
2788 
2789         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2790         try {
2791             ObjectOutputStream oos = new ObjectOutputStream(baos);
2792             oos.writeObject(s);
2793             oos.close();
2794 
2795             writeByteArray(baos.toByteArray());
2796         } catch (IOException ioe) {
2797             throw new BadParcelableException("Parcelable encountered "
2798                     + "IOException writing serializable object (name = "
2799                     + name + ")", ioe);
2800         }
2801     }
2802 
2803     /** @hide For debugging purposes */
setStackTraceParceling(boolean enabled)2804     public static void setStackTraceParceling(boolean enabled) {
2805         sParcelExceptionStackTrace = enabled;
2806     }
2807 
2808     /**
2809      * Special function for writing an exception result at the header of
2810      * a parcel, to be used when returning an exception from a transaction.
2811      * Note that this currently only supports a few exception types; any other
2812      * exception will be re-thrown by this function as a RuntimeException
2813      * (to be caught by the system's last-resort exception handling when
2814      * dispatching a transaction).
2815      *
2816      * <p>The supported exception types are:
2817      * <ul>
2818      * <li>{@link BadParcelableException}
2819      * <li>{@link IllegalArgumentException}
2820      * <li>{@link IllegalStateException}
2821      * <li>{@link NullPointerException}
2822      * <li>{@link SecurityException}
2823      * <li>{@link UnsupportedOperationException}
2824      * <li>{@link NetworkOnMainThreadException}
2825      * </ul>
2826      *
2827      * @param e The Exception to be written.
2828      *
2829      * @see #writeNoException
2830      * @see #readException
2831      */
writeException(@onNull Exception e)2832     public final void writeException(@NonNull Exception e) {
2833         AppOpsManager.prefixParcelWithAppOpsIfNeeded(this);
2834 
2835         int code = getExceptionCode(e);
2836         writeInt(code);
2837         StrictMode.clearGatheredViolations();
2838         if (code == 0) {
2839             if (e instanceof RuntimeException) {
2840                 throw (RuntimeException) e;
2841             }
2842             throw new RuntimeException(e);
2843         }
2844         writeString(e.getMessage());
2845         final long timeNow = sParcelExceptionStackTrace ? SystemClock.elapsedRealtime() : 0;
2846         if (sParcelExceptionStackTrace && (timeNow - sLastWriteExceptionStackTrace
2847                 > WRITE_EXCEPTION_STACK_TRACE_THRESHOLD_MS)) {
2848             sLastWriteExceptionStackTrace = timeNow;
2849             writeStackTrace(e);
2850         } else {
2851             writeInt(0);
2852         }
2853         switch (code) {
2854             case EX_SERVICE_SPECIFIC:
2855                 writeInt(((ServiceSpecificException) e).errorCode);
2856                 break;
2857             case EX_PARCELABLE:
2858                 // Write parceled exception prefixed by length
2859                 final int sizePosition = dataPosition();
2860                 writeInt(0);
2861                 writeParcelable((Parcelable) e, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
2862                 final int payloadPosition = dataPosition();
2863                 setDataPosition(sizePosition);
2864                 writeInt(payloadPosition - sizePosition);
2865                 setDataPosition(payloadPosition);
2866                 break;
2867         }
2868     }
2869 
2870     /** @hide */
getExceptionCode(@onNull Throwable e)2871     public static int getExceptionCode(@NonNull Throwable e) {
2872         int code = 0;
2873         if (e instanceof Parcelable
2874                 && (e.getClass().getClassLoader() == Parcelable.class.getClassLoader())) {
2875             // We only send Parcelable exceptions that are in the
2876             // BootClassLoader to ensure that the receiver can unpack them
2877             code = EX_PARCELABLE;
2878         } else if (e instanceof SecurityException) {
2879             code = EX_SECURITY;
2880         } else if (e instanceof BadParcelableException) {
2881             code = EX_BAD_PARCELABLE;
2882         } else if (e instanceof IllegalArgumentException) {
2883             code = EX_ILLEGAL_ARGUMENT;
2884         } else if (e instanceof NullPointerException) {
2885             code = EX_NULL_POINTER;
2886         } else if (e instanceof IllegalStateException) {
2887             code = EX_ILLEGAL_STATE;
2888         } else if (e instanceof NetworkOnMainThreadException) {
2889             code = EX_NETWORK_MAIN_THREAD;
2890         } else if (e instanceof UnsupportedOperationException) {
2891             code = EX_UNSUPPORTED_OPERATION;
2892         } else if (e instanceof ServiceSpecificException) {
2893             code = EX_SERVICE_SPECIFIC;
2894         }
2895         return code;
2896     }
2897 
2898     /** @hide */
writeStackTrace(@onNull Throwable e)2899     public void writeStackTrace(@NonNull Throwable e) {
2900         final int sizePosition = dataPosition();
2901         writeInt(0); // Header size will be filled in later
2902         StackTraceElement[] stackTrace = e.getStackTrace();
2903         final int truncatedSize = Math.min(stackTrace.length, 5);
2904         StringBuilder sb = new StringBuilder();
2905         for (int i = 0; i < truncatedSize; i++) {
2906             sb.append("\tat ").append(stackTrace[i]).append('\n');
2907         }
2908         writeString(sb.toString());
2909         final int payloadPosition = dataPosition();
2910         setDataPosition(sizePosition);
2911         // Write stack trace header size. Used in native side to skip the header
2912         writeInt(payloadPosition - sizePosition);
2913         setDataPosition(payloadPosition);
2914     }
2915 
2916     /**
2917      * Special function for writing information at the front of the Parcel
2918      * indicating that no exception occurred.
2919      *
2920      * @see #writeException
2921      * @see #readException
2922      */
writeNoException()2923     public final void writeNoException() {
2924         AppOpsManager.prefixParcelWithAppOpsIfNeeded(this);
2925 
2926         // Despite the name of this function ("write no exception"),
2927         // it should instead be thought of as "write the RPC response
2928         // header", but because this function name is written out by
2929         // the AIDL compiler, we're not going to rename it.
2930         //
2931         // The response header, in the non-exception case (see also
2932         // writeException above, also called by the AIDL compiler), is
2933         // either a 0 (the default case), or EX_HAS_STRICTMODE_REPLY_HEADER if
2934         // StrictMode has gathered up violations that have occurred
2935         // during a Binder call, in which case we write out the number
2936         // of violations and their details, serialized, before the
2937         // actual RPC respons data.  The receiving end of this is
2938         // readException(), below.
2939         if (StrictMode.hasGatheredViolations()) {
2940             writeInt(EX_HAS_STRICTMODE_REPLY_HEADER);
2941             final int sizePosition = dataPosition();
2942             writeInt(0);  // total size of fat header, to be filled in later
2943             StrictMode.writeGatheredViolationsToParcel(this);
2944             final int payloadPosition = dataPosition();
2945             setDataPosition(sizePosition);
2946             writeInt(payloadPosition - sizePosition);  // header size
2947             setDataPosition(payloadPosition);
2948         } else {
2949             writeInt(0);
2950         }
2951     }
2952 
2953     /**
2954      * Special function for reading an exception result from the header of
2955      * a parcel, to be used after receiving the result of a transaction.  This
2956      * will throw the exception for you if it had been written to the Parcel,
2957      * otherwise return and let you read the normal result data from the Parcel.
2958      *
2959      * @see #writeException
2960      * @see #writeNoException
2961      */
readException()2962     public final void readException() {
2963         int code = readExceptionCode();
2964         if (code != 0) {
2965             String msg = readString();
2966             readException(code, msg);
2967         }
2968     }
2969 
2970     /**
2971      * Parses the header of a Binder call's response Parcel and
2972      * returns the exception code.  Deals with lite or fat headers.
2973      * In the common successful case, this header is generally zero.
2974      * In less common cases, it's a small negative number and will be
2975      * followed by an error string.
2976      *
2977      * This exists purely for android.database.DatabaseUtils and
2978      * insulating it from having to handle fat headers as returned by
2979      * e.g. StrictMode-induced RPC responses.
2980      *
2981      * @hide
2982      */
2983     @UnsupportedAppUsage
2984     @TestApi
readExceptionCode()2985     public final int readExceptionCode() {
2986         int code = readInt();
2987         if (code == EX_HAS_NOTED_APPOPS_REPLY_HEADER) {
2988             AppOpsManager.readAndLogNotedAppops(this);
2989             // Read next header or real exception if there is no more header
2990             code = readInt();
2991         }
2992 
2993         if (code == EX_HAS_STRICTMODE_REPLY_HEADER) {
2994             int headerSize = readInt();
2995             if (headerSize == 0) {
2996                 Log.e(TAG, "Unexpected zero-sized Parcel reply header.");
2997             } else {
2998                 // Currently the only thing in the header is StrictMode stacks,
2999                 // but discussions around event/RPC tracing suggest we might
3000                 // put that here too.  If so, switch on sub-header tags here.
3001                 // But for now, just parse out the StrictMode stuff.
3002                 StrictMode.readAndHandleBinderCallViolations(this);
3003             }
3004             // And fat response headers are currently only used when
3005             // there are no exceptions, so return no error:
3006             return 0;
3007         }
3008         return code;
3009     }
3010 
3011     /**
3012      * Throw an exception with the given message. Not intended for use
3013      * outside the Parcel class.
3014      *
3015      * @param code Used to determine which exception class to throw.
3016      * @param msg The exception message.
3017      */
readException(int code, String msg)3018     public final void readException(int code, String msg) {
3019         String remoteStackTrace = null;
3020         final int remoteStackPayloadSize = readInt();
3021         if (remoteStackPayloadSize > 0) {
3022             remoteStackTrace = readString();
3023         }
3024         Exception e = createException(code, msg);
3025         // Attach remote stack trace if availalble
3026         if (remoteStackTrace != null) {
3027             RemoteException cause = new RemoteException(
3028                     "Remote stack trace:\n" + remoteStackTrace, null, false, false);
3029             ExceptionUtils.appendCause(e, cause);
3030         }
3031         SneakyThrow.sneakyThrow(e);
3032     }
3033 
3034     /**
3035      * Creates an exception with the given message.
3036      *
3037      * @param code Used to determine which exception class to throw.
3038      * @param msg The exception message.
3039      */
createException(int code, String msg)3040     private Exception createException(int code, String msg) {
3041         Exception exception = createExceptionOrNull(code, msg);
3042         return exception != null
3043                 ? exception
3044                 : new RuntimeException("Unknown exception code: " + code + " msg " + msg);
3045     }
3046 
3047     /** @hide */
createExceptionOrNull(int code, String msg)3048     public Exception createExceptionOrNull(int code, String msg) {
3049         switch (code) {
3050             case EX_PARCELABLE:
3051                 if (readInt() > 0) {
3052                     return (Exception) readParcelable(Parcelable.class.getClassLoader(), java.lang.Exception.class);
3053                 } else {
3054                     return new RuntimeException(msg + " [missing Parcelable]");
3055                 }
3056             case EX_SECURITY:
3057                 return new SecurityException(msg);
3058             case EX_BAD_PARCELABLE:
3059                 return new BadParcelableException(msg);
3060             case EX_ILLEGAL_ARGUMENT:
3061                 return new IllegalArgumentException(msg);
3062             case EX_NULL_POINTER:
3063                 return new NullPointerException(msg);
3064             case EX_ILLEGAL_STATE:
3065                 return new IllegalStateException(msg);
3066             case EX_NETWORK_MAIN_THREAD:
3067                 return new NetworkOnMainThreadException();
3068             case EX_UNSUPPORTED_OPERATION:
3069                 return new UnsupportedOperationException(msg);
3070             case EX_SERVICE_SPECIFIC:
3071                 return new ServiceSpecificException(readInt(), msg);
3072             default:
3073                 return null;
3074         }
3075     }
3076 
3077     /**
3078      * Read an integer value from the parcel at the current dataPosition().
3079      */
readInt()3080     public final int readInt() {
3081         return nativeReadInt(mNativePtr);
3082     }
3083 
3084     /**
3085      * Read a long integer value from the parcel at the current dataPosition().
3086      */
readLong()3087     public final long readLong() {
3088         return nativeReadLong(mNativePtr);
3089     }
3090 
3091     /**
3092      * Read a floating point value from the parcel at the current
3093      * dataPosition().
3094      */
readFloat()3095     public final float readFloat() {
3096         return nativeReadFloat(mNativePtr);
3097     }
3098 
3099     /**
3100      * Read a double precision floating point value from the parcel at the
3101      * current dataPosition().
3102      */
readDouble()3103     public final double readDouble() {
3104         return nativeReadDouble(mNativePtr);
3105     }
3106 
3107     /**
3108      * Read a string value from the parcel at the current dataPosition().
3109      */
3110     @Nullable
readString()3111     public final String readString() {
3112         return readString16();
3113     }
3114 
3115     /** {@hide} */
readString8()3116     public final @Nullable String readString8() {
3117         return mReadWriteHelper.readString8(this);
3118     }
3119 
3120     /** {@hide} */
readString16()3121     public final @Nullable String readString16() {
3122         return mReadWriteHelper.readString16(this);
3123     }
3124 
3125     /**
3126      * Read a string without going though a {@link ReadWriteHelper}.  Subclasses of
3127      * {@link ReadWriteHelper} must use this method instead of {@link #readString} to avoid
3128      * infinity recursive calls.
3129      *
3130      * @hide
3131      */
readStringNoHelper()3132     public @Nullable String readStringNoHelper() {
3133         return readString16NoHelper();
3134     }
3135 
3136     /** {@hide} */
readString8NoHelper()3137     public @Nullable String readString8NoHelper() {
3138         return nativeReadString8(mNativePtr);
3139     }
3140 
3141     /** {@hide} */
readString16NoHelper()3142     public @Nullable String readString16NoHelper() {
3143         return nativeReadString16(mNativePtr);
3144     }
3145 
3146     /**
3147      * Read a boolean value from the parcel at the current dataPosition().
3148      */
readBoolean()3149     public final boolean readBoolean() {
3150         return readInt() != 0;
3151     }
3152 
3153     /**
3154      * Read a CharSequence value from the parcel at the current dataPosition().
3155      * @hide
3156      */
3157     @UnsupportedAppUsage
3158     @Nullable
readCharSequence()3159     public final CharSequence readCharSequence() {
3160         return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
3161     }
3162 
3163     /**
3164      * Read an object from the parcel at the current dataPosition().
3165      */
readStrongBinder()3166     public final IBinder readStrongBinder() {
3167         final IBinder result = nativeReadStrongBinder(mNativePtr);
3168 
3169         // If it's a reply from a method with @PropagateAllowBlocking, then inherit allow-blocking
3170         // from the object that returned it.
3171         if (result != null && hasFlags(
3172                 FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT | FLAG_PROPAGATE_ALLOW_BLOCKING)) {
3173             Binder.allowBlocking(result);
3174         }
3175         return result;
3176     }
3177 
3178     /**
3179      * Read a FileDescriptor from the parcel at the current dataPosition().
3180      */
readFileDescriptor()3181     public final ParcelFileDescriptor readFileDescriptor() {
3182         FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
3183         return fd != null ? new ParcelFileDescriptor(fd) : null;
3184     }
3185 
3186     /** {@hide} */
3187     @UnsupportedAppUsage
readRawFileDescriptor()3188     public final FileDescriptor readRawFileDescriptor() {
3189         return nativeReadFileDescriptor(mNativePtr);
3190     }
3191 
3192     /**
3193      * {@hide}
3194      * Read and return a new array of FileDescriptors from the parcel.
3195      * @return the FileDescriptor array, or null if the array is null.
3196      **/
3197     @Nullable
createRawFileDescriptorArray()3198     public final FileDescriptor[] createRawFileDescriptorArray() {
3199         int N = readInt();
3200         if (N < 0) {
3201             return null;
3202         }
3203         FileDescriptor[] f = new FileDescriptor[N];
3204         for (int i = 0; i < N; i++) {
3205             f[i] = readRawFileDescriptor();
3206         }
3207         return f;
3208     }
3209 
3210     /**
3211      * {@hide}
3212      * Read an array of FileDescriptors from a parcel.
3213      * The passed array must be exactly the length of the array in the parcel.
3214      * @return the FileDescriptor array, or null if the array is null.
3215      **/
readRawFileDescriptorArray(FileDescriptor[] val)3216     public final void readRawFileDescriptorArray(FileDescriptor[] val) {
3217         int N = readInt();
3218         if (N == val.length) {
3219             for (int i=0; i<N; i++) {
3220                 val[i] = readRawFileDescriptor();
3221             }
3222         } else {
3223             throw new RuntimeException("bad array lengths");
3224         }
3225     }
3226 
3227     /**
3228      * Read a byte value from the parcel at the current dataPosition().
3229      */
readByte()3230     public final byte readByte() {
3231         return (byte)(readInt() & 0xff);
3232     }
3233 
3234     /**
3235      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
3236      * been written with {@link #writeBundle}.  Read into an existing Map object
3237      * from the parcel at the current dataPosition().
3238      *
3239      * @deprecated Consider using {@link #readBundle(ClassLoader)} as stated above, in case this
3240      *      method is still preferred use the type-safer version {@link #readMap(Map, ClassLoader,
3241      *      Class, Class)} starting from Android {@link Build.VERSION_CODES#TIRAMISU}.
3242      */
3243     @Deprecated
readMap(@onNull Map outVal, @Nullable ClassLoader loader)3244     public final void readMap(@NonNull Map outVal, @Nullable ClassLoader loader) {
3245         readMapInternal(outVal, loader, /* clazzKey */ null, /* clazzValue */ null);
3246     }
3247 
3248     /**
3249      * Same as {@link #readMap(Map, ClassLoader)} but accepts {@code clazzKey} and
3250      * {@code clazzValue} parameter as the types required for each key and value pair.
3251      *
3252      * @throws BadParcelableException If the item to be deserialized is not an instance of that
3253      * class or any of its children class
3254      */
readMap(@onNull Map<? super K, ? super V> outVal, @Nullable ClassLoader loader, @NonNull Class<K> clazzKey, @NonNull Class<V> clazzValue)3255     public <K, V> void readMap(@NonNull Map<? super K, ? super V> outVal,
3256             @Nullable ClassLoader loader, @NonNull Class<K> clazzKey,
3257             @NonNull Class<V> clazzValue) {
3258         Objects.requireNonNull(clazzKey);
3259         Objects.requireNonNull(clazzValue);
3260         readMapInternal(outVal, loader, clazzKey, clazzValue);
3261     }
3262 
3263     /**
3264      * Read into an existing List object from the parcel at the current
3265      * dataPosition(), using the given class loader to load any enclosed
3266      * Parcelables.  If it is null, the default class loader is used.
3267      *
3268      * @deprecated Use the type-safer version {@link #readList(List, ClassLoader, Class)} starting
3269      *      from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to
3270      *      use {@link #readTypedList(List, Parcelable.Creator)} if possible (eg. if the items'
3271      *      class is final) since this is also more performant. Note that changing to the latter
3272      *      also requires changing the writes.
3273      */
3274     @Deprecated
readList(@onNull List outVal, @Nullable ClassLoader loader)3275     public final void readList(@NonNull List outVal, @Nullable ClassLoader loader) {
3276         int N = readInt();
3277         readListInternal(outVal, N, loader, /* clazz */ null);
3278     }
3279 
3280     /**
3281      * Same as {@link #readList(List, ClassLoader)} but accepts {@code clazz} parameter as
3282      * the type required for each item.
3283      *
3284      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
3285      * the class that implements {@link Parcelable} has to be the immediately
3286      * enclosing class of the runtime type of its CREATOR field (that is,
3287      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
3288      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
3289      * CREATOR, use the deprecated {@link #readList(List, ClassLoader)} instead.
3290      *
3291      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
3292      * is not an instance of that class or any of its children classes or there was an error
3293      * trying to instantiate an element.
3294      */
readList(@onNull List<? super T> outVal, @Nullable ClassLoader loader, @NonNull Class<T> clazz)3295     public <T> void readList(@NonNull List<? super T> outVal,
3296             @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
3297         Objects.requireNonNull(clazz);
3298         int n = readInt();
3299         readListInternal(outVal, n, loader, clazz);
3300     }
3301 
3302     /**
3303      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
3304      * been written with {@link #writeBundle}.  Read and return a new HashMap
3305      * object from the parcel at the current dataPosition(), using the given
3306      * class loader to load any enclosed Parcelables.  Returns null if
3307      * the previously written map object was null.
3308      *
3309      * @deprecated Consider using {@link #readBundle(ClassLoader)} as stated above, in case this
3310      *      method is still preferred use the type-safer version {@link #readHashMap(ClassLoader,
3311      *      Class, Class)} starting from Android {@link Build.VERSION_CODES#TIRAMISU}.
3312      */
3313     @Deprecated
3314     @Nullable
readHashMap(@ullable ClassLoader loader)3315     public HashMap readHashMap(@Nullable ClassLoader loader) {
3316         return readHashMapInternal(loader, /* clazzKey */ null, /* clazzValue */ null);
3317     }
3318 
3319     /**
3320      * Same as {@link #readHashMap(ClassLoader)} but accepts {@code clazzKey} and
3321      * {@code clazzValue} parameter as the types required for each key and value pair.
3322      *
3323      * @throws BadParcelableException if the item to be deserialized is not an instance of that
3324      * class or any of its children class
3325      */
3326     @SuppressLint({"ConcreteCollection", "NullableCollection"})
3327     @Nullable
readHashMap(@ullable ClassLoader loader, @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue)3328     public <K, V> HashMap<K, V> readHashMap(@Nullable ClassLoader loader,
3329             @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) {
3330         Objects.requireNonNull(clazzKey);
3331         Objects.requireNonNull(clazzValue);
3332         return readHashMapInternal(loader, clazzKey, clazzValue);
3333     }
3334 
3335     /**
3336      * Read and return a new Bundle object from the parcel at the current
3337      * dataPosition().  Returns null if the previously written Bundle object was
3338      * null.
3339      */
3340     @Nullable
readBundle()3341     public final Bundle readBundle() {
3342         return readBundle(null);
3343     }
3344 
3345     /**
3346      * Read and return a new Bundle object from the parcel at the current
3347      * dataPosition(), using the given class loader to initialize the class
3348      * loader of the Bundle for later retrieval of Parcelable objects.
3349      * Returns null if the previously written Bundle object was null.
3350      */
3351     @Nullable
readBundle(@ullable ClassLoader loader)3352     public final Bundle readBundle(@Nullable ClassLoader loader) {
3353         int length = readInt();
3354         if (length < 0) {
3355             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
3356             return null;
3357         }
3358 
3359         final Bundle bundle = new Bundle(this, length);
3360         if (loader != null) {
3361             bundle.setClassLoader(loader);
3362         }
3363         return bundle;
3364     }
3365 
3366     /**
3367      * Read and return a new Bundle object from the parcel at the current
3368      * dataPosition().  Returns null if the previously written Bundle object was
3369      * null.
3370      */
3371     @Nullable
readPersistableBundle()3372     public final PersistableBundle readPersistableBundle() {
3373         return readPersistableBundle(null);
3374     }
3375 
3376     /**
3377      * Read and return a new Bundle object from the parcel at the current
3378      * dataPosition(), using the given class loader to initialize the class
3379      * loader of the Bundle for later retrieval of Parcelable objects.
3380      * Returns null if the previously written Bundle object was null.
3381      */
3382     @Nullable
readPersistableBundle(@ullable ClassLoader loader)3383     public final PersistableBundle readPersistableBundle(@Nullable ClassLoader loader) {
3384         int length = readInt();
3385         if (length < 0) {
3386             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
3387             return null;
3388         }
3389 
3390         final PersistableBundle bundle = new PersistableBundle(this, length);
3391         if (loader != null) {
3392             bundle.setClassLoader(loader);
3393         }
3394         return bundle;
3395     }
3396 
3397     /**
3398      * Read a Size from the parcel at the current dataPosition().
3399      */
3400     @NonNull
readSize()3401     public final Size readSize() {
3402         final int width = readInt();
3403         final int height = readInt();
3404         return new Size(width, height);
3405     }
3406 
3407     /**
3408      * Read a SizeF from the parcel at the current dataPosition().
3409      */
3410     @NonNull
readSizeF()3411     public final SizeF readSizeF() {
3412         final float width = readFloat();
3413         final float height = readFloat();
3414         return new SizeF(width, height);
3415     }
3416 
3417     /**
3418      * Read and return a byte[] object from the parcel.
3419      */
3420     @Nullable
createByteArray()3421     public final byte[] createByteArray() {
3422         return nativeCreateByteArray(mNativePtr);
3423     }
3424 
3425     /**
3426      * Read a byte[] object from the parcel and copy it into the
3427      * given byte array.
3428      */
readByteArray(@onNull byte[] val)3429     public final void readByteArray(@NonNull byte[] val) {
3430         boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0);
3431         if (!valid) {
3432             throw new RuntimeException("bad array lengths");
3433         }
3434     }
3435 
3436     /**
3437      * Read a blob of data from the parcel and return it as a byte array.
3438      * @see #writeBlob(byte[], int, int)
3439      */
3440     @Nullable
readBlob()3441     public final byte[] readBlob() {
3442         return nativeReadBlob(mNativePtr);
3443     }
3444 
3445     /**
3446      * Read and return a String[] object from the parcel.
3447      * {@hide}
3448      */
3449     @UnsupportedAppUsage
3450     @Nullable
readStringArray()3451     public final String[] readStringArray() {
3452         return createString16Array();
3453     }
3454 
3455     /**
3456      * Read and return a CharSequence[] object from the parcel.
3457      * {@hide}
3458      */
3459     @Nullable
readCharSequenceArray()3460     public final CharSequence[] readCharSequenceArray() {
3461         CharSequence[] array = null;
3462 
3463         int length = readInt();
3464         if (length >= 0)
3465         {
3466             array = new CharSequence[length];
3467 
3468             for (int i = 0 ; i < length ; i++)
3469             {
3470                 array[i] = readCharSequence();
3471             }
3472         }
3473 
3474         return array;
3475     }
3476 
3477     /**
3478      * Read and return an ArrayList&lt;CharSequence&gt; object from the parcel.
3479      * {@hide}
3480      */
3481     @Nullable
readCharSequenceList()3482     public final ArrayList<CharSequence> readCharSequenceList() {
3483         ArrayList<CharSequence> array = null;
3484 
3485         int length = readInt();
3486         if (length >= 0) {
3487             array = new ArrayList<CharSequence>(length);
3488 
3489             for (int i = 0 ; i < length ; i++) {
3490                 array.add(readCharSequence());
3491             }
3492         }
3493 
3494         return array;
3495     }
3496 
3497     /**
3498      * Read and return a new ArrayList object from the parcel at the current
3499      * dataPosition().  Returns null if the previously written list object was
3500      * null.  The given class loader will be used to load any enclosed
3501      * Parcelables.
3502      *
3503      * @deprecated Use the type-safer version {@link #readArrayList(ClassLoader, Class)} starting
3504      *      from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to
3505      *      use {@link #createTypedArrayList(Parcelable.Creator)} if possible (eg. if the items'
3506      *      class is final) since this is also more performant. Note that changing to the latter
3507      *      also requires changing the writes.
3508      */
3509     @Deprecated
3510     @Nullable
readArrayList(@ullable ClassLoader loader)3511     public ArrayList readArrayList(@Nullable ClassLoader loader) {
3512         return readArrayListInternal(loader, /* clazz */ null);
3513     }
3514 
3515     /**
3516      * Same as {@link #readArrayList(ClassLoader)} but accepts {@code clazz} parameter as
3517      * the type required for each item.
3518      *
3519      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
3520      * the class that implements {@link Parcelable} has to be the immediately
3521      * enclosing class of the runtime type of its CREATOR field (that is,
3522      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
3523      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
3524      * CREATOR, use the deprecated {@link #readArrayList(ClassLoader)} instead.
3525      *
3526      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
3527      * is not an instance of that class or any of its children classes or there was an error
3528      * trying to instantiate an element.
3529      */
3530     @SuppressLint({"ConcreteCollection", "NullableCollection"})
3531     @Nullable
readArrayList(@ullable ClassLoader loader, @NonNull Class<? extends T> clazz)3532     public <T> ArrayList<T> readArrayList(@Nullable ClassLoader loader,
3533             @NonNull Class<? extends T> clazz) {
3534         Objects.requireNonNull(clazz);
3535         return readArrayListInternal(loader, clazz);
3536     }
3537 
3538     /**
3539      * Read and return a new Object array from the parcel at the current
3540      * dataPosition().  Returns null if the previously written array was
3541      * null.  The given class loader will be used to load any enclosed
3542      * Parcelables.
3543      *
3544      * @deprecated Use the type-safer version {@link #readArray(ClassLoader, Class)} starting from
3545      *      Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to use
3546      *      {@link #createTypedArray(Parcelable.Creator)} if possible (eg. if the items' class is
3547      *      final) since this is also more performant. Note that changing to the latter also
3548      *      requires changing the writes.
3549      */
3550     @Deprecated
3551     @Nullable
readArray(@ullable ClassLoader loader)3552     public Object[] readArray(@Nullable ClassLoader loader) {
3553         return readArrayInternal(loader, /* clazz */ null);
3554     }
3555 
3556     /**
3557      * Same as {@link #readArray(ClassLoader)} but accepts {@code clazz} parameter as
3558      * the type required for each item.
3559      *
3560      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
3561      * the class that implements {@link Parcelable} has to be the immediately
3562      * enclosing class of the runtime type of its CREATOR field (that is,
3563      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
3564      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
3565      * CREATOR, use the deprecated {@link #readArray(ClassLoader)} instead.
3566      *
3567      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
3568      * is not an instance of that class or any of its children classes or there was an error
3569      * trying to instantiate an element.
3570      */
3571     @SuppressLint({"ArrayReturn", "NullableCollection"})
3572     @Nullable
readArray(@ullable ClassLoader loader, @NonNull Class<T> clazz)3573     public <T> T[] readArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
3574         Objects.requireNonNull(clazz);
3575         return readArrayInternal(loader, clazz);
3576     }
3577 
3578     /**
3579      * Read and return a new SparseArray object from the parcel at the current
3580      * dataPosition().  Returns null if the previously written list object was
3581      * null.  The given class loader will be used to load any enclosed
3582      * Parcelables.
3583      *
3584      * @deprecated Use the type-safer version {@link #readSparseArray(ClassLoader, Class)} starting
3585      *      from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to
3586      *      use {@link #createTypedSparseArray(Parcelable.Creator)} if possible (eg. if the items'
3587      *      class is final) since this is also more performant. Note that changing to the latter
3588      *      also requires changing the writes.
3589      */
3590     @Deprecated
3591     @Nullable
readSparseArray(@ullable ClassLoader loader)3592     public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader) {
3593         return readSparseArrayInternal(loader, /* clazz */ null);
3594     }
3595 
3596     /**
3597      * Same as {@link #readSparseArray(ClassLoader)} but accepts {@code clazz} parameter as
3598      * the type required for each item.
3599      *
3600      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
3601      * the class that implements {@link Parcelable} has to be the immediately
3602      * enclosing class of the runtime type of its CREATOR field (that is,
3603      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
3604      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
3605      * CREATOR, use the deprecated {@link #readSparseArray(ClassLoader)} instead.
3606      *
3607      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
3608      * is not an instance of that class or any of its children classes or there was an error
3609      * trying to instantiate an element.
3610      */
3611     @Nullable
readSparseArray(@ullable ClassLoader loader, @NonNull Class<? extends T> clazz)3612     public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader,
3613             @NonNull Class<? extends T> clazz) {
3614         Objects.requireNonNull(clazz);
3615         return readSparseArrayInternal(loader, clazz);
3616     }
3617 
3618     /**
3619      * Read and return a new SparseBooleanArray object from the parcel at the current
3620      * dataPosition().  Returns null if the previously written list object was
3621      * null.
3622      */
3623     @Nullable
readSparseBooleanArray()3624     public final SparseBooleanArray readSparseBooleanArray() {
3625         int N = readInt();
3626         if (N < 0) {
3627             return null;
3628         }
3629         SparseBooleanArray sa = new SparseBooleanArray(N);
3630         readSparseBooleanArrayInternal(sa, N);
3631         return sa;
3632     }
3633 
3634     /**
3635      * Read and return a new SparseIntArray object from the parcel at the current
3636      * dataPosition(). Returns null if the previously written array object was null.
3637      * @hide
3638      */
3639     @Nullable
readSparseIntArray()3640     public final SparseIntArray readSparseIntArray() {
3641         int N = readInt();
3642         if (N < 0) {
3643             return null;
3644         }
3645         SparseIntArray sa = new SparseIntArray(N);
3646         readSparseIntArrayInternal(sa, N);
3647         return sa;
3648     }
3649 
3650     /**
3651      * Read and return a new ArrayList containing a particular object type from
3652      * the parcel that was written with {@link #writeTypedList} at the
3653      * current dataPosition().  Returns null if the
3654      * previously written list object was null.  The list <em>must</em> have
3655      * previously been written via {@link #writeTypedList} with the same object
3656      * type.
3657      *
3658      * @return A newly created ArrayList containing objects with the same data
3659      *         as those that were previously written.
3660      *
3661      * @see #writeTypedList
3662      */
3663     @Nullable
createTypedArrayList(@onNull Parcelable.Creator<T> c)3664     public final <T> ArrayList<T> createTypedArrayList(@NonNull Parcelable.Creator<T> c) {
3665         int N = readInt();
3666         if (N < 0) {
3667             return null;
3668         }
3669         ArrayList<T> l = new ArrayList<T>(N);
3670         while (N > 0) {
3671             l.add(readTypedObject(c));
3672             N--;
3673         }
3674         return l;
3675     }
3676 
3677     /**
3678      * Read into the given List items containing a particular object type
3679      * that were written with {@link #writeTypedList} at the
3680      * current dataPosition().  The list <em>must</em> have
3681      * previously been written via {@link #writeTypedList} with the same object
3682      * type.
3683      *
3684      * @see #writeTypedList
3685      */
readTypedList(@onNull List<T> list, @NonNull Parcelable.Creator<T> c)3686     public final <T> void readTypedList(@NonNull List<T> list, @NonNull Parcelable.Creator<T> c) {
3687         int M = list.size();
3688         int N = readInt();
3689         int i = 0;
3690         for (; i < M && i < N; i++) {
3691             list.set(i, readTypedObject(c));
3692         }
3693         for (; i<N; i++) {
3694             list.add(readTypedObject(c));
3695         }
3696         for (; i<M; i++) {
3697             list.remove(N);
3698         }
3699     }
3700 
3701     /**
3702      * Read into a new {@link SparseArray} items containing a particular object type
3703      * that were written with {@link #writeTypedSparseArray(SparseArray, int)} at the
3704      * current dataPosition().  The list <em>must</em> have previously been written
3705      * via {@link #writeTypedSparseArray(SparseArray, int)} with the same object type.
3706      *
3707      * @param creator The creator to use when for instantiation.
3708      *
3709      * @return A newly created {@link SparseArray} containing objects with the same data
3710      *         as those that were previously written.
3711      *
3712      * @see #writeTypedSparseArray(SparseArray, int)
3713      */
createTypedSparseArray( @onNull Parcelable.Creator<T> creator)3714     public final @Nullable <T extends Parcelable> SparseArray<T> createTypedSparseArray(
3715             @NonNull Parcelable.Creator<T> creator) {
3716         final int count = readInt();
3717         if (count < 0) {
3718             return null;
3719         }
3720         final SparseArray<T> array = new SparseArray<>(count);
3721         for (int i = 0; i < count; i++) {
3722             final int index = readInt();
3723             final T value = readTypedObject(creator);
3724             array.append(index, value);
3725         }
3726         return array;
3727     }
3728 
3729     /**
3730      * Read into a new {@link ArrayMap} with string keys items containing a particular
3731      * object type that were written with {@link #writeTypedArrayMap(ArrayMap, int)} at the
3732      * current dataPosition().  The list <em>must</em> have previously been written
3733      * via {@link #writeTypedArrayMap(ArrayMap, int)} with the same object type.
3734      *
3735      * @param creator The creator to use when for instantiation.
3736      *
3737      * @return A newly created {@link ArrayMap} containing objects with the same data
3738      *         as those that were previously written.
3739      *
3740      * @see #writeTypedArrayMap(ArrayMap, int)
3741      */
createTypedArrayMap( @onNull Parcelable.Creator<T> creator)3742     public final @Nullable <T extends Parcelable> ArrayMap<String, T> createTypedArrayMap(
3743             @NonNull Parcelable.Creator<T> creator) {
3744         final int count = readInt();
3745         if (count < 0) {
3746             return null;
3747         }
3748         final ArrayMap<String, T> map = new ArrayMap<>(count);
3749         for (int i = 0; i < count; i++) {
3750             final String key = readString();
3751             final T value = readTypedObject(creator);
3752             map.append(key, value);
3753         }
3754         return map;
3755     }
3756 
3757     /**
3758      * Read and return a new ArrayList containing String objects from
3759      * the parcel that was written with {@link #writeStringList} at the
3760      * current dataPosition().  Returns null if the
3761      * previously written list object was null.
3762      *
3763      * @return A newly created ArrayList containing strings with the same data
3764      *         as those that were previously written.
3765      *
3766      * @see #writeStringList
3767      */
3768     @Nullable
createStringArrayList()3769     public final ArrayList<String> createStringArrayList() {
3770         int N = readInt();
3771         if (N < 0) {
3772             return null;
3773         }
3774         ArrayList<String> l = new ArrayList<String>(N);
3775         while (N > 0) {
3776             l.add(readString());
3777             N--;
3778         }
3779         return l;
3780     }
3781 
3782     /**
3783      * Read and return a new ArrayList containing IBinder objects from
3784      * the parcel that was written with {@link #writeBinderList} at the
3785      * current dataPosition().  Returns null if the
3786      * previously written list object was null.
3787      *
3788      * @return A newly created ArrayList containing strings with the same data
3789      *         as those that were previously written.
3790      *
3791      * @see #writeBinderList
3792      */
3793     @Nullable
createBinderArrayList()3794     public final ArrayList<IBinder> createBinderArrayList() {
3795         int N = readInt();
3796         if (N < 0) {
3797             return null;
3798         }
3799         ArrayList<IBinder> l = new ArrayList<IBinder>(N);
3800         while (N > 0) {
3801             l.add(readStrongBinder());
3802             N--;
3803         }
3804         return l;
3805     }
3806 
3807     /**
3808      * Read and return a new ArrayList containing T (IInterface) objects from
3809      * the parcel that was written with {@link #writeInterfaceList} at the
3810      * current dataPosition().  Returns null if the
3811      * previously written list object was null.
3812      *
3813      * @return A newly created ArrayList containing T (IInterface)
3814      *
3815      * @see #writeInterfaceList
3816      */
3817     @SuppressLint({"ConcreteCollection", "NullableCollection"})
3818     @Nullable
createInterfaceArrayList( @onNull Function<IBinder, T> asInterface)3819     public final <T extends IInterface> ArrayList<T> createInterfaceArrayList(
3820             @NonNull Function<IBinder, T> asInterface) {
3821         int N = readInt();
3822         if (N < 0) {
3823             return null;
3824         }
3825         ArrayList<T> l = new ArrayList<T>(N);
3826         while (N > 0) {
3827             l.add(asInterface.apply(readStrongBinder()));
3828             N--;
3829         }
3830         return l;
3831     }
3832 
3833     /**
3834      * Read into the given List items String objects that were written with
3835      * {@link #writeStringList} at the current dataPosition().
3836      *
3837      * @see #writeStringList
3838      */
readStringList(@onNull List<String> list)3839     public final void readStringList(@NonNull List<String> list) {
3840         int M = list.size();
3841         int N = readInt();
3842         int i = 0;
3843         for (; i < M && i < N; i++) {
3844             list.set(i, readString());
3845         }
3846         for (; i<N; i++) {
3847             list.add(readString());
3848         }
3849         for (; i<M; i++) {
3850             list.remove(N);
3851         }
3852     }
3853 
3854     /**
3855      * Read into the given List items IBinder objects that were written with
3856      * {@link #writeBinderList} at the current dataPosition().
3857      *
3858      * @see #writeBinderList
3859      */
readBinderList(@onNull List<IBinder> list)3860     public final void readBinderList(@NonNull List<IBinder> list) {
3861         int M = list.size();
3862         int N = readInt();
3863         int i = 0;
3864         for (; i < M && i < N; i++) {
3865             list.set(i, readStrongBinder());
3866         }
3867         for (; i<N; i++) {
3868             list.add(readStrongBinder());
3869         }
3870         for (; i<M; i++) {
3871             list.remove(N);
3872         }
3873     }
3874 
3875     /**
3876      * Read into the given List items IInterface objects that were written with
3877      * {@link #writeInterfaceList} at the current dataPosition().
3878      *
3879      * @see #writeInterfaceList
3880      */
readInterfaceList(@onNull List<T> list, @NonNull Function<IBinder, T> asInterface)3881     public final <T extends IInterface> void readInterfaceList(@NonNull List<T> list,
3882             @NonNull Function<IBinder, T> asInterface) {
3883         int M = list.size();
3884         int N = readInt();
3885         int i = 0;
3886         for (; i < M && i < N; i++) {
3887             list.set(i, asInterface.apply(readStrongBinder()));
3888         }
3889         for (; i<N; i++) {
3890             list.add(asInterface.apply(readStrongBinder()));
3891         }
3892         for (; i<M; i++) {
3893             list.remove(N);
3894         }
3895     }
3896 
3897     /**
3898      * Read the list of {@code Parcelable} objects at the current data position into the
3899      * given {@code list}. The contents of the {@code list} are replaced. If the serialized
3900      * list was {@code null}, {@code list} is cleared.
3901      *
3902      * @see #writeParcelableList(List, int)
3903      *
3904      * @deprecated Use the type-safer version {@link #readParcelableList(List, ClassLoader, Class)}
3905      *      starting from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the
3906      *      format to use {@link #readTypedList(List, Parcelable.Creator)} if possible (eg. if the
3907      *      items' class is final) since this is also more performant. Note that changing to the
3908      *      latter also requires changing the writes.
3909      */
3910     @Deprecated
3911     @NonNull
readParcelableList(@onNull List<T> list, @Nullable ClassLoader cl)3912     public final <T extends Parcelable> List<T> readParcelableList(@NonNull List<T> list,
3913             @Nullable ClassLoader cl) {
3914         return readParcelableListInternal(list, cl, /*clazz*/ null);
3915     }
3916 
3917     /**
3918      * Same as {@link #readParcelableList(List, ClassLoader)} but accepts {@code clazz} parameter as
3919      * the type required for each item.
3920      *
3921      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
3922      * the class that implements {@link Parcelable} has to be the immediately
3923      * enclosing class of the runtime type of its CREATOR field (that is,
3924      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
3925      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
3926      * CREATOR, use the deprecated {@link #readParcelableList(List, ClassLoader)} instead.
3927      *
3928      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
3929      * is not an instance of that class or any of its children classes or there was an error
3930      * trying to instantiate an element.
3931      */
3932     @NonNull
readParcelableList(@onNull List<T> list, @Nullable ClassLoader cl, @NonNull Class<? extends T> clazz)3933     public <T> List<T> readParcelableList(@NonNull List<T> list,
3934             @Nullable ClassLoader cl, @NonNull Class<? extends T> clazz) {
3935         Objects.requireNonNull(list);
3936         Objects.requireNonNull(clazz);
3937         return readParcelableListInternal(list, cl, clazz);
3938     }
3939 
3940     /**
3941      * @param clazz The type of the object expected or {@code null} for performing no checks.
3942      */
3943     @NonNull
readParcelableListInternal(@onNull List<T> list, @Nullable ClassLoader cl, @Nullable Class<? extends T> clazz)3944     private <T> List<T> readParcelableListInternal(@NonNull List<T> list,
3945             @Nullable ClassLoader cl, @Nullable Class<? extends T> clazz) {
3946         final int n = readInt();
3947         if (n == -1) {
3948             list.clear();
3949             return list;
3950         }
3951 
3952         final int m = list.size();
3953         int i = 0;
3954         for (; i < m && i < n; i++) {
3955             list.set(i, (T) readParcelableInternal(cl, clazz));
3956         }
3957         for (; i < n; i++) {
3958             list.add((T) readParcelableInternal(cl, clazz));
3959         }
3960         for (; i < m; i++) {
3961             list.remove(n);
3962         }
3963         return list;
3964     }
3965 
3966     /**
3967      * Read and return a new array containing a particular object type from
3968      * the parcel at the current dataPosition().  Returns null if the
3969      * previously written array was null.  The array <em>must</em> have
3970      * previously been written via {@link #writeTypedArray} with the same
3971      * object type.
3972      *
3973      * @return A newly created array containing objects with the same data
3974      *         as those that were previously written.
3975      *
3976      * @see #writeTypedArray
3977      */
3978     @Nullable
createTypedArray(@onNull Parcelable.Creator<T> c)3979     public final <T> T[] createTypedArray(@NonNull Parcelable.Creator<T> c) {
3980         int N = readInt();
3981         if (N < 0) {
3982             return null;
3983         }
3984         T[] l = c.newArray(N);
3985         for (int i=0; i<N; i++) {
3986             l[i] = readTypedObject(c);
3987         }
3988         return l;
3989     }
3990 
readTypedArray(@onNull T[] val, @NonNull Parcelable.Creator<T> c)3991     public final <T> void readTypedArray(@NonNull T[] val, @NonNull Parcelable.Creator<T> c) {
3992         int N = readInt();
3993         if (N == val.length) {
3994             for (int i=0; i<N; i++) {
3995                 val[i] = readTypedObject(c);
3996             }
3997         } else {
3998             throw new RuntimeException("bad array lengths");
3999         }
4000     }
4001 
4002     /**
4003      * @deprecated
4004      * @hide
4005      */
4006     @Deprecated
readTypedArray(Parcelable.Creator<T> c)4007     public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
4008         return createTypedArray(c);
4009     }
4010 
4011     /**
4012      * Read and return a typed Parcelable object from a parcel.
4013      * Returns null if the previous written object was null.
4014      * The object <em>must</em> have previous been written via
4015      * {@link #writeTypedObject} with the same object type.
4016      *
4017      * @return A newly created object of the type that was previously
4018      *         written.
4019      *
4020      * @see #writeTypedObject
4021      */
4022     @Nullable
readTypedObject(@onNull Parcelable.Creator<T> c)4023     public final <T> T readTypedObject(@NonNull Parcelable.Creator<T> c) {
4024         if (readInt() != 0) {
4025             return c.createFromParcel(this);
4026         } else {
4027             return null;
4028         }
4029     }
4030 
4031     /**
4032      * Read a new multi-dimensional array from a parcel.  If you want to read Parcelable or
4033      * IInterface values, use {@link #readFixedArray(Object, Parcelable.Creator)} or
4034      * {@link #readFixedArray(Object, Function)}.
4035      * @param val the destination array to hold the read values.
4036      *
4037      * @see #writeTypedArray
4038      * @see #readBooleanArray
4039      * @see #readByteArray
4040      * @see #readCharArray
4041      * @see #readIntArray
4042      * @see #readLongArray
4043      * @see #readFloatArray
4044      * @see #readDoubleArray
4045      * @see #readBinderArray
4046      * @see #readInterfaceArray
4047      * @see #readTypedArray
4048      */
readFixedArray(@onNull T val)4049     public <T> void readFixedArray(@NonNull T val) {
4050         Class<?> componentType = val.getClass().getComponentType();
4051         if (componentType == boolean.class) {
4052             readBooleanArray((boolean[]) val);
4053         } else if (componentType == byte.class) {
4054             readByteArray((byte[]) val);
4055         } else if (componentType == char.class) {
4056             readCharArray((char[]) val);
4057         } else if (componentType == int.class) {
4058             readIntArray((int[]) val);
4059         } else if (componentType == long.class) {
4060             readLongArray((long[]) val);
4061         } else if (componentType == float.class) {
4062             readFloatArray((float[]) val);
4063         } else if (componentType == double.class) {
4064             readDoubleArray((double[]) val);
4065         } else if (componentType == IBinder.class) {
4066             readBinderArray((IBinder[]) val);
4067         } else if (componentType.isArray()) {
4068             int length = readInt();
4069             if (length != Array.getLength(val)) {
4070                 throw new BadParcelableException("Bad length: expected " + Array.getLength(val)
4071                     + ", but got " + length);
4072             }
4073             for (int i = 0; i < length; i++) {
4074                 readFixedArray(Array.get(val, i));
4075             }
4076         } else {
4077             throw new BadParcelableException("Unknown type for fixed-size array: " + componentType);
4078         }
4079     }
4080 
4081     /**
4082      * Read a new multi-dimensional array of typed interfaces from a parcel.
4083      * If you want to read Parcelable values, use
4084      * {@link #readFixedArray(Object, Parcelable.Creator)}. For values of other types, use
4085      * {@link #readFixedArray(Object)}.
4086      * @param val the destination array to hold the read values.
4087      */
readFixedArray(@onNull T val, @NonNull Function<IBinder, S> asInterface)4088     public <T, S extends IInterface> void readFixedArray(@NonNull T val,
4089             @NonNull Function<IBinder, S> asInterface) {
4090         Class<?> componentType = val.getClass().getComponentType();
4091         if (IInterface.class.isAssignableFrom(componentType)) {
4092             readInterfaceArray((S[]) val, asInterface);
4093         } else if (componentType.isArray()) {
4094             int length = readInt();
4095             if (length != Array.getLength(val)) {
4096                 throw new BadParcelableException("Bad length: expected " + Array.getLength(val)
4097                     + ", but got " + length);
4098             }
4099             for (int i = 0; i < length; i++) {
4100                 readFixedArray(Array.get(val, i), asInterface);
4101             }
4102         } else {
4103             throw new BadParcelableException("Unknown type for fixed-size array: " + componentType);
4104         }
4105     }
4106 
4107     /**
4108      * Read a new multi-dimensional array of typed parcelables from a parcel.
4109      * If you want to read IInterface values, use
4110      * {@link #readFixedArray(Object, Function)}. For values of other types, use
4111      * {@link #readFixedArray(Object)}.
4112      * @param val the destination array to hold the read values.
4113      */
readFixedArray(@onNull T val, @NonNull Parcelable.Creator<S> c)4114     public <T, S extends Parcelable> void readFixedArray(@NonNull T val,
4115             @NonNull Parcelable.Creator<S> c) {
4116         Class<?> componentType = val.getClass().getComponentType();
4117         if (Parcelable.class.isAssignableFrom(componentType)) {
4118             readTypedArray((S[]) val, c);
4119         } else if (componentType.isArray()) {
4120             int length = readInt();
4121             if (length != Array.getLength(val)) {
4122                 throw new BadParcelableException("Bad length: expected " + Array.getLength(val)
4123                     + ", but got " + length);
4124             }
4125             for (int i = 0; i < length; i++) {
4126                 readFixedArray(Array.get(val, i), c);
4127             }
4128         } else {
4129             throw new BadParcelableException("Unknown type for fixed-size array: " + componentType);
4130         }
4131     }
4132 
ensureClassHasExpectedDimensions(@onNull Class<?> cls, int numDimension)4133     private void ensureClassHasExpectedDimensions(@NonNull Class<?> cls, int numDimension) {
4134         if (numDimension <= 0) {
4135             throw new BadParcelableException("Fixed-size array should have dimensions.");
4136         }
4137 
4138         for (int i = 0; i < numDimension; i++) {
4139             if (!cls.isArray()) {
4140                 throw new BadParcelableException("Array has fewer dimensions than expected: "
4141                     + numDimension);
4142             }
4143             cls = cls.getComponentType();
4144         }
4145         if (cls.isArray()) {
4146             throw new BadParcelableException("Array has more dimensions than expected: "
4147                 + numDimension);
4148         }
4149     }
4150 
4151     /**
4152      * Read and return a new multi-dimensional array from a parcel.  Returns null if the
4153      * previously written array object is null.  If you want to read Parcelable or
4154      * IInterface values, use {@link #createFixedArray(Class, Parcelable.Creator, int[])} or
4155      * {@link #createFixedArray(Class, Function, int[])}.
4156      * @param cls  the Class object for the target array type. (e.g. int[][].class)
4157      * @param dimensions an array of int representing length of each dimension.
4158      *
4159      * @see #writeTypedArray
4160      * @see #createBooleanArray
4161      * @see #createByteArray
4162      * @see #createCharArray
4163      * @see #createIntArray
4164      * @see #createLongArray
4165      * @see #createFloatArray
4166      * @see #createDoubleArray
4167      * @see #createBinderArray
4168      * @see #createInterfaceArray
4169      * @see #createTypedArray
4170      */
4171     @Nullable
createFixedArray(@onNull Class<T> cls, @NonNull int... dimensions)4172     public <T> T createFixedArray(@NonNull Class<T> cls, @NonNull int... dimensions) {
4173         // Check if type matches with dimensions
4174         // If type is one-dimensional array, delegate to other creators
4175         // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
4176 
4177         ensureClassHasExpectedDimensions(cls, dimensions.length);
4178 
4179         T val = null;
4180         final Class<?> componentType = cls.getComponentType();
4181         if (componentType == boolean.class) {
4182             val = (T) createBooleanArray();
4183         } else if (componentType == byte.class) {
4184             val = (T) createByteArray();
4185         } else if (componentType == char.class) {
4186             val = (T) createCharArray();
4187         } else if (componentType == int.class) {
4188             val = (T) createIntArray();
4189         } else if (componentType == long.class) {
4190             val = (T) createLongArray();
4191         } else if (componentType == float.class) {
4192             val = (T) createFloatArray();
4193         } else if (componentType == double.class) {
4194             val = (T) createDoubleArray();
4195         } else if (componentType == IBinder.class) {
4196             val = (T) createBinderArray();
4197         } else if (componentType.isArray()) {
4198             int length = readInt();
4199             if (length < 0) {
4200                 return null;
4201             }
4202             if (length != dimensions[0]) {
4203                 throw new BadParcelableException("Bad length: expected " + dimensions[0]
4204                     + ", but got " + length);
4205             }
4206 
4207             // Create a multi-dimensional array with an innermost component type and dimensions
4208             Class<?> innermost = componentType.getComponentType();
4209             while (innermost.isArray()) {
4210                 innermost = innermost.getComponentType();
4211             }
4212             val = (T) Array.newInstance(innermost, dimensions);
4213             for (int i = 0; i < length; i++) {
4214                 readFixedArray(Array.get(val, i));
4215             }
4216             return val;
4217         } else {
4218             throw new BadParcelableException("Unknown type for fixed-size array: " + componentType);
4219         }
4220 
4221         // Check if val is null (which is OK) or has the expected size.
4222         // This check doesn't have to be multi-dimensional because multi-dimensional arrays
4223         // are created with expected dimensions.
4224         if (val != null && Array.getLength(val) != dimensions[0]) {
4225             throw new BadParcelableException("Bad length: expected " + dimensions[0] + ", but got "
4226                 + Array.getLength(val));
4227         }
4228         return val;
4229     }
4230 
4231     /**
4232      * Read and return a new multi-dimensional array of typed interfaces from a parcel.
4233      * Returns null if the previously written array object is null.  If you want to read
4234      * Parcelable values, use {@link #createFixedArray(Class, Parcelable.Creator, int[])}.
4235      * For values of other types use {@link #createFixedArray(Class, int[])}.
4236      * @param cls  the Class object for the target array type. (e.g. IFoo[][].class)
4237      * @param dimensions an array of int representing length of each dimension.
4238      */
4239     @Nullable
createFixedArray(@onNull Class<T> cls, @NonNull Function<IBinder, S> asInterface, @NonNull int... dimensions)4240     public <T, S extends IInterface> T createFixedArray(@NonNull Class<T> cls,
4241             @NonNull Function<IBinder, S> asInterface, @NonNull int... dimensions) {
4242         // Check if type matches with dimensions
4243         // If type is one-dimensional array, delegate to other creators
4244         // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
4245 
4246         ensureClassHasExpectedDimensions(cls, dimensions.length);
4247 
4248         T val = null;
4249         final Class<?> componentType = cls.getComponentType();
4250         if (IInterface.class.isAssignableFrom(componentType)) {
4251             val = (T) createInterfaceArray(n -> (S[]) Array.newInstance(componentType, n),
4252                     asInterface);
4253         } else if (componentType.isArray()) {
4254             int length = readInt();
4255             if (length < 0) {
4256                 return null;
4257             }
4258             if (length != dimensions[0]) {
4259                 throw new BadParcelableException("Bad length: expected " + dimensions[0]
4260                     + ", but got " + length);
4261             }
4262 
4263             // Create a multi-dimensional array with an innermost component type and dimensions
4264             Class<?> innermost = componentType.getComponentType();
4265             while (innermost.isArray()) {
4266                 innermost = innermost.getComponentType();
4267             }
4268             val = (T) Array.newInstance(innermost, dimensions);
4269             for (int i = 0; i < length; i++) {
4270                 readFixedArray(Array.get(val, i), asInterface);
4271             }
4272             return val;
4273         } else {
4274             throw new BadParcelableException("Unknown type for fixed-size array: " + componentType);
4275         }
4276 
4277         // Check if val is null (which is OK) or has the expected size.
4278         // This check doesn't have to be multi-dimensional because multi-dimensional arrays
4279         // are created with expected dimensions.
4280         if (val != null && Array.getLength(val) != dimensions[0]) {
4281             throw new BadParcelableException("Bad length: expected " + dimensions[0] + ", but got "
4282                 + Array.getLength(val));
4283         }
4284         return val;
4285     }
4286 
4287     /**
4288      * Read and return a new multi-dimensional array of typed parcelables from a parcel.
4289      * Returns null if the previously written array object is null.  If you want to read
4290      * IInterface values, use {@link #createFixedArray(Class, Function, int[])}.
4291      * For values of other types use {@link #createFixedArray(Class, int[])}.
4292      * @param cls  the Class object for the target array type. (e.g. Foo[][].class)
4293      * @param dimensions an array of int representing length of each dimension.
4294      */
4295     @Nullable
createFixedArray(@onNull Class<T> cls, @NonNull Parcelable.Creator<S> c, @NonNull int... dimensions)4296     public <T, S extends Parcelable> T createFixedArray(@NonNull Class<T> cls,
4297             @NonNull Parcelable.Creator<S> c, @NonNull int... dimensions) {
4298         // Check if type matches with dimensions
4299         // If type is one-dimensional array, delegate to other creators
4300         // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
4301 
4302         ensureClassHasExpectedDimensions(cls, dimensions.length);
4303 
4304         T val = null;
4305         final Class<?> componentType = cls.getComponentType();
4306         if (Parcelable.class.isAssignableFrom(componentType)) {
4307             val = (T) createTypedArray(c);
4308         } else if (componentType.isArray()) {
4309             int length = readInt();
4310             if (length < 0) {
4311                 return null;
4312             }
4313             if (length != dimensions[0]) {
4314                 throw new BadParcelableException("Bad length: expected " + dimensions[0]
4315                     + ", but got " + length);
4316             }
4317 
4318             // Create a multi-dimensional array with an innermost component type and dimensions
4319             Class<?> innermost = componentType.getComponentType();
4320             while (innermost.isArray()) {
4321                 innermost = innermost.getComponentType();
4322             }
4323             val = (T) Array.newInstance(innermost, dimensions);
4324             for (int i = 0; i < length; i++) {
4325                 readFixedArray(Array.get(val, i), c);
4326             }
4327             return val;
4328         } else {
4329             throw new BadParcelableException("Unknown type for fixed-size array: " + componentType);
4330         }
4331 
4332         // Check if val is null (which is OK) or has the expected size.
4333         // This check doesn't have to be multi-dimensional because multi-dimensional arrays
4334         // are created with expected dimensions.
4335         if (val != null && Array.getLength(val) != dimensions[0]) {
4336             throw new BadParcelableException("Bad length: expected " + dimensions[0] + ", but got "
4337                 + Array.getLength(val));
4338         }
4339         return val;
4340     }
4341 
4342     /**
4343      * Write a heterogeneous array of Parcelable objects into the Parcel.
4344      * Each object in the array is written along with its class name, so
4345      * that the correct class can later be instantiated.  As a result, this
4346      * has significantly more overhead than {@link #writeTypedArray}, but will
4347      * correctly handle an array containing more than one type of object.
4348      *
4349      * @param value The array of objects to be written.
4350      * @param parcelableFlags Contextual flags as per
4351      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
4352      *
4353      * @see #writeTypedArray
4354      */
writeParcelableArray(@ullable T[] value, int parcelableFlags)4355     public final <T extends Parcelable> void writeParcelableArray(@Nullable T[] value,
4356             int parcelableFlags) {
4357         if (value != null) {
4358             int N = value.length;
4359             writeInt(N);
4360             for (int i=0; i<N; i++) {
4361                 writeParcelable(value[i], parcelableFlags);
4362             }
4363         } else {
4364             writeInt(-1);
4365         }
4366     }
4367 
4368     /**
4369      * Read a typed object from a parcel.  The given class loader will be
4370      * used to load any enclosed Parcelables.  If it is null, the default class
4371      * loader will be used.
4372      */
4373     @Nullable
readValue(@ullable ClassLoader loader)4374     public final Object readValue(@Nullable ClassLoader loader) {
4375         return readValue(loader, /* clazz */ null);
4376     }
4377 
4378 
4379     /**
4380      * @see #readValue(int, ClassLoader, Class, Class[])
4381      */
4382     @Nullable
readValue(@ullable ClassLoader loader, @Nullable Class<T> clazz, @Nullable Class<?>... itemTypes)4383     private <T> T readValue(@Nullable ClassLoader loader, @Nullable Class<T> clazz,
4384             @Nullable Class<?>... itemTypes) {
4385         int type = readInt();
4386         final T object;
4387         if (isLengthPrefixed(type)) {
4388             int length = readInt();
4389             int start = dataPosition();
4390             object = readValue(type, loader, clazz, itemTypes);
4391             int actual = dataPosition() - start;
4392             if (actual != length) {
4393                 Slog.wtfStack(TAG,
4394                         "Unparcelling of " + object + " of type " + Parcel.valueTypeToString(type)
4395                                 + "  consumed " + actual + " bytes, but " + length + " expected.");
4396             }
4397         } else {
4398             object = readValue(type, loader, clazz, itemTypes);
4399         }
4400         return object;
4401     }
4402 
4403     /**
4404      * This will return a {@link BiFunction} for length-prefixed types that deserializes the object
4405      * when {@link BiFunction#apply} is called (the arguments correspond to the ones of {@link
4406      * #readValue(int, ClassLoader, Class, Class[])} after the class loader), for other types it
4407      * will return the object itself.
4408      *
4409      * <p>After calling {@link BiFunction#apply} the parcel cursor will not change. Note that you
4410      * shouldn't recycle the parcel, not at least until all objects have been retrieved. No
4411      * synchronization attempts are made.
4412      *
4413      * </p>The function returned implements {@link #equals(Object)} and {@link #hashCode()}. Two
4414      * function objects are equal if either of the following is true:
4415      * <ul>
4416      *   <li>{@link BiFunction#apply} has been called on both and both objects returned are equal.
4417      *   <li>{@link BiFunction#apply} hasn't been called on either one and everything below is true:
4418      *   <ul>
4419      *       <li>The {@code loader} parameters used to retrieve each are equal.
4420      *       <li>They both have the same type.
4421      *       <li>They have the same payload length.
4422      *       <li>Their binary content is the same.
4423      *   </ul>
4424      * </ul>
4425      *
4426      * @hide
4427      */
4428     @Nullable
readLazyValue(@ullable ClassLoader loader)4429     public Object readLazyValue(@Nullable ClassLoader loader) {
4430         int start = dataPosition();
4431         int type = readInt();
4432         if (isLengthPrefixed(type)) {
4433             int objectLength = readInt();
4434             if (objectLength < 0) {
4435                 return null;
4436             }
4437             int end = MathUtils.addOrThrow(dataPosition(), objectLength);
4438             int valueLength = end - start;
4439             setDataPosition(end);
4440             return new LazyValue(this, start, valueLength, type, loader);
4441         } else {
4442             return readValue(type, loader, /* clazz */ null);
4443         }
4444     }
4445 
4446 
4447     private static final class LazyValue implements BiFunction<Class<?>, Class<?>[], Object> {
4448         /**
4449          *                      |   4B   |   4B   |
4450          * mSource = Parcel{... |  type  | length | object | ...}
4451          *                      a        b        c        d
4452          * length = d - c
4453          * mPosition = a
4454          * mLength = d - a
4455          */
4456         private final int mPosition;
4457         private final int mLength;
4458         private final int mType;
4459         @Nullable private final ClassLoader mLoader;
4460         @Nullable private Object mObject;
4461 
4462         /**
4463          * This goes from non-null to null once. Always check the nullability of this object before
4464          * performing any operations, either involving itself or mObject since the happens-before
4465          * established by this volatile will guarantee visibility of either. We can assume this
4466          * parcel won't change anymore.
4467          */
4468         @Nullable private volatile Parcel mSource;
4469 
LazyValue(Parcel source, int position, int length, int type, @Nullable ClassLoader loader)4470         LazyValue(Parcel source, int position, int length, int type, @Nullable ClassLoader loader) {
4471             mSource = requireNonNull(source);
4472             mPosition = position;
4473             mLength = length;
4474             mType = type;
4475             mLoader = loader;
4476         }
4477 
4478         @Override
apply(@ullable Class<?> clazz, @Nullable Class<?>[] itemTypes)4479         public Object apply(@Nullable Class<?> clazz, @Nullable Class<?>[] itemTypes) {
4480             Parcel source = mSource;
4481             if (source != null) {
4482                 synchronized (source) {
4483                     // Check mSource != null guarantees callers won't ever see different objects.
4484                     if (mSource != null) {
4485                         int restore = source.dataPosition();
4486                         try {
4487                             source.setDataPosition(mPosition);
4488                             mObject = source.readValue(mLoader, clazz, itemTypes);
4489                         } finally {
4490                             source.setDataPosition(restore);
4491                         }
4492                         mSource = null;
4493                     }
4494                 }
4495             }
4496             return mObject;
4497         }
4498 
writeToParcel(Parcel out)4499         public void writeToParcel(Parcel out) {
4500             Parcel source = mSource;
4501             if (source != null) {
4502                 synchronized (source) {
4503                     if (mSource != null) {
4504                         out.appendFrom(source, mPosition, mLength);
4505                         return;
4506                     }
4507                 }
4508             }
4509 
4510             out.writeValue(mObject);
4511         }
4512 
hasFileDescriptors()4513         public boolean hasFileDescriptors() {
4514             Parcel source = mSource;
4515             if (source != null) {
4516                 synchronized (source) {
4517                     if (mSource != null) {
4518                         return source.hasFileDescriptors(mPosition, mLength);
4519                     }
4520                 }
4521             }
4522 
4523             return Parcel.hasFileDescriptors(mObject);
4524         }
4525 
4526         @Override
toString()4527         public String toString() {
4528             return (mSource != null)
4529                     ? "Supplier{" + valueTypeToString(mType) + "@" + mPosition + "+" + mLength + '}'
4530                     : "Supplier{" + mObject + "}";
4531         }
4532 
4533         /**
4534          * We're checking if the *lazy value* is equal to another one, not if the *object*
4535          * represented by the lazy value is equal to the other one. So, if there are two lazy values
4536          * and one of them has been deserialized but the other hasn't this will always return false.
4537          */
4538         @Override
equals(Object other)4539         public boolean equals(Object other) {
4540             if (this == other) {
4541                 return true;
4542             }
4543             if (!(other instanceof LazyValue)) {
4544                 return false;
4545             }
4546             LazyValue value = (LazyValue) other;
4547             // Check if they are either both serialized or both deserialized.
4548             Parcel source = mSource;
4549             Parcel otherSource = value.mSource;
4550             if ((source == null) != (otherSource == null)) {
4551                 return false;
4552             }
4553             // If both are deserialized, compare the live objects.
4554             if (source == null) {
4555                 // Note that here it's guaranteed that both mObject references contain valid values
4556                 // (possibly null) since mSource will have provided the memory barrier for those and
4557                 // once deserialized we never go back to serialized state.
4558                 return Objects.equals(mObject, value.mObject);
4559             }
4560             // Better safely fail here since this could mean we get different objects.
4561             if (!Objects.equals(mLoader, value.mLoader)) {
4562                 return false;
4563             }
4564             // Otherwise compare metadata prior to comparing payload.
4565             if (mType != value.mType || mLength != value.mLength) {
4566                 return false;
4567             }
4568             // Finally we compare the payload.
4569             return Parcel.compareData(source, mPosition, otherSource, value.mPosition, mLength);
4570         }
4571 
4572         @Override
hashCode()4573         public int hashCode() {
4574             // Accessing mSource first to provide memory barrier for mObject
4575             return Objects.hash(mSource == null, mObject, mLoader, mType, mLength);
4576         }
4577     }
4578 
4579     /** Same as {@link #readValue(ClassLoader, Class, Class[])} without any item types. */
readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz)4580     private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz) {
4581         // Avoids allocating Class[0] array
4582         return readValue(type, loader, clazz, (Class<?>[]) null);
4583     }
4584 
4585     /**
4586      * Reads a value from the parcel of type {@code type}. Does NOT read the int representing the
4587      * type first.
4588      *
4589      * @param clazz The type of the object expected or {@code null} for performing no checks.
4590      * @param itemTypes If the value is a container, these represent the item types (eg. for a list
4591      *                  it's the item type, for a map, it's the key type, followed by the value
4592      *                  type).
4593      */
4594     @SuppressWarnings("unchecked")
4595     @Nullable
readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz, @Nullable Class<?>... itemTypes)4596     private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz,
4597             @Nullable Class<?>... itemTypes) {
4598         final Object object;
4599         switch (type) {
4600             case VAL_NULL:
4601                 object = null;
4602                 break;
4603 
4604             case VAL_STRING:
4605                 object = readString();
4606                 break;
4607 
4608             case VAL_INTEGER:
4609                 object = readInt();
4610                 break;
4611 
4612             case VAL_MAP:
4613                 checkTypeToUnparcel(clazz, HashMap.class);
4614                 Class<?> keyType = ArrayUtils.getOrNull(itemTypes, 0);
4615                 Class<?> valueType = ArrayUtils.getOrNull(itemTypes, 1);
4616                 checkArgument((keyType == null) == (valueType == null));
4617                 object = readHashMapInternal(loader, keyType, valueType);
4618                 break;
4619 
4620             case VAL_PARCELABLE:
4621                 object = readParcelableInternal(loader, clazz);
4622                 break;
4623 
4624             case VAL_SHORT:
4625                 object = (short) readInt();
4626                 break;
4627 
4628             case VAL_LONG:
4629                 object = readLong();
4630                 break;
4631 
4632             case VAL_FLOAT:
4633                 object = readFloat();
4634                 break;
4635 
4636             case VAL_DOUBLE:
4637                 object = readDouble();
4638                 break;
4639 
4640             case VAL_BOOLEAN:
4641                 object = readInt() == 1;
4642                 break;
4643 
4644             case VAL_CHARSEQUENCE:
4645                 object = readCharSequence();
4646                 break;
4647 
4648             case VAL_LIST: {
4649                 checkTypeToUnparcel(clazz, ArrayList.class);
4650                 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0);
4651                 object = readArrayListInternal(loader, itemType);
4652                 break;
4653             }
4654             case VAL_BOOLEANARRAY:
4655                 object = createBooleanArray();
4656                 break;
4657 
4658             case VAL_BYTEARRAY:
4659                 object = createByteArray();
4660                 break;
4661 
4662             case VAL_STRINGARRAY:
4663                 object = readStringArray();
4664                 break;
4665 
4666             case VAL_CHARSEQUENCEARRAY:
4667                 object = readCharSequenceArray();
4668                 break;
4669 
4670             case VAL_IBINDER:
4671                 object = readStrongBinder();
4672                 break;
4673 
4674             case VAL_OBJECTARRAY: {
4675                 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0);
4676                 checkArrayTypeToUnparcel(clazz, (itemType != null) ? itemType : Object.class);
4677                 object = readArrayInternal(loader, itemType);
4678                 break;
4679             }
4680             case VAL_INTARRAY:
4681                 object = createIntArray();
4682                 break;
4683 
4684             case VAL_LONGARRAY:
4685                 object = createLongArray();
4686                 break;
4687 
4688             case VAL_BYTE:
4689                 object = readByte();
4690                 break;
4691 
4692             case VAL_SERIALIZABLE:
4693                 object = readSerializableInternal(loader, clazz);
4694                 break;
4695 
4696             case VAL_PARCELABLEARRAY: {
4697                 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0);
4698                 checkArrayTypeToUnparcel(clazz, (itemType != null) ? itemType : Parcelable.class);
4699                 object = readParcelableArrayInternal(loader, itemType);
4700                 break;
4701             }
4702             case VAL_SPARSEARRAY: {
4703                 checkTypeToUnparcel(clazz, SparseArray.class);
4704                 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0);
4705                 object = readSparseArrayInternal(loader, itemType);
4706                 break;
4707             }
4708             case VAL_SPARSEBOOLEANARRAY:
4709                 object = readSparseBooleanArray();
4710                 break;
4711 
4712             case VAL_BUNDLE:
4713                 object = readBundle(loader); // loading will be deferred
4714                 break;
4715 
4716             case VAL_PERSISTABLEBUNDLE:
4717                 object = readPersistableBundle(loader);
4718                 break;
4719 
4720             case VAL_SIZE:
4721                 object = readSize();
4722                 break;
4723 
4724             case VAL_SIZEF:
4725                 object = readSizeF();
4726                 break;
4727 
4728             case VAL_DOUBLEARRAY:
4729                 object = createDoubleArray();
4730                 break;
4731 
4732             case VAL_CHAR:
4733                 object = (char) readInt();
4734                 break;
4735 
4736             case VAL_SHORTARRAY:
4737                 object = createShortArray();
4738                 break;
4739 
4740             case VAL_CHARARRAY:
4741                 object = createCharArray();
4742                 break;
4743 
4744             case VAL_FLOATARRAY:
4745                 object = createFloatArray();
4746                 break;
4747 
4748             default:
4749                 int off = dataPosition() - 4;
4750                 throw new BadParcelableException(
4751                     "Parcel " + this + ": Unmarshalling unknown type code " + type
4752                             + " at offset " + off);
4753         }
4754         if (object != null && clazz != null && !clazz.isInstance(object)) {
4755             throw new BadTypeParcelableException("Unparcelled object " + object
4756                     + " is not an instance of required class " + clazz.getName()
4757                     + " provided in the parameter");
4758         }
4759         return (T) object;
4760     }
4761 
isLengthPrefixed(int type)4762     private boolean isLengthPrefixed(int type) {
4763         // In general, we want custom types and containers of custom types to be length-prefixed,
4764         // this allows clients (eg. Bundle) to skip their content during deserialization. The
4765         // exception to this is Bundle, since Bundle is already length-prefixed and already copies
4766         // the correspondent section of the parcel internally.
4767         switch (type) {
4768             case VAL_MAP:
4769             case VAL_PARCELABLE:
4770             case VAL_LIST:
4771             case VAL_SPARSEARRAY:
4772             case VAL_PARCELABLEARRAY:
4773             case VAL_OBJECTARRAY:
4774             case VAL_SERIALIZABLE:
4775                 return true;
4776             default:
4777                 return false;
4778         }
4779     }
4780 
4781     /**
4782      * Checks that an array of type T[], where T is {@code componentTypeToUnparcel}, is a subtype of
4783      * {@code requiredArrayType}.
4784      */
checkArrayTypeToUnparcel(@ullable Class<?> requiredArrayType, Class<?> componentTypeToUnparcel)4785     private void checkArrayTypeToUnparcel(@Nullable Class<?> requiredArrayType,
4786             Class<?> componentTypeToUnparcel) {
4787         if (requiredArrayType != null) {
4788             // In Java 12, we could use componentTypeToUnparcel.arrayType() for the check
4789             Class<?> requiredComponentType = requiredArrayType.getComponentType();
4790             if (requiredComponentType == null) {
4791                 throw new BadTypeParcelableException(
4792                         "About to unparcel an array but type "
4793                                 + requiredArrayType.getCanonicalName()
4794                                 + " required by caller is not an array.");
4795             }
4796             checkTypeToUnparcel(requiredComponentType, componentTypeToUnparcel);
4797         }
4798     }
4799 
4800     /**
4801      * Checks that {@code typeToUnparcel} is a subtype of {@code requiredType}, if {@code
4802      * requiredType} is not {@code null}.
4803      */
checkTypeToUnparcel(@ullable Class<?> requiredType, Class<?> typeToUnparcel)4804     private void checkTypeToUnparcel(@Nullable Class<?> requiredType, Class<?> typeToUnparcel) {
4805         if (requiredType != null && !requiredType.isAssignableFrom(typeToUnparcel)) {
4806             throw new BadTypeParcelableException(
4807                     "About to unparcel a " + typeToUnparcel.getCanonicalName()
4808                             + ", which is not a subtype of type " + requiredType.getCanonicalName()
4809                             + " required by caller.");
4810         }
4811     }
4812 
4813     /**
4814      * Read and return a new Parcelable from the parcel.  The given class loader
4815      * will be used to load any enclosed Parcelables.  If it is null, the default
4816      * class loader will be used.
4817      * @param loader A ClassLoader from which to instantiate the Parcelable
4818      * object, or null for the default class loader.
4819      * @return Returns the newly created Parcelable, or null if a null
4820      * object has been written.
4821      * @throws BadParcelableException Throws BadParcelableException if there
4822      * was an error trying to instantiate the Parcelable.
4823      *
4824      * @deprecated Use the type-safer version {@link #readParcelable(ClassLoader, Class)} starting
4825      *      from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to
4826      *      use {@link Parcelable.Creator#createFromParcel(Parcel)} if possible since this is also
4827      *      more performant. Note that changing to the latter also requires changing the writes.
4828      */
4829     @Deprecated
4830     @Nullable
readParcelable(@ullable ClassLoader loader)4831     public final <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader) {
4832         return readParcelableInternal(loader, /* clazz */ null);
4833     }
4834 
4835     /**
4836      * Same as {@link #readParcelable(ClassLoader)} but accepts {@code clazz} parameter as the type
4837      * required for each item.
4838      *
4839      * <p><b>Warning: </b> the class that implements {@link Parcelable} has to be the immediately
4840      * enclosing class of the runtime type of its CREATOR field (that is,
4841      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
4842      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
4843      * CREATOR, use the deprecated {@link #readParcelable(ClassLoader)} instead.
4844      *
4845      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
4846      * is not an instance of that class or any of its children classes or there was an error
4847      * trying to instantiate an element.
4848      */
4849     @Nullable
readParcelable(@ullable ClassLoader loader, @NonNull Class<T> clazz)4850     public <T> T readParcelable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
4851         Objects.requireNonNull(clazz);
4852         return readParcelableInternal(loader, clazz);
4853     }
4854 
4855     /**
4856      * @param clazz The type of the parcelable expected or {@code null} for performing no checks.
4857      */
4858     @SuppressWarnings("unchecked")
4859     @Nullable
readParcelableInternal(@ullable ClassLoader loader, @Nullable Class<T> clazz)4860     private <T> T readParcelableInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
4861         Parcelable.Creator<?> creator = readParcelableCreatorInternal(loader, clazz);
4862         if (creator == null) {
4863             return null;
4864         }
4865         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
4866             Parcelable.ClassLoaderCreator<?> classLoaderCreator =
4867                     (Parcelable.ClassLoaderCreator<?>) creator;
4868             return (T) classLoaderCreator.createFromParcel(this, loader);
4869         }
4870         return (T) creator.createFromParcel(this);
4871     }
4872 
4873     /** @hide */
4874     @UnsupportedAppUsage
4875     @SuppressWarnings("unchecked")
4876     @Nullable
readCreator(@onNull Parcelable.Creator<?> creator, @Nullable ClassLoader loader)4877     public final <T extends Parcelable> T readCreator(@NonNull Parcelable.Creator<?> creator,
4878             @Nullable ClassLoader loader) {
4879         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
4880           Parcelable.ClassLoaderCreator<?> classLoaderCreator =
4881               (Parcelable.ClassLoaderCreator<?>) creator;
4882           return (T) classLoaderCreator.createFromParcel(this, loader);
4883         }
4884         return (T) creator.createFromParcel(this);
4885     }
4886 
4887     /**
4888      * Read and return a Parcelable.Creator from the parcel. The given class loader will be used to
4889      * load the {@link Parcelable.Creator}. If it is null, the default class loader will be used.
4890      *
4891      * @param loader A ClassLoader from which to instantiate the {@link Parcelable.Creator}
4892      * object, or null for the default class loader.
4893      * @return the previously written {@link Parcelable.Creator}, or null if a null Creator was
4894      * written.
4895      * @throws BadParcelableException Throws BadParcelableException if there was an error trying to
4896      * read the {@link Parcelable.Creator}.
4897      *
4898      * @see #writeParcelableCreator
4899      *
4900      * @deprecated Use the type-safer version {@link #readParcelableCreator(ClassLoader, Class)}
4901      *       starting from Android {@link Build.VERSION_CODES#TIRAMISU}.
4902      */
4903     @Deprecated
4904     @Nullable
readParcelableCreator(@ullable ClassLoader loader)4905     public final Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader loader) {
4906         return readParcelableCreatorInternal(loader, /* clazz */ null);
4907     }
4908 
4909     /**
4910      * Same as {@link #readParcelableCreator(ClassLoader)} but accepts {@code clazz} parameter
4911      * as the required type.
4912      *
4913      * <p><b>Warning: </b> the class that implements {@link Parcelable} has to be the immediately
4914      * enclosing class of the runtime type of its CREATOR field (that is,
4915      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
4916      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
4917      * CREATOR, use the deprecated {@link #readParcelableCreator(ClassLoader) instead.
4918      *
4919      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
4920      * is not an instance of that class or any of its children classes or there there was an error
4921      * trying to read the {@link Parcelable.Creator}.
4922      */
4923     @Nullable
readParcelableCreator( @ullable ClassLoader loader, @NonNull Class<T> clazz)4924     public <T> Parcelable.Creator<T> readParcelableCreator(
4925             @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
4926         Objects.requireNonNull(clazz);
4927         return readParcelableCreatorInternal(loader, clazz);
4928     }
4929 
4930     /**
4931      * @param clazz The type of the parcelable expected or {@code null} for performing no checks.
4932      */
4933     @SuppressWarnings("unchecked")
4934     @Nullable
readParcelableCreatorInternal( @ullable ClassLoader loader, @Nullable Class<T> clazz)4935     private <T> Parcelable.Creator<T> readParcelableCreatorInternal(
4936             @Nullable ClassLoader loader, @Nullable Class<T> clazz) {
4937         String name = readString();
4938         if (name == null) {
4939             return null;
4940         }
4941 
4942         Pair<Parcelable.Creator<?>, Class<?>> creatorAndParcelableClass;
4943         synchronized (sPairedCreators) {
4944             HashMap<String, Pair<Parcelable.Creator<?>, Class<?>>> map =
4945                     sPairedCreators.get(loader);
4946             if (map == null) {
4947                 sPairedCreators.put(loader, new HashMap<>());
4948                 mCreators.put(loader, new HashMap<>());
4949                 creatorAndParcelableClass = null;
4950             } else {
4951                 creatorAndParcelableClass = map.get(name);
4952             }
4953         }
4954 
4955         if (creatorAndParcelableClass != null) {
4956             Parcelable.Creator<?> creator = creatorAndParcelableClass.first;
4957             Class<?> parcelableClass = creatorAndParcelableClass.second;
4958             if (clazz != null) {
4959                 if (!clazz.isAssignableFrom(parcelableClass)) {
4960                     throw new BadTypeParcelableException("Parcelable creator " + name + " is not "
4961                             + "a subclass of required class " + clazz.getName()
4962                             + " provided in the parameter");
4963                 }
4964             }
4965 
4966             return (Parcelable.Creator<T>) creator;
4967         }
4968 
4969         Parcelable.Creator<?> creator;
4970         Class<?> parcelableClass;
4971         try {
4972             // If loader == null, explicitly emulate Class.forName(String) "caller
4973             // classloader" behavior.
4974             ClassLoader parcelableClassLoader =
4975                     (loader == null ? getClass().getClassLoader() : loader);
4976             // Avoid initializing the Parcelable class until we know it implements
4977             // Parcelable and has the necessary CREATOR field. http://b/1171613.
4978             parcelableClass = Class.forName(name, false /* initialize */,
4979                     parcelableClassLoader);
4980             if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
4981                 throw new BadParcelableException("Parcelable protocol requires subclassing "
4982                         + "from Parcelable on class " + name);
4983             }
4984             if (clazz != null) {
4985                 if (!clazz.isAssignableFrom(parcelableClass)) {
4986                     throw new BadTypeParcelableException("Parcelable creator " + name + " is not "
4987                             + "a subclass of required class " + clazz.getName()
4988                             + " provided in the parameter");
4989                 }
4990             }
4991 
4992             Field f = parcelableClass.getField("CREATOR");
4993             if ((f.getModifiers() & Modifier.STATIC) == 0) {
4994                 throw new BadParcelableException("Parcelable protocol requires "
4995                         + "the CREATOR object to be static on class " + name);
4996             }
4997             Class<?> creatorType = f.getType();
4998             if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {
4999                 // Fail before calling Field.get(), not after, to avoid initializing
5000                 // parcelableClass unnecessarily.
5001                 throw new BadParcelableException("Parcelable protocol requires a "
5002                         + "Parcelable.Creator object called "
5003                         + "CREATOR on class " + name);
5004             }
5005             creator = (Parcelable.Creator<?>) f.get(null);
5006         } catch (IllegalAccessException e) {
5007             Log.e(TAG, "Illegal access when unmarshalling: " + name, e);
5008             throw new BadParcelableException(
5009                     "IllegalAccessException when unmarshalling: " + name, e);
5010         } catch (ClassNotFoundException e) {
5011             Log.e(TAG, "Class not found when unmarshalling: " + name, e);
5012             throw new BadParcelableException(
5013                     "ClassNotFoundException when unmarshalling: " + name, e);
5014         } catch (NoSuchFieldException e) {
5015             throw new BadParcelableException("Parcelable protocol requires a "
5016                     + "Parcelable.Creator object called "
5017                     + "CREATOR on class " + name, e);
5018         }
5019         if (creator == null) {
5020             throw new BadParcelableException("Parcelable protocol requires a "
5021                     + "non-null Parcelable.Creator object called "
5022                     + "CREATOR on class " + name);
5023         }
5024 
5025         synchronized (sPairedCreators) {
5026             sPairedCreators.get(loader).put(name, Pair.create(creator, parcelableClass));
5027             mCreators.get(loader).put(name, creator);
5028         }
5029 
5030         return (Parcelable.Creator<T>) creator;
5031     }
5032 
5033     /**
5034      * Read and return a new Parcelable array from the parcel.
5035      * The given class loader will be used to load any enclosed
5036      * Parcelables.
5037      * @return the Parcelable array, or null if the array is null
5038      *
5039      * @deprecated Use the type-safer version {@link #readParcelableArray(ClassLoader, Class)}
5040      *      starting from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the
5041      *      format to use {@link #createTypedArray(Parcelable.Creator)} if possible (eg. if the
5042      *      items' class is final) since this is also more performant. Note that changing to the
5043      *      latter also requires changing the writes.
5044      */
5045     @Deprecated
5046     @Nullable
readParcelableArray(@ullable ClassLoader loader)5047     public Parcelable[] readParcelableArray(@Nullable ClassLoader loader) {
5048         return readParcelableArrayInternal(loader, /* clazz */ null);
5049     }
5050 
5051     /**
5052      * Same as {@link #readParcelableArray(ClassLoader)}  but accepts {@code clazz} parameter as
5053      * the type required for each item.
5054      *
5055      * <p><b>Warning: </b> the class that implements {@link Parcelable} has to be the immediately
5056      * enclosing class of the runtime type of its CREATOR field (that is,
5057      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
5058      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
5059      * CREATOR, use the deprecated {@link #readParcelableArray(ClassLoader)} instead.
5060      *
5061      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
5062      * is not an instance of that class or any of its children classes or there was an error
5063      * trying to instantiate an element.
5064      */
5065     @SuppressLint({"ArrayReturn", "NullableCollection"})
5066     @Nullable
readParcelableArray(@ullable ClassLoader loader, @NonNull Class<T> clazz)5067     public <T> T[] readParcelableArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
5068         return readParcelableArrayInternal(loader, requireNonNull(clazz));
5069     }
5070 
5071     @SuppressWarnings("unchecked")
5072     @Nullable
readParcelableArrayInternal(@ullable ClassLoader loader, @Nullable Class<T> clazz)5073     private <T> T[] readParcelableArrayInternal(@Nullable ClassLoader loader,
5074             @Nullable Class<T> clazz) {
5075         int n = readInt();
5076         if (n < 0) {
5077             return null;
5078         }
5079         T[] p = (T[]) ((clazz == null) ? new Parcelable[n] : Array.newInstance(clazz, n));
5080         for (int i = 0; i < n; i++) {
5081             p[i] = readParcelableInternal(loader, clazz);
5082         }
5083         return p;
5084     }
5085 
5086     /**
5087      * Read and return a new Serializable object from the parcel.
5088      * @return the Serializable object, or null if the Serializable name
5089      * wasn't found in the parcel.
5090      *
5091      * Unlike {@link #readSerializable(ClassLoader, Class)}, it uses the nearest valid class loader
5092      * up the execution stack to instantiate the Serializable object.
5093      *
5094      * @deprecated Use the type-safer version {@link #readSerializable(ClassLoader, Class)} starting
5095      *       from Android {@link Build.VERSION_CODES#TIRAMISU}.
5096      */
5097     @Deprecated
5098     @Nullable
readSerializable()5099     public Serializable readSerializable() {
5100         return readSerializableInternal(/* loader */ null, /* clazz */ null);
5101     }
5102 
5103     /**
5104      * Same as {@link #readSerializable()} but accepts {@code loader} and {@code clazz} parameters.
5105      *
5106      * @param loader A ClassLoader from which to instantiate the Serializable object,
5107      * or null for the default class loader.
5108      * @param clazz The type of the object expected.
5109      *
5110      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
5111      * is not an instance of that class or any of its children class or there there was an error
5112      * deserializing the object.
5113      */
5114     @Nullable
readSerializable(@ullable ClassLoader loader, @NonNull Class<T> clazz)5115     public <T> T readSerializable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
5116         Objects.requireNonNull(clazz);
5117         return readSerializableInternal(
5118                 loader == null ? getClass().getClassLoader() : loader, clazz);
5119     }
5120 
5121     /**
5122      * @param clazz The type of the serializable expected or {@code null} for performing no checks
5123      */
5124     @Nullable
readSerializableInternal(@ullable final ClassLoader loader, @Nullable Class<T> clazz)5125     private <T> T readSerializableInternal(@Nullable final ClassLoader loader,
5126             @Nullable Class<T> clazz) {
5127         String name = readString();
5128         if (name == null) {
5129             // For some reason we were unable to read the name of the Serializable (either there
5130             // is nothing left in the Parcel to read, or the next value wasn't a String), so
5131             // return null, which indicates that the name wasn't found in the parcel.
5132             return null;
5133         }
5134 
5135         try {
5136             if (clazz != null && loader != null) {
5137                 // If custom classloader is provided, resolve the type of serializable using the
5138                 // name, then check the type before deserialization. As in this case we can resolve
5139                 // the class the same way as ObjectInputStream, using the provided classloader.
5140                 Class<?> cl = Class.forName(name, false, loader);
5141                 if (!clazz.isAssignableFrom(cl)) {
5142                     throw new BadTypeParcelableException("Serializable object "
5143                             + cl.getName() + " is not a subclass of required class "
5144                             + clazz.getName() + " provided in the parameter");
5145                 }
5146             }
5147             byte[] serializedData = createByteArray();
5148             ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
5149             ObjectInputStream ois = new ObjectInputStream(bais) {
5150                 @Override
5151                 protected Class<?> resolveClass(ObjectStreamClass osClass)
5152                         throws IOException, ClassNotFoundException {
5153                     // try the custom classloader if provided
5154                     if (loader != null) {
5155                         Class<?> c = Class.forName(osClass.getName(), false, loader);
5156                         return Objects.requireNonNull(c);
5157                     }
5158                     return super.resolveClass(osClass);
5159                 }
5160             };
5161             T object = (T) ois.readObject();
5162             if (clazz != null && loader == null) {
5163                 // If custom classloader is not provided, check the type of the serializable using
5164                 // the deserialized object, as we cannot resolve the class the same way as
5165                 // ObjectInputStream.
5166                 if (!clazz.isAssignableFrom(object.getClass())) {
5167                     throw new BadTypeParcelableException("Serializable object "
5168                             + object.getClass().getName() + " is not a subclass of required class "
5169                             + clazz.getName() + " provided in the parameter");
5170                 }
5171             }
5172             return object;
5173         } catch (IOException ioe) {
5174             throw new BadParcelableException("Parcelable encountered "
5175                     + "IOException reading a Serializable object (name = "
5176                     + name + ")", ioe);
5177         } catch (ClassNotFoundException cnfe) {
5178             throw new BadParcelableException("Parcelable encountered "
5179                     + "ClassNotFoundException reading a Serializable object (name = "
5180                     + name + ")", cnfe);
5181         }
5182     }
5183 
5184 
5185     // Left due to the UnsupportedAppUsage. Do not use anymore - use sPairedCreators instead
5186     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
5187     private static final HashMap<ClassLoader, HashMap<String, Parcelable.Creator<?>>>
5188             mCreators = new HashMap<>();
5189 
5190     // Cache of previously looked up CREATOR.createFromParcel() methods for particular classes.
5191     // Keys are the names of the classes, values are a pair consisting of a parcelable creator,
5192     // and the class of the parcelable type for the object.
5193     private static final HashMap<ClassLoader, HashMap<String,
5194             Pair<Parcelable.Creator<?>, Class<?>>>> sPairedCreators = new HashMap<>();
5195 
5196     /** @hide for internal use only. */
obtain(int obj)5197     static protected final Parcel obtain(int obj) {
5198         throw new UnsupportedOperationException();
5199     }
5200 
5201     /** @hide */
obtain(long obj)5202     static protected final Parcel obtain(long obj) {
5203         Parcel res = null;
5204         synchronized (sPoolSync) {
5205             if (sHolderPool != null) {
5206                 res = sHolderPool;
5207                 sHolderPool = res.mPoolNext;
5208                 res.mPoolNext = null;
5209                 sHolderPoolSize--;
5210             }
5211         }
5212 
5213         // When no cache found above, create from scratch; otherwise prepare the
5214         // cached object to be used
5215         if (res == null) {
5216             res = new Parcel(obj);
5217         } else {
5218             res.mRecycled = false;
5219             if (DEBUG_RECYCLE) {
5220                 res.mStack = new RuntimeException();
5221             }
5222             res.init(obj);
5223         }
5224         return res;
5225     }
5226 
Parcel(long nativePtr)5227     private Parcel(long nativePtr) {
5228         if (DEBUG_RECYCLE) {
5229             mStack = new RuntimeException();
5230         }
5231         //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
5232         init(nativePtr);
5233     }
5234 
init(long nativePtr)5235     private void init(long nativePtr) {
5236         if (nativePtr != 0) {
5237             mNativePtr = nativePtr;
5238             mOwnsNativeParcelObject = false;
5239         } else {
5240             mNativePtr = nativeCreate();
5241             mOwnsNativeParcelObject = true;
5242         }
5243     }
5244 
freeBuffer()5245     private void freeBuffer() {
5246         mFlags = 0;
5247         resetSqaushingState();
5248         if (mOwnsNativeParcelObject) {
5249             nativeFreeBuffer(mNativePtr);
5250         }
5251         mReadWriteHelper = ReadWriteHelper.DEFAULT;
5252     }
5253 
destroy()5254     private void destroy() {
5255         resetSqaushingState();
5256         if (mNativePtr != 0) {
5257             if (mOwnsNativeParcelObject) {
5258                 nativeDestroy(mNativePtr);
5259             }
5260             mNativePtr = 0;
5261         }
5262     }
5263 
5264     @Override
finalize()5265     protected void finalize() throws Throwable {
5266         if (DEBUG_RECYCLE) {
5267             // we could always have this log on, but it's spammy
5268             if (!mRecycled) {
5269                 Log.w(TAG, "Client did not call Parcel.recycle()", mStack);
5270             }
5271         }
5272         destroy();
5273     }
5274 
5275     /**
5276      * To be replaced by {@link #readMapInternal(Map, int, ClassLoader, Class, Class)}, but keep
5277      * the old API for compatibility usages.
5278      */
readMapInternal(@onNull Map outVal, int n, @Nullable ClassLoader loader)5279     /* package */ void readMapInternal(@NonNull Map outVal, int n,
5280             @Nullable ClassLoader loader) {
5281         readMapInternal(outVal, n, loader, /* clazzKey */null, /* clazzValue */null);
5282     }
5283 
5284     @Nullable
readHashMapInternal(@ullable ClassLoader loader, @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue)5285     private <K, V> HashMap<K, V> readHashMapInternal(@Nullable ClassLoader loader,
5286             @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) {
5287         int n = readInt();
5288         if (n < 0) {
5289             return null;
5290         }
5291         HashMap<K, V> map = new HashMap<>(n);
5292         readMapInternal(map, n, loader, clazzKey, clazzValue);
5293         return map;
5294     }
5295 
readMapInternal(@onNull Map<? super K, ? super V> outVal, @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, @Nullable Class<V> clazzValue)5296     private <K, V> void readMapInternal(@NonNull Map<? super K, ? super V> outVal,
5297             @Nullable ClassLoader loader, @Nullable Class<K> clazzKey,
5298             @Nullable Class<V> clazzValue) {
5299         int n = readInt();
5300         readMapInternal(outVal, n, loader, clazzKey, clazzValue);
5301     }
5302 
readMapInternal(@onNull Map<? super K, ? super V> outVal, int n, @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, @Nullable Class<V> clazzValue)5303     private <K, V> void readMapInternal(@NonNull Map<? super K, ? super V> outVal, int n,
5304             @Nullable ClassLoader loader, @Nullable Class<K> clazzKey,
5305             @Nullable Class<V> clazzValue) {
5306         while (n > 0) {
5307             K key = readValue(loader, clazzKey);
5308             V value = readValue(loader, clazzValue);
5309             outVal.put(key, value);
5310             n--;
5311         }
5312     }
5313 
readArrayMapInternal(@onNull ArrayMap<? super String, Object> outVal, int size, @Nullable ClassLoader loader)5314     private void readArrayMapInternal(@NonNull ArrayMap<? super String, Object> outVal,
5315             int size, @Nullable ClassLoader loader) {
5316         readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader);
5317     }
5318 
5319     /**
5320      * Reads a map into {@code map}.
5321      *
5322      * @param sorted Whether the keys are sorted by their hashes, if so we use an optimized path.
5323      * @param lazy   Whether to populate the map with lazy {@link Function} objects for
5324      *               length-prefixed values. See {@link Parcel#readLazyValue(ClassLoader)} for more
5325      *               details.
5326      * @return a count of the lazy values in the map
5327      * @hide
5328      */
readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted, boolean lazy, @Nullable ClassLoader loader)5329     int readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted,
5330             boolean lazy, @Nullable ClassLoader loader) {
5331         int lazyValues = 0;
5332         while (size > 0) {
5333             String key = readString();
5334             Object value = (lazy) ? readLazyValue(loader) : readValue(loader);
5335             if (value instanceof LazyValue) {
5336                 lazyValues++;
5337             }
5338             if (sorted) {
5339                 map.append(key, value);
5340             } else {
5341                 map.put(key, value);
5342             }
5343             size--;
5344         }
5345         if (sorted) {
5346             map.validate();
5347         }
5348         return lazyValues;
5349     }
5350 
5351     /**
5352      * @hide For testing only.
5353      */
5354     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
readArrayMap(@onNull ArrayMap<? super String, Object> outVal, @Nullable ClassLoader loader)5355     public void readArrayMap(@NonNull ArrayMap<? super String, Object> outVal,
5356             @Nullable ClassLoader loader) {
5357         final int N = readInt();
5358         if (N < 0) {
5359             return;
5360         }
5361         readArrayMapInternal(outVal, N, loader);
5362     }
5363 
5364     /**
5365      * Reads an array set.
5366      *
5367      * @param loader The class loader to use.
5368      *
5369      * @hide
5370      */
5371     @UnsupportedAppUsage
readArraySet(@ullable ClassLoader loader)5372     public @Nullable ArraySet<? extends Object> readArraySet(@Nullable ClassLoader loader) {
5373         final int size = readInt();
5374         if (size < 0) {
5375             return null;
5376         }
5377         ArraySet<Object> result = new ArraySet<>(size);
5378         for (int i = 0; i < size; i++) {
5379             Object value = readValue(loader);
5380             result.append(value);
5381         }
5382         return result;
5383     }
5384 
5385     /**
5386      * The method is replaced by {@link #readListInternal(List, int, ClassLoader, Class)}, however
5387      * we are keeping this unused method here to allow unsupported app usages.
5388      */
readListInternal(@onNull List outVal, int n, @Nullable ClassLoader loader)5389     private void readListInternal(@NonNull List outVal, int n, @Nullable ClassLoader loader) {
5390         readListInternal(outVal, n, loader,  /* clazz */ null);
5391     }
5392 
5393     /**
5394      * @param clazz The type of the object expected or {@code null} for performing no checks.
5395      */
readListInternal(@onNull List<? super T> outVal, int n, @Nullable ClassLoader loader, @Nullable Class<T> clazz)5396     private <T> void readListInternal(@NonNull List<? super T> outVal, int n,
5397             @Nullable ClassLoader loader, @Nullable Class<T> clazz) {
5398         while (n > 0) {
5399             T value = readValue(loader, clazz);
5400             //Log.d(TAG, "Unmarshalling value=" + value);
5401             outVal.add(value);
5402             n--;
5403         }
5404     }
5405 
5406     /**
5407      * @param clazz The type of the object expected or {@code null} for performing no checks.
5408      */
5409     @SuppressLint({"ConcreteCollection", "NullableCollection"})
5410     @Nullable
readArrayListInternal(@ullable ClassLoader loader, @Nullable Class<? extends T> clazz)5411     private <T> ArrayList<T> readArrayListInternal(@Nullable ClassLoader loader,
5412             @Nullable Class<? extends T> clazz) {
5413         int n = readInt();
5414         if (n < 0) {
5415             return null;
5416         }
5417         ArrayList<T> l = new ArrayList<>(n);
5418         readListInternal(l, n, loader, clazz);
5419         return l;
5420     }
5421 
5422     /**
5423      * The method is replaced by {@link #readArrayInternal(ClassLoader, Class)}, however
5424      * we are keeping this unused method here to allow unsupported app usages.
5425      */
readArrayInternal(@onNull Object[] outVal, int N, @Nullable ClassLoader loader)5426     private void readArrayInternal(@NonNull Object[] outVal, int N,
5427             @Nullable ClassLoader loader) {
5428         for (int i = 0; i < N; i++) {
5429             Object value = readValue(loader, /* clazz */ null);
5430             outVal[i] = value;
5431         }
5432     }
5433 
5434     /**
5435      * @param clazz The type of the object expected or {@code null} for performing no checks.
5436      */
5437     @SuppressWarnings("unchecked")
5438     @Nullable
readArrayInternal(@ullable ClassLoader loader, @Nullable Class<T> clazz)5439     private <T> T[] readArrayInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
5440         int n = readInt();
5441         if (n < 0) {
5442             return null;
5443         }
5444         T[] outVal = (T[]) ((clazz == null) ? new Object[n] : Array.newInstance(clazz, n));
5445 
5446         for (int i = 0; i < n; i++) {
5447             T value = readValue(loader, clazz);
5448             outVal[i] = value;
5449         }
5450         return outVal;
5451     }
5452 
5453     /**
5454      * The method is replaced by {@link #readSparseArray(ClassLoader, Class)}, however
5455      * we are keeping this unused method here to allow unsupported app usages.
5456      */
readSparseArrayInternal(@onNull SparseArray outVal, int N, @Nullable ClassLoader loader)5457     private void readSparseArrayInternal(@NonNull SparseArray outVal, int N,
5458             @Nullable ClassLoader loader) {
5459         while (N > 0) {
5460             int key = readInt();
5461             Object value = readValue(loader);
5462             outVal.append(key, value);
5463             N--;
5464         }
5465     }
5466 
5467     /**
5468      * @param clazz The type of the object expected or {@code null} for performing no checks.
5469      */
5470     @Nullable
readSparseArrayInternal(@ullable ClassLoader loader, @Nullable Class<? extends T> clazz)5471     private <T> SparseArray<T> readSparseArrayInternal(@Nullable ClassLoader loader,
5472             @Nullable Class<? extends T> clazz) {
5473         int n = readInt();
5474         if (n < 0) {
5475             return null;
5476         }
5477         SparseArray<T> outVal = new SparseArray<>(n);
5478 
5479         while (n > 0) {
5480             int key = readInt();
5481             T value = readValue(loader, clazz);
5482             outVal.append(key, value);
5483             n--;
5484         }
5485         return outVal;
5486     }
5487 
5488 
readSparseBooleanArrayInternal(@onNull SparseBooleanArray outVal, int N)5489     private void readSparseBooleanArrayInternal(@NonNull SparseBooleanArray outVal, int N) {
5490         while (N > 0) {
5491             int key = readInt();
5492             boolean value = this.readByte() == 1;
5493             //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
5494             outVal.append(key, value);
5495             N--;
5496         }
5497     }
5498 
readSparseIntArrayInternal(@onNull SparseIntArray outVal, int N)5499     private void readSparseIntArrayInternal(@NonNull SparseIntArray outVal, int N) {
5500         while (N > 0) {
5501             int key = readInt();
5502             int value = readInt();
5503             outVal.append(key, value);
5504             N--;
5505         }
5506     }
5507 
5508     /**
5509      * @hide For testing
5510      */
getOpenAshmemSize()5511     public long getOpenAshmemSize() {
5512         return nativeGetOpenAshmemSize(mNativePtr);
5513     }
5514 
valueTypeToString(int type)5515     private static String valueTypeToString(int type) {
5516         switch (type) {
5517             case VAL_NULL: return "VAL_NULL";
5518             case VAL_INTEGER: return "VAL_INTEGER";
5519             case VAL_MAP: return "VAL_MAP";
5520             case VAL_BUNDLE: return "VAL_BUNDLE";
5521             case VAL_PERSISTABLEBUNDLE: return "VAL_PERSISTABLEBUNDLE";
5522             case VAL_PARCELABLE: return "VAL_PARCELABLE";
5523             case VAL_SHORT: return "VAL_SHORT";
5524             case VAL_LONG: return "VAL_LONG";
5525             case VAL_FLOAT: return "VAL_FLOAT";
5526             case VAL_DOUBLE: return "VAL_DOUBLE";
5527             case VAL_BOOLEAN: return "VAL_BOOLEAN";
5528             case VAL_CHARSEQUENCE: return "VAL_CHARSEQUENCE";
5529             case VAL_LIST: return "VAL_LIST";
5530             case VAL_SPARSEARRAY: return "VAL_SPARSEARRAY";
5531             case VAL_BOOLEANARRAY: return "VAL_BOOLEANARRAY";
5532             case VAL_BYTEARRAY: return "VAL_BYTEARRAY";
5533             case VAL_STRINGARRAY: return "VAL_STRINGARRAY";
5534             case VAL_CHARSEQUENCEARRAY: return "VAL_CHARSEQUENCEARRAY";
5535             case VAL_IBINDER: return "VAL_IBINDER";
5536             case VAL_PARCELABLEARRAY: return "VAL_PARCELABLEARRAY";
5537             case VAL_INTARRAY: return "VAL_INTARRAY";
5538             case VAL_LONGARRAY: return "VAL_LONGARRAY";
5539             case VAL_BYTE: return "VAL_BYTE";
5540             case VAL_SIZE: return "VAL_SIZE";
5541             case VAL_SIZEF: return "VAL_SIZEF";
5542             case VAL_DOUBLEARRAY: return "VAL_DOUBLEARRAY";
5543             case VAL_CHAR: return "VAL_CHAR";
5544             case VAL_SHORTARRAY: return "VAL_SHORTARRAY";
5545             case VAL_CHARARRAY: return "VAL_CHARARRAY";
5546             case VAL_FLOATARRAY: return "VAL_FLOATARRAY";
5547             case VAL_OBJECTARRAY: return "VAL_OBJECTARRAY";
5548             case VAL_SERIALIZABLE: return "VAL_SERIALIZABLE";
5549             default: return "UNKNOWN(" + type + ")";
5550         }
5551     }
5552 }
5553