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( @uppressLintR) @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( @uppressLintR) @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