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 android.text.TextUtils;
20 import android.util.ArrayMap;
21 import android.util.Log;
22 import android.util.Size;
23 import android.util.SizeF;
24 import android.util.SparseArray;
25 import android.util.SparseBooleanArray;
26 
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.FileDescriptor;
30 import java.io.FileNotFoundException;
31 import java.io.IOException;
32 import java.io.ObjectInputStream;
33 import java.io.ObjectOutputStream;
34 import java.io.ObjectStreamClass;
35 import java.io.Serializable;
36 import java.lang.reflect.Field;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Set;
43 
44 /**
45  * Container for a message (data and object references) that can
46  * be sent through an IBinder.  A Parcel can contain both flattened data
47  * that will be unflattened on the other side of the IPC (using the various
48  * methods here for writing specific types, or the general
49  * {@link Parcelable} interface), and references to live {@link IBinder}
50  * objects that will result in the other side receiving a proxy IBinder
51  * connected with the original IBinder in the Parcel.
52  *
53  * <p class="note">Parcel is <strong>not</strong> a general-purpose
54  * serialization mechanism.  This class (and the corresponding
55  * {@link Parcelable} API for placing arbitrary objects into a Parcel) is
56  * designed as a high-performance IPC transport.  As such, it is not
57  * appropriate to place any Parcel data in to persistent storage: changes
58  * in the underlying implementation of any of the data in the Parcel can
59  * render older data unreadable.</p>
60  *
61  * <p>The bulk of the Parcel API revolves around reading and writing data
62  * of various types.  There are six major classes of such functions available.</p>
63  *
64  * <h3>Primitives</h3>
65  *
66  * <p>The most basic data functions are for writing and reading primitive
67  * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
68  * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
69  * {@link #readInt}, {@link #writeLong}, {@link #readLong},
70  * {@link #writeString}, {@link #readString}.  Most other
71  * data operations are built on top of these.  The given data is written and
72  * read using the endianess of the host CPU.</p>
73  *
74  * <h3>Primitive Arrays</h3>
75  *
76  * <p>There are a variety of methods for reading and writing raw arrays
77  * of primitive objects, which generally result in writing a 4-byte length
78  * followed by the primitive data items.  The methods for reading can either
79  * read the data into an existing array, or create and return a new array.
80  * These available types are:</p>
81  *
82  * <ul>
83  * <li> {@link #writeBooleanArray(boolean[])},
84  * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
85  * <li> {@link #writeByteArray(byte[])},
86  * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])},
87  * {@link #createByteArray()}
88  * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])},
89  * {@link #createCharArray()}
90  * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])},
91  * {@link #createDoubleArray()}
92  * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])},
93  * {@link #createFloatArray()}
94  * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])},
95  * {@link #createIntArray()}
96  * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])},
97  * {@link #createLongArray()}
98  * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])},
99  * {@link #createStringArray()}.
100  * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
101  * {@link #readSparseBooleanArray()}.
102  * </ul>
103  *
104  * <h3>Parcelables</h3>
105  *
106  * <p>The {@link Parcelable} protocol provides an extremely efficient (but
107  * low-level) protocol for objects to write and read themselves from Parcels.
108  * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
109  * and {@link #readParcelable(ClassLoader)} or
110  * {@link #writeParcelableArray} and
111  * {@link #readParcelableArray(ClassLoader)} to write or read.  These
112  * methods write both the class type and its data to the Parcel, allowing
113  * that class to be reconstructed from the appropriate class loader when
114  * later reading.</p>
115  *
116  * <p>There are also some methods that provide a more efficient way to work
117  * with Parcelables: {@link #writeTypedArray},
118  * {@link #writeTypedList(List)},
119  * {@link #readTypedArray} and {@link #readTypedList}.  These methods
120  * do not write the class information of the original object: instead, the
121  * caller of the read function must know what type to expect and pass in the
122  * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
123  * properly construct the new object and read its data.  (To more efficient
124  * write and read a single Parceable object, you can directly call
125  * {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
126  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
127  * yourself.)</p>
128  *
129  * <h3>Bundles</h3>
130  *
131  * <p>A special type-safe container, called {@link Bundle}, is available
132  * for key/value maps of heterogeneous values.  This has many optimizations
133  * for improved performance when reading and writing data, and its type-safe
134  * API avoids difficult to debug type errors when finally marshalling the
135  * data contents into a Parcel.  The methods to use are
136  * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
137  * {@link #readBundle(ClassLoader)}.
138  *
139  * <h3>Active Objects</h3>
140  *
141  * <p>An unusual feature of Parcel is the ability to read and write active
142  * objects.  For these objects the actual contents of the object is not
143  * written, rather a special token referencing the object is written.  When
144  * reading the object back from the Parcel, you do not get a new instance of
145  * the object, but rather a handle that operates on the exact same object that
146  * was originally written.  There are two forms of active objects available.</p>
147  *
148  * <p>{@link Binder} objects are a core facility of Android's general cross-process
149  * communication system.  The {@link IBinder} interface describes an abstract
150  * protocol with a Binder object.  Any such interface can be written in to
151  * a Parcel, and upon reading you will receive either the original object
152  * implementing that interface or a special proxy implementation
153  * that communicates calls back to the original object.  The methods to use are
154  * {@link #writeStrongBinder(IBinder)},
155  * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()},
156  * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])},
157  * {@link #createBinderArray()},
158  * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
159  * {@link #createBinderArrayList()}.</p>
160  *
161  * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
162  * can be written and {@link ParcelFileDescriptor} objects returned to operate
163  * on the original file descriptor.  The returned file descriptor is a dup
164  * of the original file descriptor: the object and fd is different, but
165  * operating on the same underlying file stream, with the same position, etc.
166  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
167  * {@link #readFileDescriptor()}.
168  *
169  * <h3>Untyped Containers</h3>
170  *
171  * <p>A final class of methods are for writing and reading standard Java
172  * containers of arbitrary types.  These all revolve around the
173  * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
174  * which define the types of objects allowed.  The container methods are
175  * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)},
176  * {@link #writeList(List)}, {@link #readList(List, ClassLoader)},
177  * {@link #readArrayList(ClassLoader)},
178  * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
179  * {@link #writeSparseArray(SparseArray)},
180  * {@link #readSparseArray(ClassLoader)}.
181  */
182 public final class Parcel {
183     private static final boolean DEBUG_RECYCLE = false;
184     private static final boolean DEBUG_ARRAY_MAP = false;
185     private static final String TAG = "Parcel";
186 
187     @SuppressWarnings({"UnusedDeclaration"})
188     private long mNativePtr; // used by native code
189 
190     /**
191      * Flag indicating if {@link #mNativePtr} was allocated by this object,
192      * indicating that we're responsible for its lifecycle.
193      */
194     private boolean mOwnsNativeParcelObject;
195 
196     private RuntimeException mStack;
197 
198     private static final int POOL_SIZE = 6;
199     private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE];
200     private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE];
201 
202     private static final int VAL_NULL = -1;
203     private static final int VAL_STRING = 0;
204     private static final int VAL_INTEGER = 1;
205     private static final int VAL_MAP = 2;
206     private static final int VAL_BUNDLE = 3;
207     private static final int VAL_PARCELABLE = 4;
208     private static final int VAL_SHORT = 5;
209     private static final int VAL_LONG = 6;
210     private static final int VAL_FLOAT = 7;
211     private static final int VAL_DOUBLE = 8;
212     private static final int VAL_BOOLEAN = 9;
213     private static final int VAL_CHARSEQUENCE = 10;
214     private static final int VAL_LIST  = 11;
215     private static final int VAL_SPARSEARRAY = 12;
216     private static final int VAL_BYTEARRAY = 13;
217     private static final int VAL_STRINGARRAY = 14;
218     private static final int VAL_IBINDER = 15;
219     private static final int VAL_PARCELABLEARRAY = 16;
220     private static final int VAL_OBJECTARRAY = 17;
221     private static final int VAL_INTARRAY = 18;
222     private static final int VAL_LONGARRAY = 19;
223     private static final int VAL_BYTE = 20;
224     private static final int VAL_SERIALIZABLE = 21;
225     private static final int VAL_SPARSEBOOLEANARRAY = 22;
226     private static final int VAL_BOOLEANARRAY = 23;
227     private static final int VAL_CHARSEQUENCEARRAY = 24;
228     private static final int VAL_PERSISTABLEBUNDLE = 25;
229     private static final int VAL_SIZE = 26;
230     private static final int VAL_SIZEF = 27;
231 
232     // The initial int32 in a Binder call's reply Parcel header:
233     private static final int EX_SECURITY = -1;
234     private static final int EX_BAD_PARCELABLE = -2;
235     private static final int EX_ILLEGAL_ARGUMENT = -3;
236     private static final int EX_NULL_POINTER = -4;
237     private static final int EX_ILLEGAL_STATE = -5;
238     private static final int EX_NETWORK_MAIN_THREAD = -6;
239     private static final int EX_UNSUPPORTED_OPERATION = -7;
240     private static final int EX_HAS_REPLY_HEADER = -128;  // special; see below
241 
nativeDataSize(long nativePtr)242     private static native int nativeDataSize(long nativePtr);
nativeDataAvail(long nativePtr)243     private static native int nativeDataAvail(long nativePtr);
nativeDataPosition(long nativePtr)244     private static native int nativeDataPosition(long nativePtr);
nativeDataCapacity(long nativePtr)245     private static native int nativeDataCapacity(long nativePtr);
nativeSetDataSize(long nativePtr, int size)246     private static native void nativeSetDataSize(long nativePtr, int size);
nativeSetDataPosition(long nativePtr, int pos)247     private static native void nativeSetDataPosition(long nativePtr, int pos);
nativeSetDataCapacity(long nativePtr, int size)248     private static native void nativeSetDataCapacity(long nativePtr, int size);
249 
nativePushAllowFds(long nativePtr, boolean allowFds)250     private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds);
nativeRestoreAllowFds(long nativePtr, boolean lastValue)251     private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue);
252 
nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len)253     private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len);
nativeWriteBlob(long nativePtr, byte[] b, int offset, int len)254     private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len);
nativeWriteInt(long nativePtr, int val)255     private static native void nativeWriteInt(long nativePtr, int val);
nativeWriteLong(long nativePtr, long val)256     private static native void nativeWriteLong(long nativePtr, long val);
nativeWriteFloat(long nativePtr, float val)257     private static native void nativeWriteFloat(long nativePtr, float val);
nativeWriteDouble(long nativePtr, double val)258     private static native void nativeWriteDouble(long nativePtr, double val);
nativeWriteString(long nativePtr, String val)259     private static native void nativeWriteString(long nativePtr, String val);
nativeWriteStrongBinder(long nativePtr, IBinder val)260     private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
nativeWriteFileDescriptor(long nativePtr, FileDescriptor val)261     private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
262 
nativeCreateByteArray(long nativePtr)263     private static native byte[] nativeCreateByteArray(long nativePtr);
nativeReadBlob(long nativePtr)264     private static native byte[] nativeReadBlob(long nativePtr);
nativeReadInt(long nativePtr)265     private static native int nativeReadInt(long nativePtr);
nativeReadLong(long nativePtr)266     private static native long nativeReadLong(long nativePtr);
nativeReadFloat(long nativePtr)267     private static native float nativeReadFloat(long nativePtr);
nativeReadDouble(long nativePtr)268     private static native double nativeReadDouble(long nativePtr);
nativeReadString(long nativePtr)269     private static native String nativeReadString(long nativePtr);
nativeReadStrongBinder(long nativePtr)270     private static native IBinder nativeReadStrongBinder(long nativePtr);
nativeReadFileDescriptor(long nativePtr)271     private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);
272 
nativeCreate()273     private static native long nativeCreate();
nativeFreeBuffer(long nativePtr)274     private static native void nativeFreeBuffer(long nativePtr);
nativeDestroy(long nativePtr)275     private static native void nativeDestroy(long nativePtr);
276 
nativeMarshall(long nativePtr)277     private static native byte[] nativeMarshall(long nativePtr);
nativeUnmarshall( long nativePtr, byte[] data, int offset, int length)278     private static native void nativeUnmarshall(
279             long nativePtr, byte[] data, int offset, int length);
nativeAppendFrom( long thisNativePtr, long otherNativePtr, int offset, int length)280     private static native void nativeAppendFrom(
281             long thisNativePtr, long otherNativePtr, int offset, int length);
nativeHasFileDescriptors(long nativePtr)282     private static native boolean nativeHasFileDescriptors(long nativePtr);
nativeWriteInterfaceToken(long nativePtr, String interfaceName)283     private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName);
nativeEnforceInterface(long nativePtr, String interfaceName)284     private static native void nativeEnforceInterface(long nativePtr, String interfaceName);
285 
286     public final static Parcelable.Creator<String> STRING_CREATOR
287              = new Parcelable.Creator<String>() {
288         public String createFromParcel(Parcel source) {
289             return source.readString();
290         }
291         public String[] newArray(int size) {
292             return new String[size];
293         }
294     };
295 
296     /**
297      * Retrieve a new Parcel object from the pool.
298      */
obtain()299     public static Parcel obtain() {
300         final Parcel[] pool = sOwnedPool;
301         synchronized (pool) {
302             Parcel p;
303             for (int i=0; i<POOL_SIZE; i++) {
304                 p = pool[i];
305                 if (p != null) {
306                     pool[i] = null;
307                     if (DEBUG_RECYCLE) {
308                         p.mStack = new RuntimeException();
309                     }
310                     return p;
311                 }
312             }
313         }
314         return new Parcel(0);
315     }
316 
317     /**
318      * Put a Parcel object back into the pool.  You must not touch
319      * the object after this call.
320      */
recycle()321     public final void recycle() {
322         if (DEBUG_RECYCLE) mStack = null;
323         freeBuffer();
324 
325         final Parcel[] pool;
326         if (mOwnsNativeParcelObject) {
327             pool = sOwnedPool;
328         } else {
329             mNativePtr = 0;
330             pool = sHolderPool;
331         }
332 
333         synchronized (pool) {
334             for (int i=0; i<POOL_SIZE; i++) {
335                 if (pool[i] == null) {
336                     pool[i] = this;
337                     return;
338                 }
339             }
340         }
341     }
342 
343     /** @hide */
getGlobalAllocSize()344     public static native long getGlobalAllocSize();
345 
346     /** @hide */
getGlobalAllocCount()347     public static native long getGlobalAllocCount();
348 
349     /**
350      * Returns the total amount of data contained in the parcel.
351      */
dataSize()352     public final int dataSize() {
353         return nativeDataSize(mNativePtr);
354     }
355 
356     /**
357      * Returns the amount of data remaining to be read from the
358      * parcel.  That is, {@link #dataSize}-{@link #dataPosition}.
359      */
dataAvail()360     public final int dataAvail() {
361         return nativeDataAvail(mNativePtr);
362     }
363 
364     /**
365      * Returns the current position in the parcel data.  Never
366      * more than {@link #dataSize}.
367      */
dataPosition()368     public final int dataPosition() {
369         return nativeDataPosition(mNativePtr);
370     }
371 
372     /**
373      * Returns the total amount of space in the parcel.  This is always
374      * >= {@link #dataSize}.  The difference between it and dataSize() is the
375      * amount of room left until the parcel needs to re-allocate its
376      * data buffer.
377      */
dataCapacity()378     public final int dataCapacity() {
379         return nativeDataCapacity(mNativePtr);
380     }
381 
382     /**
383      * Change the amount of data in the parcel.  Can be either smaller or
384      * larger than the current size.  If larger than the current capacity,
385      * more memory will be allocated.
386      *
387      * @param size The new number of bytes in the Parcel.
388      */
setDataSize(int size)389     public final void setDataSize(int size) {
390         nativeSetDataSize(mNativePtr, size);
391     }
392 
393     /**
394      * Move the current read/write position in the parcel.
395      * @param pos New offset in the parcel; must be between 0 and
396      * {@link #dataSize}.
397      */
setDataPosition(int pos)398     public final void setDataPosition(int pos) {
399         nativeSetDataPosition(mNativePtr, pos);
400     }
401 
402     /**
403      * Change the capacity (current available space) of the parcel.
404      *
405      * @param size The new capacity of the parcel, in bytes.  Can not be
406      * less than {@link #dataSize} -- that is, you can not drop existing data
407      * with this method.
408      */
setDataCapacity(int size)409     public final void setDataCapacity(int size) {
410         nativeSetDataCapacity(mNativePtr, size);
411     }
412 
413     /** @hide */
pushAllowFds(boolean allowFds)414     public final boolean pushAllowFds(boolean allowFds) {
415         return nativePushAllowFds(mNativePtr, allowFds);
416     }
417 
418     /** @hide */
restoreAllowFds(boolean lastValue)419     public final void restoreAllowFds(boolean lastValue) {
420         nativeRestoreAllowFds(mNativePtr, lastValue);
421     }
422 
423     /**
424      * Returns the raw bytes of the parcel.
425      *
426      * <p class="note">The data you retrieve here <strong>must not</strong>
427      * be placed in any kind of persistent storage (on local disk, across
428      * a network, etc).  For that, you should use standard serialization
429      * or another kind of general serialization mechanism.  The Parcel
430      * marshalled representation is highly optimized for local IPC, and as
431      * such does not attempt to maintain compatibility with data created
432      * in different versions of the platform.
433      */
marshall()434     public final byte[] marshall() {
435         return nativeMarshall(mNativePtr);
436     }
437 
438     /**
439      * Set the bytes in data to be the raw bytes of this Parcel.
440      */
unmarshall(byte[] data, int offset, int length)441     public final void unmarshall(byte[] data, int offset, int length) {
442         nativeUnmarshall(mNativePtr, data, offset, length);
443     }
444 
appendFrom(Parcel parcel, int offset, int length)445     public final void appendFrom(Parcel parcel, int offset, int length) {
446         nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
447     }
448 
449     /**
450      * Report whether the parcel contains any marshalled file descriptors.
451      */
hasFileDescriptors()452     public final boolean hasFileDescriptors() {
453         return nativeHasFileDescriptors(mNativePtr);
454     }
455 
456     /**
457      * Store or read an IBinder interface token in the parcel at the current
458      * {@link #dataPosition}.  This is used to validate that the marshalled
459      * transaction is intended for the target interface.
460      */
writeInterfaceToken(String interfaceName)461     public final void writeInterfaceToken(String interfaceName) {
462         nativeWriteInterfaceToken(mNativePtr, interfaceName);
463     }
464 
enforceInterface(String interfaceName)465     public final void enforceInterface(String interfaceName) {
466         nativeEnforceInterface(mNativePtr, interfaceName);
467     }
468 
469     /**
470      * Write a byte array into the parcel at the current {@link #dataPosition},
471      * growing {@link #dataCapacity} if needed.
472      * @param b Bytes to place into the parcel.
473      */
writeByteArray(byte[] b)474     public final void writeByteArray(byte[] b) {
475         writeByteArray(b, 0, (b != null) ? b.length : 0);
476     }
477 
478     /**
479      * Write a byte array into the parcel at the current {@link #dataPosition},
480      * growing {@link #dataCapacity} if needed.
481      * @param b Bytes to place into the parcel.
482      * @param offset Index of first byte to be written.
483      * @param len Number of bytes to write.
484      */
writeByteArray(byte[] b, int offset, int len)485     public final void writeByteArray(byte[] b, int offset, int len) {
486         if (b == null) {
487             writeInt(-1);
488             return;
489         }
490         Arrays.checkOffsetAndCount(b.length, offset, len);
491         nativeWriteByteArray(mNativePtr, b, offset, len);
492     }
493 
494     /**
495      * Write a blob of data into the parcel at the current {@link #dataPosition},
496      * growing {@link #dataCapacity} if needed.
497      * @param b Bytes to place into the parcel.
498      * {@hide}
499      * {@SystemApi}
500      */
writeBlob(byte[] b)501     public final void writeBlob(byte[] b) {
502         nativeWriteBlob(mNativePtr, b, 0, (b != null) ? b.length : 0);
503     }
504 
505     /**
506      * Write an integer value into the parcel at the current dataPosition(),
507      * growing dataCapacity() if needed.
508      */
writeInt(int val)509     public final void writeInt(int val) {
510         nativeWriteInt(mNativePtr, val);
511     }
512 
513     /**
514      * Write a long integer value into the parcel at the current dataPosition(),
515      * growing dataCapacity() if needed.
516      */
writeLong(long val)517     public final void writeLong(long val) {
518         nativeWriteLong(mNativePtr, val);
519     }
520 
521     /**
522      * Write a floating point value into the parcel at the current
523      * dataPosition(), growing dataCapacity() if needed.
524      */
writeFloat(float val)525     public final void writeFloat(float val) {
526         nativeWriteFloat(mNativePtr, val);
527     }
528 
529     /**
530      * Write a double precision floating point value into the parcel at the
531      * current dataPosition(), growing dataCapacity() if needed.
532      */
writeDouble(double val)533     public final void writeDouble(double val) {
534         nativeWriteDouble(mNativePtr, val);
535     }
536 
537     /**
538      * Write a string value into the parcel at the current dataPosition(),
539      * growing dataCapacity() if needed.
540      */
writeString(String val)541     public final void writeString(String val) {
542         nativeWriteString(mNativePtr, val);
543     }
544 
545     /**
546      * Write a CharSequence value into the parcel at the current dataPosition(),
547      * growing dataCapacity() if needed.
548      * @hide
549      */
writeCharSequence(CharSequence val)550     public final void writeCharSequence(CharSequence val) {
551         TextUtils.writeToParcel(val, this, 0);
552     }
553 
554     /**
555      * Write an object into the parcel at the current dataPosition(),
556      * growing dataCapacity() if needed.
557      */
writeStrongBinder(IBinder val)558     public final void writeStrongBinder(IBinder val) {
559         nativeWriteStrongBinder(mNativePtr, val);
560     }
561 
562     /**
563      * Write an object into the parcel at the current dataPosition(),
564      * growing dataCapacity() if needed.
565      */
writeStrongInterface(IInterface val)566     public final void writeStrongInterface(IInterface val) {
567         writeStrongBinder(val == null ? null : val.asBinder());
568     }
569 
570     /**
571      * Write a FileDescriptor into the parcel at the current dataPosition(),
572      * growing dataCapacity() if needed.
573      *
574      * <p class="caution">The file descriptor will not be closed, which may
575      * result in file descriptor leaks when objects are returned from Binder
576      * calls.  Use {@link ParcelFileDescriptor#writeToParcel} instead, which
577      * accepts contextual flags and will close the original file descriptor
578      * if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
579      */
writeFileDescriptor(FileDescriptor val)580     public final void writeFileDescriptor(FileDescriptor val) {
581         nativeWriteFileDescriptor(mNativePtr, val);
582     }
583 
584     /**
585      * Write a byte value into the parcel at the current dataPosition(),
586      * growing dataCapacity() if needed.
587      */
writeByte(byte val)588     public final void writeByte(byte val) {
589         writeInt(val);
590     }
591 
592     /**
593      * Please use {@link #writeBundle} instead.  Flattens a Map into the parcel
594      * at the current dataPosition(),
595      * growing dataCapacity() if needed.  The Map keys must be String objects.
596      * The Map values are written using {@link #writeValue} and must follow
597      * the specification there.
598      *
599      * <p>It is strongly recommended to use {@link #writeBundle} instead of
600      * this method, since the Bundle class provides a type-safe API that
601      * allows you to avoid mysterious type errors at the point of marshalling.
602      */
writeMap(Map val)603     public final void writeMap(Map val) {
604         writeMapInternal((Map<String, Object>) val);
605     }
606 
607     /**
608      * Flatten a Map into the parcel at the current dataPosition(),
609      * growing dataCapacity() if needed.  The Map keys must be String objects.
610      */
writeMapInternal(Map<String,Object> val)611     /* package */ void writeMapInternal(Map<String,Object> val) {
612         if (val == null) {
613             writeInt(-1);
614             return;
615         }
616         Set<Map.Entry<String,Object>> entries = val.entrySet();
617         writeInt(entries.size());
618         for (Map.Entry<String,Object> e : entries) {
619             writeValue(e.getKey());
620             writeValue(e.getValue());
621         }
622     }
623 
624     /**
625      * Flatten an ArrayMap into the parcel at the current dataPosition(),
626      * growing dataCapacity() if needed.  The Map keys must be String objects.
627      */
writeArrayMapInternal(ArrayMap<String, Object> val)628     /* package */ void writeArrayMapInternal(ArrayMap<String, Object> val) {
629         if (val == null) {
630             writeInt(-1);
631             return;
632         }
633         final int N = val.size();
634         writeInt(N);
635         if (DEBUG_ARRAY_MAP) {
636             RuntimeException here =  new RuntimeException("here");
637             here.fillInStackTrace();
638             Log.d(TAG, "Writing " + N + " ArrayMap entries", here);
639         }
640         int startPos;
641         for (int i=0; i<N; i++) {
642             if (DEBUG_ARRAY_MAP) startPos = dataPosition();
643             writeString(val.keyAt(i));
644             writeValue(val.valueAt(i));
645             if (DEBUG_ARRAY_MAP) Log.d(TAG, "  Write #" + i + " "
646                     + (dataPosition()-startPos) + " bytes: key=0x"
647                     + Integer.toHexString(val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0)
648                     + " " + val.keyAt(i));
649         }
650     }
651 
652     /**
653      * @hide For testing only.
654      */
writeArrayMap(ArrayMap<String, Object> val)655     public void writeArrayMap(ArrayMap<String, Object> val) {
656         writeArrayMapInternal(val);
657     }
658 
659     /**
660      * Flatten a Bundle into the parcel at the current dataPosition(),
661      * growing dataCapacity() if needed.
662      */
writeBundle(Bundle val)663     public final void writeBundle(Bundle val) {
664         if (val == null) {
665             writeInt(-1);
666             return;
667         }
668 
669         val.writeToParcel(this, 0);
670     }
671 
672     /**
673      * Flatten a PersistableBundle into the parcel at the current dataPosition(),
674      * growing dataCapacity() if needed.
675      */
writePersistableBundle(PersistableBundle val)676     public final void writePersistableBundle(PersistableBundle val) {
677         if (val == null) {
678             writeInt(-1);
679             return;
680         }
681 
682         val.writeToParcel(this, 0);
683     }
684 
685     /**
686      * Flatten a Size into the parcel at the current dataPosition(),
687      * growing dataCapacity() if needed.
688      */
writeSize(Size val)689     public final void writeSize(Size val) {
690         writeInt(val.getWidth());
691         writeInt(val.getHeight());
692     }
693 
694     /**
695      * Flatten a SizeF into the parcel at the current dataPosition(),
696      * growing dataCapacity() if needed.
697      */
writeSizeF(SizeF val)698     public final void writeSizeF(SizeF val) {
699         writeFloat(val.getWidth());
700         writeFloat(val.getHeight());
701     }
702 
703     /**
704      * Flatten a List into the parcel at the current dataPosition(), growing
705      * dataCapacity() if needed.  The List values are written using
706      * {@link #writeValue} and must follow the specification there.
707      */
writeList(List val)708     public final void writeList(List val) {
709         if (val == null) {
710             writeInt(-1);
711             return;
712         }
713         int N = val.size();
714         int i=0;
715         writeInt(N);
716         while (i < N) {
717             writeValue(val.get(i));
718             i++;
719         }
720     }
721 
722     /**
723      * Flatten an Object array into the parcel at the current dataPosition(),
724      * growing dataCapacity() if needed.  The array values are written using
725      * {@link #writeValue} and must follow the specification there.
726      */
writeArray(Object[] val)727     public final void writeArray(Object[] val) {
728         if (val == null) {
729             writeInt(-1);
730             return;
731         }
732         int N = val.length;
733         int i=0;
734         writeInt(N);
735         while (i < N) {
736             writeValue(val[i]);
737             i++;
738         }
739     }
740 
741     /**
742      * Flatten a generic SparseArray into the parcel at the current
743      * dataPosition(), growing dataCapacity() if needed.  The SparseArray
744      * values are written using {@link #writeValue} and must follow the
745      * specification there.
746      */
writeSparseArray(SparseArray<Object> val)747     public final void writeSparseArray(SparseArray<Object> val) {
748         if (val == null) {
749             writeInt(-1);
750             return;
751         }
752         int N = val.size();
753         writeInt(N);
754         int i=0;
755         while (i < N) {
756             writeInt(val.keyAt(i));
757             writeValue(val.valueAt(i));
758             i++;
759         }
760     }
761 
writeSparseBooleanArray(SparseBooleanArray val)762     public final void writeSparseBooleanArray(SparseBooleanArray val) {
763         if (val == null) {
764             writeInt(-1);
765             return;
766         }
767         int N = val.size();
768         writeInt(N);
769         int i=0;
770         while (i < N) {
771             writeInt(val.keyAt(i));
772             writeByte((byte)(val.valueAt(i) ? 1 : 0));
773             i++;
774         }
775     }
776 
writeBooleanArray(boolean[] val)777     public final void writeBooleanArray(boolean[] val) {
778         if (val != null) {
779             int N = val.length;
780             writeInt(N);
781             for (int i=0; i<N; i++) {
782                 writeInt(val[i] ? 1 : 0);
783             }
784         } else {
785             writeInt(-1);
786         }
787     }
788 
createBooleanArray()789     public final boolean[] createBooleanArray() {
790         int N = readInt();
791         // >>2 as a fast divide-by-4 works in the create*Array() functions
792         // because dataAvail() will never return a negative number.  4 is
793         // the size of a stored boolean in the stream.
794         if (N >= 0 && N <= (dataAvail() >> 2)) {
795             boolean[] val = new boolean[N];
796             for (int i=0; i<N; i++) {
797                 val[i] = readInt() != 0;
798             }
799             return val;
800         } else {
801             return null;
802         }
803     }
804 
readBooleanArray(boolean[] val)805     public final void readBooleanArray(boolean[] val) {
806         int N = readInt();
807         if (N == val.length) {
808             for (int i=0; i<N; i++) {
809                 val[i] = readInt() != 0;
810             }
811         } else {
812             throw new RuntimeException("bad array lengths");
813         }
814     }
815 
writeCharArray(char[] val)816     public final void writeCharArray(char[] val) {
817         if (val != null) {
818             int N = val.length;
819             writeInt(N);
820             for (int i=0; i<N; i++) {
821                 writeInt((int)val[i]);
822             }
823         } else {
824             writeInt(-1);
825         }
826     }
827 
createCharArray()828     public final char[] createCharArray() {
829         int N = readInt();
830         if (N >= 0 && N <= (dataAvail() >> 2)) {
831             char[] val = new char[N];
832             for (int i=0; i<N; i++) {
833                 val[i] = (char)readInt();
834             }
835             return val;
836         } else {
837             return null;
838         }
839     }
840 
readCharArray(char[] val)841     public final void readCharArray(char[] val) {
842         int N = readInt();
843         if (N == val.length) {
844             for (int i=0; i<N; i++) {
845                 val[i] = (char)readInt();
846             }
847         } else {
848             throw new RuntimeException("bad array lengths");
849         }
850     }
851 
writeIntArray(int[] val)852     public final void writeIntArray(int[] val) {
853         if (val != null) {
854             int N = val.length;
855             writeInt(N);
856             for (int i=0; i<N; i++) {
857                 writeInt(val[i]);
858             }
859         } else {
860             writeInt(-1);
861         }
862     }
863 
createIntArray()864     public final int[] createIntArray() {
865         int N = readInt();
866         if (N >= 0 && N <= (dataAvail() >> 2)) {
867             int[] val = new int[N];
868             for (int i=0; i<N; i++) {
869                 val[i] = readInt();
870             }
871             return val;
872         } else {
873             return null;
874         }
875     }
876 
readIntArray(int[] val)877     public final void readIntArray(int[] val) {
878         int N = readInt();
879         if (N == val.length) {
880             for (int i=0; i<N; i++) {
881                 val[i] = readInt();
882             }
883         } else {
884             throw new RuntimeException("bad array lengths");
885         }
886     }
887 
writeLongArray(long[] val)888     public final void writeLongArray(long[] val) {
889         if (val != null) {
890             int N = val.length;
891             writeInt(N);
892             for (int i=0; i<N; i++) {
893                 writeLong(val[i]);
894             }
895         } else {
896             writeInt(-1);
897         }
898     }
899 
createLongArray()900     public final long[] createLongArray() {
901         int N = readInt();
902         // >>3 because stored longs are 64 bits
903         if (N >= 0 && N <= (dataAvail() >> 3)) {
904             long[] val = new long[N];
905             for (int i=0; i<N; i++) {
906                 val[i] = readLong();
907             }
908             return val;
909         } else {
910             return null;
911         }
912     }
913 
readLongArray(long[] val)914     public final void readLongArray(long[] val) {
915         int N = readInt();
916         if (N == val.length) {
917             for (int i=0; i<N; i++) {
918                 val[i] = readLong();
919             }
920         } else {
921             throw new RuntimeException("bad array lengths");
922         }
923     }
924 
writeFloatArray(float[] val)925     public final void writeFloatArray(float[] val) {
926         if (val != null) {
927             int N = val.length;
928             writeInt(N);
929             for (int i=0; i<N; i++) {
930                 writeFloat(val[i]);
931             }
932         } else {
933             writeInt(-1);
934         }
935     }
936 
createFloatArray()937     public final float[] createFloatArray() {
938         int N = readInt();
939         // >>2 because stored floats are 4 bytes
940         if (N >= 0 && N <= (dataAvail() >> 2)) {
941             float[] val = new float[N];
942             for (int i=0; i<N; i++) {
943                 val[i] = readFloat();
944             }
945             return val;
946         } else {
947             return null;
948         }
949     }
950 
readFloatArray(float[] val)951     public final void readFloatArray(float[] val) {
952         int N = readInt();
953         if (N == val.length) {
954             for (int i=0; i<N; i++) {
955                 val[i] = readFloat();
956             }
957         } else {
958             throw new RuntimeException("bad array lengths");
959         }
960     }
961 
writeDoubleArray(double[] val)962     public final void writeDoubleArray(double[] val) {
963         if (val != null) {
964             int N = val.length;
965             writeInt(N);
966             for (int i=0; i<N; i++) {
967                 writeDouble(val[i]);
968             }
969         } else {
970             writeInt(-1);
971         }
972     }
973 
createDoubleArray()974     public final double[] createDoubleArray() {
975         int N = readInt();
976         // >>3 because stored doubles are 8 bytes
977         if (N >= 0 && N <= (dataAvail() >> 3)) {
978             double[] val = new double[N];
979             for (int i=0; i<N; i++) {
980                 val[i] = readDouble();
981             }
982             return val;
983         } else {
984             return null;
985         }
986     }
987 
readDoubleArray(double[] val)988     public final void readDoubleArray(double[] val) {
989         int N = readInt();
990         if (N == val.length) {
991             for (int i=0; i<N; i++) {
992                 val[i] = readDouble();
993             }
994         } else {
995             throw new RuntimeException("bad array lengths");
996         }
997     }
998 
writeStringArray(String[] val)999     public final void writeStringArray(String[] val) {
1000         if (val != null) {
1001             int N = val.length;
1002             writeInt(N);
1003             for (int i=0; i<N; i++) {
1004                 writeString(val[i]);
1005             }
1006         } else {
1007             writeInt(-1);
1008         }
1009     }
1010 
createStringArray()1011     public final String[] createStringArray() {
1012         int N = readInt();
1013         if (N >= 0) {
1014             String[] val = new String[N];
1015             for (int i=0; i<N; i++) {
1016                 val[i] = readString();
1017             }
1018             return val;
1019         } else {
1020             return null;
1021         }
1022     }
1023 
readStringArray(String[] val)1024     public final void readStringArray(String[] val) {
1025         int N = readInt();
1026         if (N == val.length) {
1027             for (int i=0; i<N; i++) {
1028                 val[i] = readString();
1029             }
1030         } else {
1031             throw new RuntimeException("bad array lengths");
1032         }
1033     }
1034 
writeBinderArray(IBinder[] val)1035     public final void writeBinderArray(IBinder[] val) {
1036         if (val != null) {
1037             int N = val.length;
1038             writeInt(N);
1039             for (int i=0; i<N; i++) {
1040                 writeStrongBinder(val[i]);
1041             }
1042         } else {
1043             writeInt(-1);
1044         }
1045     }
1046 
1047     /**
1048      * @hide
1049      */
writeCharSequenceArray(CharSequence[] val)1050     public final void writeCharSequenceArray(CharSequence[] val) {
1051         if (val != null) {
1052             int N = val.length;
1053             writeInt(N);
1054             for (int i=0; i<N; i++) {
1055                 writeCharSequence(val[i]);
1056             }
1057         } else {
1058             writeInt(-1);
1059         }
1060     }
1061 
createBinderArray()1062     public final IBinder[] createBinderArray() {
1063         int N = readInt();
1064         if (N >= 0) {
1065             IBinder[] val = new IBinder[N];
1066             for (int i=0; i<N; i++) {
1067                 val[i] = readStrongBinder();
1068             }
1069             return val;
1070         } else {
1071             return null;
1072         }
1073     }
1074 
readBinderArray(IBinder[] val)1075     public final void readBinderArray(IBinder[] val) {
1076         int N = readInt();
1077         if (N == val.length) {
1078             for (int i=0; i<N; i++) {
1079                 val[i] = readStrongBinder();
1080             }
1081         } else {
1082             throw new RuntimeException("bad array lengths");
1083         }
1084     }
1085 
1086     /**
1087      * Flatten a List containing a particular object type into the parcel, at
1088      * the current dataPosition() and growing dataCapacity() if needed.  The
1089      * type of the objects in the list must be one that implements Parcelable.
1090      * Unlike the generic writeList() method, however, only the raw data of the
1091      * objects is written and not their type, so you must use the corresponding
1092      * readTypedList() to unmarshall them.
1093      *
1094      * @param val The list of objects to be written.
1095      *
1096      * @see #createTypedArrayList
1097      * @see #readTypedList
1098      * @see Parcelable
1099      */
writeTypedList(List<T> val)1100     public final <T extends Parcelable> void writeTypedList(List<T> val) {
1101         if (val == null) {
1102             writeInt(-1);
1103             return;
1104         }
1105         int N = val.size();
1106         int i=0;
1107         writeInt(N);
1108         while (i < N) {
1109             T item = val.get(i);
1110             if (item != null) {
1111                 writeInt(1);
1112                 item.writeToParcel(this, 0);
1113             } else {
1114                 writeInt(0);
1115             }
1116             i++;
1117         }
1118     }
1119 
1120     /**
1121      * Flatten a List containing String objects into the parcel, at
1122      * the current dataPosition() and growing dataCapacity() if needed.  They
1123      * can later be retrieved with {@link #createStringArrayList} or
1124      * {@link #readStringList}.
1125      *
1126      * @param val The list of strings to be written.
1127      *
1128      * @see #createStringArrayList
1129      * @see #readStringList
1130      */
writeStringList(List<String> val)1131     public final void writeStringList(List<String> val) {
1132         if (val == null) {
1133             writeInt(-1);
1134             return;
1135         }
1136         int N = val.size();
1137         int i=0;
1138         writeInt(N);
1139         while (i < N) {
1140             writeString(val.get(i));
1141             i++;
1142         }
1143     }
1144 
1145     /**
1146      * Flatten a List containing IBinder objects into the parcel, at
1147      * the current dataPosition() and growing dataCapacity() if needed.  They
1148      * can later be retrieved with {@link #createBinderArrayList} or
1149      * {@link #readBinderList}.
1150      *
1151      * @param val The list of strings to be written.
1152      *
1153      * @see #createBinderArrayList
1154      * @see #readBinderList
1155      */
writeBinderList(List<IBinder> val)1156     public final void writeBinderList(List<IBinder> val) {
1157         if (val == null) {
1158             writeInt(-1);
1159             return;
1160         }
1161         int N = val.size();
1162         int i=0;
1163         writeInt(N);
1164         while (i < N) {
1165             writeStrongBinder(val.get(i));
1166             i++;
1167         }
1168     }
1169 
1170     /**
1171      * Flatten a heterogeneous array containing a particular object type into
1172      * the parcel, at
1173      * the current dataPosition() and growing dataCapacity() if needed.  The
1174      * type of the objects in the array must be one that implements Parcelable.
1175      * Unlike the {@link #writeParcelableArray} method, however, only the
1176      * raw data of the objects is written and not their type, so you must use
1177      * {@link #readTypedArray} with the correct corresponding
1178      * {@link Parcelable.Creator} implementation to unmarshall them.
1179      *
1180      * @param val The array of objects to be written.
1181      * @param parcelableFlags Contextual flags as per
1182      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
1183      *
1184      * @see #readTypedArray
1185      * @see #writeParcelableArray
1186      * @see Parcelable.Creator
1187      */
writeTypedArray(T[] val, int parcelableFlags)1188     public final <T extends Parcelable> void writeTypedArray(T[] val,
1189             int parcelableFlags) {
1190         if (val != null) {
1191             int N = val.length;
1192             writeInt(N);
1193             for (int i=0; i<N; i++) {
1194                 T item = val[i];
1195                 if (item != null) {
1196                     writeInt(1);
1197                     item.writeToParcel(this, parcelableFlags);
1198                 } else {
1199                     writeInt(0);
1200                 }
1201             }
1202         } else {
1203             writeInt(-1);
1204         }
1205     }
1206 
1207     /**
1208      * Flatten a generic object in to a parcel.  The given Object value may
1209      * currently be one of the following types:
1210      *
1211      * <ul>
1212      * <li> null
1213      * <li> String
1214      * <li> Byte
1215      * <li> Short
1216      * <li> Integer
1217      * <li> Long
1218      * <li> Float
1219      * <li> Double
1220      * <li> Boolean
1221      * <li> String[]
1222      * <li> boolean[]
1223      * <li> byte[]
1224      * <li> int[]
1225      * <li> long[]
1226      * <li> Object[] (supporting objects of the same type defined here).
1227      * <li> {@link Bundle}
1228      * <li> Map (as supported by {@link #writeMap}).
1229      * <li> Any object that implements the {@link Parcelable} protocol.
1230      * <li> Parcelable[]
1231      * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}).
1232      * <li> List (as supported by {@link #writeList}).
1233      * <li> {@link SparseArray} (as supported by {@link #writeSparseArray(SparseArray)}).
1234      * <li> {@link IBinder}
1235      * <li> Any object that implements Serializable (but see
1236      *      {@link #writeSerializable} for caveats).  Note that all of the
1237      *      previous types have relatively efficient implementations for
1238      *      writing to a Parcel; having to rely on the generic serialization
1239      *      approach is much less efficient and should be avoided whenever
1240      *      possible.
1241      * </ul>
1242      *
1243      * <p class="caution">{@link Parcelable} objects are written with
1244      * {@link Parcelable#writeToParcel} using contextual flags of 0.  When
1245      * serializing objects containing {@link ParcelFileDescriptor}s,
1246      * this may result in file descriptor leaks when they are returned from
1247      * Binder calls (where {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}
1248      * should be used).</p>
1249      */
writeValue(Object v)1250     public final void writeValue(Object v) {
1251         if (v == null) {
1252             writeInt(VAL_NULL);
1253         } else if (v instanceof String) {
1254             writeInt(VAL_STRING);
1255             writeString((String) v);
1256         } else if (v instanceof Integer) {
1257             writeInt(VAL_INTEGER);
1258             writeInt((Integer) v);
1259         } else if (v instanceof Map) {
1260             writeInt(VAL_MAP);
1261             writeMap((Map) v);
1262         } else if (v instanceof Bundle) {
1263             // Must be before Parcelable
1264             writeInt(VAL_BUNDLE);
1265             writeBundle((Bundle) v);
1266         } else if (v instanceof Parcelable) {
1267             writeInt(VAL_PARCELABLE);
1268             writeParcelable((Parcelable) v, 0);
1269         } else if (v instanceof Short) {
1270             writeInt(VAL_SHORT);
1271             writeInt(((Short) v).intValue());
1272         } else if (v instanceof Long) {
1273             writeInt(VAL_LONG);
1274             writeLong((Long) v);
1275         } else if (v instanceof Float) {
1276             writeInt(VAL_FLOAT);
1277             writeFloat((Float) v);
1278         } else if (v instanceof Double) {
1279             writeInt(VAL_DOUBLE);
1280             writeDouble((Double) v);
1281         } else if (v instanceof Boolean) {
1282             writeInt(VAL_BOOLEAN);
1283             writeInt((Boolean) v ? 1 : 0);
1284         } else if (v instanceof CharSequence) {
1285             // Must be after String
1286             writeInt(VAL_CHARSEQUENCE);
1287             writeCharSequence((CharSequence) v);
1288         } else if (v instanceof List) {
1289             writeInt(VAL_LIST);
1290             writeList((List) v);
1291         } else if (v instanceof SparseArray) {
1292             writeInt(VAL_SPARSEARRAY);
1293             writeSparseArray((SparseArray) v);
1294         } else if (v instanceof boolean[]) {
1295             writeInt(VAL_BOOLEANARRAY);
1296             writeBooleanArray((boolean[]) v);
1297         } else if (v instanceof byte[]) {
1298             writeInt(VAL_BYTEARRAY);
1299             writeByteArray((byte[]) v);
1300         } else if (v instanceof String[]) {
1301             writeInt(VAL_STRINGARRAY);
1302             writeStringArray((String[]) v);
1303         } else if (v instanceof CharSequence[]) {
1304             // Must be after String[] and before Object[]
1305             writeInt(VAL_CHARSEQUENCEARRAY);
1306             writeCharSequenceArray((CharSequence[]) v);
1307         } else if (v instanceof IBinder) {
1308             writeInt(VAL_IBINDER);
1309             writeStrongBinder((IBinder) v);
1310         } else if (v instanceof Parcelable[]) {
1311             writeInt(VAL_PARCELABLEARRAY);
1312             writeParcelableArray((Parcelable[]) v, 0);
1313         } else if (v instanceof int[]) {
1314             writeInt(VAL_INTARRAY);
1315             writeIntArray((int[]) v);
1316         } else if (v instanceof long[]) {
1317             writeInt(VAL_LONGARRAY);
1318             writeLongArray((long[]) v);
1319         } else if (v instanceof Byte) {
1320             writeInt(VAL_BYTE);
1321             writeInt((Byte) v);
1322         } else if (v instanceof PersistableBundle) {
1323             writeInt(VAL_PERSISTABLEBUNDLE);
1324             writePersistableBundle((PersistableBundle) v);
1325         } else if (v instanceof Size) {
1326             writeInt(VAL_SIZE);
1327             writeSize((Size) v);
1328         } else if (v instanceof SizeF) {
1329             writeInt(VAL_SIZEF);
1330             writeSizeF((SizeF) v);
1331         } else {
1332             Class<?> clazz = v.getClass();
1333             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
1334                 // Only pure Object[] are written here, Other arrays of non-primitive types are
1335                 // handled by serialization as this does not record the component type.
1336                 writeInt(VAL_OBJECTARRAY);
1337                 writeArray((Object[]) v);
1338             } else if (v instanceof Serializable) {
1339                 // Must be last
1340                 writeInt(VAL_SERIALIZABLE);
1341                 writeSerializable((Serializable) v);
1342             } else {
1343                 throw new RuntimeException("Parcel: unable to marshal value " + v);
1344             }
1345         }
1346     }
1347 
1348     /**
1349      * Flatten the name of the class of the Parcelable and its contents
1350      * into the parcel.
1351      *
1352      * @param p The Parcelable object to be written.
1353      * @param parcelableFlags Contextual flags as per
1354      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
1355      */
writeParcelable(Parcelable p, int parcelableFlags)1356     public final void writeParcelable(Parcelable p, int parcelableFlags) {
1357         if (p == null) {
1358             writeString(null);
1359             return;
1360         }
1361         String name = p.getClass().getName();
1362         writeString(name);
1363         p.writeToParcel(this, parcelableFlags);
1364     }
1365 
1366     /** @hide */
writeParcelableCreator(Parcelable p)1367     public final void writeParcelableCreator(Parcelable p) {
1368         String name = p.getClass().getName();
1369         writeString(name);
1370     }
1371 
1372     /**
1373      * Write a generic serializable object in to a Parcel.  It is strongly
1374      * recommended that this method be avoided, since the serialization
1375      * overhead is extremely large, and this approach will be much slower than
1376      * using the other approaches to writing data in to a Parcel.
1377      */
writeSerializable(Serializable s)1378     public final void writeSerializable(Serializable s) {
1379         if (s == null) {
1380             writeString(null);
1381             return;
1382         }
1383         String name = s.getClass().getName();
1384         writeString(name);
1385 
1386         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1387         try {
1388             ObjectOutputStream oos = new ObjectOutputStream(baos);
1389             oos.writeObject(s);
1390             oos.close();
1391 
1392             writeByteArray(baos.toByteArray());
1393         } catch (IOException ioe) {
1394             throw new RuntimeException("Parcelable encountered " +
1395                 "IOException writing serializable object (name = " + name +
1396                 ")", ioe);
1397         }
1398     }
1399 
1400     /**
1401      * Special function for writing an exception result at the header of
1402      * a parcel, to be used when returning an exception from a transaction.
1403      * Note that this currently only supports a few exception types; any other
1404      * exception will be re-thrown by this function as a RuntimeException
1405      * (to be caught by the system's last-resort exception handling when
1406      * dispatching a transaction).
1407      *
1408      * <p>The supported exception types are:
1409      * <ul>
1410      * <li>{@link BadParcelableException}
1411      * <li>{@link IllegalArgumentException}
1412      * <li>{@link IllegalStateException}
1413      * <li>{@link NullPointerException}
1414      * <li>{@link SecurityException}
1415      * <li>{@link NetworkOnMainThreadException}
1416      * </ul>
1417      *
1418      * @param e The Exception to be written.
1419      *
1420      * @see #writeNoException
1421      * @see #readException
1422      */
writeException(Exception e)1423     public final void writeException(Exception e) {
1424         int code = 0;
1425         if (e instanceof SecurityException) {
1426             code = EX_SECURITY;
1427         } else if (e instanceof BadParcelableException) {
1428             code = EX_BAD_PARCELABLE;
1429         } else if (e instanceof IllegalArgumentException) {
1430             code = EX_ILLEGAL_ARGUMENT;
1431         } else if (e instanceof NullPointerException) {
1432             code = EX_NULL_POINTER;
1433         } else if (e instanceof IllegalStateException) {
1434             code = EX_ILLEGAL_STATE;
1435         } else if (e instanceof NetworkOnMainThreadException) {
1436             code = EX_NETWORK_MAIN_THREAD;
1437         } else if (e instanceof UnsupportedOperationException) {
1438             code = EX_UNSUPPORTED_OPERATION;
1439         }
1440         writeInt(code);
1441         StrictMode.clearGatheredViolations();
1442         if (code == 0) {
1443             if (e instanceof RuntimeException) {
1444                 throw (RuntimeException) e;
1445             }
1446             throw new RuntimeException(e);
1447         }
1448         writeString(e.getMessage());
1449     }
1450 
1451     /**
1452      * Special function for writing information at the front of the Parcel
1453      * indicating that no exception occurred.
1454      *
1455      * @see #writeException
1456      * @see #readException
1457      */
writeNoException()1458     public final void writeNoException() {
1459         // Despite the name of this function ("write no exception"),
1460         // it should instead be thought of as "write the RPC response
1461         // header", but because this function name is written out by
1462         // the AIDL compiler, we're not going to rename it.
1463         //
1464         // The response header, in the non-exception case (see also
1465         // writeException above, also called by the AIDL compiler), is
1466         // either a 0 (the default case), or EX_HAS_REPLY_HEADER if
1467         // StrictMode has gathered up violations that have occurred
1468         // during a Binder call, in which case we write out the number
1469         // of violations and their details, serialized, before the
1470         // actual RPC respons data.  The receiving end of this is
1471         // readException(), below.
1472         if (StrictMode.hasGatheredViolations()) {
1473             writeInt(EX_HAS_REPLY_HEADER);
1474             final int sizePosition = dataPosition();
1475             writeInt(0);  // total size of fat header, to be filled in later
1476             StrictMode.writeGatheredViolationsToParcel(this);
1477             final int payloadPosition = dataPosition();
1478             setDataPosition(sizePosition);
1479             writeInt(payloadPosition - sizePosition);  // header size
1480             setDataPosition(payloadPosition);
1481         } else {
1482             writeInt(0);
1483         }
1484     }
1485 
1486     /**
1487      * Special function for reading an exception result from the header of
1488      * a parcel, to be used after receiving the result of a transaction.  This
1489      * will throw the exception for you if it had been written to the Parcel,
1490      * otherwise return and let you read the normal result data from the Parcel.
1491      *
1492      * @see #writeException
1493      * @see #writeNoException
1494      */
readException()1495     public final void readException() {
1496         int code = readExceptionCode();
1497         if (code != 0) {
1498             String msg = readString();
1499             readException(code, msg);
1500         }
1501     }
1502 
1503     /**
1504      * Parses the header of a Binder call's response Parcel and
1505      * returns the exception code.  Deals with lite or fat headers.
1506      * In the common successful case, this header is generally zero.
1507      * In less common cases, it's a small negative number and will be
1508      * followed by an error string.
1509      *
1510      * This exists purely for android.database.DatabaseUtils and
1511      * insulating it from having to handle fat headers as returned by
1512      * e.g. StrictMode-induced RPC responses.
1513      *
1514      * @hide
1515      */
readExceptionCode()1516     public final int readExceptionCode() {
1517         int code = readInt();
1518         if (code == EX_HAS_REPLY_HEADER) {
1519             int headerSize = readInt();
1520             if (headerSize == 0) {
1521                 Log.e(TAG, "Unexpected zero-sized Parcel reply header.");
1522             } else {
1523                 // Currently the only thing in the header is StrictMode stacks,
1524                 // but discussions around event/RPC tracing suggest we might
1525                 // put that here too.  If so, switch on sub-header tags here.
1526                 // But for now, just parse out the StrictMode stuff.
1527                 StrictMode.readAndHandleBinderCallViolations(this);
1528             }
1529             // And fat response headers are currently only used when
1530             // there are no exceptions, so return no error:
1531             return 0;
1532         }
1533         return code;
1534     }
1535 
1536     /**
1537      * Throw an exception with the given message. Not intended for use
1538      * outside the Parcel class.
1539      *
1540      * @param code Used to determine which exception class to throw.
1541      * @param msg The exception message.
1542      */
readException(int code, String msg)1543     public final void readException(int code, String msg) {
1544         switch (code) {
1545             case EX_SECURITY:
1546                 throw new SecurityException(msg);
1547             case EX_BAD_PARCELABLE:
1548                 throw new BadParcelableException(msg);
1549             case EX_ILLEGAL_ARGUMENT:
1550                 throw new IllegalArgumentException(msg);
1551             case EX_NULL_POINTER:
1552                 throw new NullPointerException(msg);
1553             case EX_ILLEGAL_STATE:
1554                 throw new IllegalStateException(msg);
1555             case EX_NETWORK_MAIN_THREAD:
1556                 throw new NetworkOnMainThreadException();
1557             case EX_UNSUPPORTED_OPERATION:
1558                 throw new UnsupportedOperationException(msg);
1559         }
1560         throw new RuntimeException("Unknown exception code: " + code
1561                 + " msg " + msg);
1562     }
1563 
1564     /**
1565      * Read an integer value from the parcel at the current dataPosition().
1566      */
readInt()1567     public final int readInt() {
1568         return nativeReadInt(mNativePtr);
1569     }
1570 
1571     /**
1572      * Read a long integer value from the parcel at the current dataPosition().
1573      */
readLong()1574     public final long readLong() {
1575         return nativeReadLong(mNativePtr);
1576     }
1577 
1578     /**
1579      * Read a floating point value from the parcel at the current
1580      * dataPosition().
1581      */
readFloat()1582     public final float readFloat() {
1583         return nativeReadFloat(mNativePtr);
1584     }
1585 
1586     /**
1587      * Read a double precision floating point value from the parcel at the
1588      * current dataPosition().
1589      */
readDouble()1590     public final double readDouble() {
1591         return nativeReadDouble(mNativePtr);
1592     }
1593 
1594     /**
1595      * Read a string value from the parcel at the current dataPosition().
1596      */
readString()1597     public final String readString() {
1598         return nativeReadString(mNativePtr);
1599     }
1600 
1601     /**
1602      * Read a CharSequence value from the parcel at the current dataPosition().
1603      * @hide
1604      */
readCharSequence()1605     public final CharSequence readCharSequence() {
1606         return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
1607     }
1608 
1609     /**
1610      * Read an object from the parcel at the current dataPosition().
1611      */
readStrongBinder()1612     public final IBinder readStrongBinder() {
1613         return nativeReadStrongBinder(mNativePtr);
1614     }
1615 
1616     /**
1617      * Read a FileDescriptor from the parcel at the current dataPosition().
1618      */
readFileDescriptor()1619     public final ParcelFileDescriptor readFileDescriptor() {
1620         FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
1621         return fd != null ? new ParcelFileDescriptor(fd) : null;
1622     }
1623 
1624     /** {@hide} */
readRawFileDescriptor()1625     public final FileDescriptor readRawFileDescriptor() {
1626         return nativeReadFileDescriptor(mNativePtr);
1627     }
1628 
openFileDescriptor(String file, int mode)1629     /*package*/ static native FileDescriptor openFileDescriptor(String file,
1630             int mode) throws FileNotFoundException;
dupFileDescriptor(FileDescriptor orig)1631     /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
1632             throws IOException;
closeFileDescriptor(FileDescriptor desc)1633     /*package*/ static native void closeFileDescriptor(FileDescriptor desc)
1634             throws IOException;
clearFileDescriptor(FileDescriptor desc)1635     /*package*/ static native void clearFileDescriptor(FileDescriptor desc);
1636 
1637     /**
1638      * Read a byte value from the parcel at the current dataPosition().
1639      */
readByte()1640     public final byte readByte() {
1641         return (byte)(readInt() & 0xff);
1642     }
1643 
1644     /**
1645      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
1646      * been written with {@link #writeBundle}.  Read into an existing Map object
1647      * from the parcel at the current dataPosition().
1648      */
readMap(Map outVal, ClassLoader loader)1649     public final void readMap(Map outVal, ClassLoader loader) {
1650         int N = readInt();
1651         readMapInternal(outVal, N, loader);
1652     }
1653 
1654     /**
1655      * Read into an existing List object from the parcel at the current
1656      * dataPosition(), using the given class loader to load any enclosed
1657      * Parcelables.  If it is null, the default class loader is used.
1658      */
readList(List outVal, ClassLoader loader)1659     public final void readList(List outVal, ClassLoader loader) {
1660         int N = readInt();
1661         readListInternal(outVal, N, loader);
1662     }
1663 
1664     /**
1665      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
1666      * been written with {@link #writeBundle}.  Read and return a new HashMap
1667      * object from the parcel at the current dataPosition(), using the given
1668      * class loader to load any enclosed Parcelables.  Returns null if
1669      * the previously written map object was null.
1670      */
readHashMap(ClassLoader loader)1671     public final HashMap readHashMap(ClassLoader loader)
1672     {
1673         int N = readInt();
1674         if (N < 0) {
1675             return null;
1676         }
1677         HashMap m = new HashMap(N);
1678         readMapInternal(m, N, loader);
1679         return m;
1680     }
1681 
1682     /**
1683      * Read and return a new Bundle object from the parcel at the current
1684      * dataPosition().  Returns null if the previously written Bundle object was
1685      * null.
1686      */
readBundle()1687     public final Bundle readBundle() {
1688         return readBundle(null);
1689     }
1690 
1691     /**
1692      * Read and return a new Bundle object from the parcel at the current
1693      * dataPosition(), using the given class loader to initialize the class
1694      * loader of the Bundle for later retrieval of Parcelable objects.
1695      * Returns null if the previously written Bundle object was null.
1696      */
readBundle(ClassLoader loader)1697     public final Bundle readBundle(ClassLoader loader) {
1698         int length = readInt();
1699         if (length < 0) {
1700             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
1701             return null;
1702         }
1703 
1704         final Bundle bundle = new Bundle(this, length);
1705         if (loader != null) {
1706             bundle.setClassLoader(loader);
1707         }
1708         return bundle;
1709     }
1710 
1711     /**
1712      * Read and return a new Bundle object from the parcel at the current
1713      * dataPosition().  Returns null if the previously written Bundle object was
1714      * null.
1715      */
readPersistableBundle()1716     public final PersistableBundle readPersistableBundle() {
1717         return readPersistableBundle(null);
1718     }
1719 
1720     /**
1721      * Read and return a new Bundle object from the parcel at the current
1722      * dataPosition(), using the given class loader to initialize the class
1723      * loader of the Bundle for later retrieval of Parcelable objects.
1724      * Returns null if the previously written Bundle object was null.
1725      */
readPersistableBundle(ClassLoader loader)1726     public final PersistableBundle readPersistableBundle(ClassLoader loader) {
1727         int length = readInt();
1728         if (length < 0) {
1729             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
1730             return null;
1731         }
1732 
1733         final PersistableBundle bundle = new PersistableBundle(this, length);
1734         if (loader != null) {
1735             bundle.setClassLoader(loader);
1736         }
1737         return bundle;
1738     }
1739 
1740     /**
1741      * Read a Size from the parcel at the current dataPosition().
1742      */
readSize()1743     public final Size readSize() {
1744         final int width = readInt();
1745         final int height = readInt();
1746         return new Size(width, height);
1747     }
1748 
1749     /**
1750      * Read a SizeF from the parcel at the current dataPosition().
1751      */
readSizeF()1752     public final SizeF readSizeF() {
1753         final float width = readFloat();
1754         final float height = readFloat();
1755         return new SizeF(width, height);
1756     }
1757 
1758     /**
1759      * Read and return a byte[] object from the parcel.
1760      */
createByteArray()1761     public final byte[] createByteArray() {
1762         return nativeCreateByteArray(mNativePtr);
1763     }
1764 
1765     /**
1766      * Read a byte[] object from the parcel and copy it into the
1767      * given byte array.
1768      */
readByteArray(byte[] val)1769     public final void readByteArray(byte[] val) {
1770         // TODO: make this a native method to avoid the extra copy.
1771         byte[] ba = createByteArray();
1772         if (ba.length == val.length) {
1773            System.arraycopy(ba, 0, val, 0, ba.length);
1774         } else {
1775             throw new RuntimeException("bad array lengths");
1776         }
1777     }
1778 
1779     /**
1780      * Read a blob of data from the parcel and return it as a byte array.
1781      * {@hide}
1782      * {@SystemApi}
1783      */
readBlob()1784     public final byte[] readBlob() {
1785         return nativeReadBlob(mNativePtr);
1786     }
1787 
1788     /**
1789      * Read and return a String[] object from the parcel.
1790      * {@hide}
1791      */
readStringArray()1792     public final String[] readStringArray() {
1793         String[] array = null;
1794 
1795         int length = readInt();
1796         if (length >= 0)
1797         {
1798             array = new String[length];
1799 
1800             for (int i = 0 ; i < length ; i++)
1801             {
1802                 array[i] = readString();
1803             }
1804         }
1805 
1806         return array;
1807     }
1808 
1809     /**
1810      * Read and return a CharSequence[] object from the parcel.
1811      * {@hide}
1812      */
readCharSequenceArray()1813     public final CharSequence[] readCharSequenceArray() {
1814         CharSequence[] array = null;
1815 
1816         int length = readInt();
1817         if (length >= 0)
1818         {
1819             array = new CharSequence[length];
1820 
1821             for (int i = 0 ; i < length ; i++)
1822             {
1823                 array[i] = readCharSequence();
1824             }
1825         }
1826 
1827         return array;
1828     }
1829 
1830     /**
1831      * Read and return a new ArrayList object from the parcel at the current
1832      * dataPosition().  Returns null if the previously written list object was
1833      * null.  The given class loader will be used to load any enclosed
1834      * Parcelables.
1835      */
readArrayList(ClassLoader loader)1836     public final ArrayList readArrayList(ClassLoader loader) {
1837         int N = readInt();
1838         if (N < 0) {
1839             return null;
1840         }
1841         ArrayList l = new ArrayList(N);
1842         readListInternal(l, N, loader);
1843         return l;
1844     }
1845 
1846     /**
1847      * Read and return a new Object array from the parcel at the current
1848      * dataPosition().  Returns null if the previously written array was
1849      * null.  The given class loader will be used to load any enclosed
1850      * Parcelables.
1851      */
readArray(ClassLoader loader)1852     public final Object[] readArray(ClassLoader loader) {
1853         int N = readInt();
1854         if (N < 0) {
1855             return null;
1856         }
1857         Object[] l = new Object[N];
1858         readArrayInternal(l, N, loader);
1859         return l;
1860     }
1861 
1862     /**
1863      * Read and return a new SparseArray object from the parcel at the current
1864      * dataPosition().  Returns null if the previously written list object was
1865      * null.  The given class loader will be used to load any enclosed
1866      * Parcelables.
1867      */
readSparseArray(ClassLoader loader)1868     public final SparseArray readSparseArray(ClassLoader loader) {
1869         int N = readInt();
1870         if (N < 0) {
1871             return null;
1872         }
1873         SparseArray sa = new SparseArray(N);
1874         readSparseArrayInternal(sa, N, loader);
1875         return sa;
1876     }
1877 
1878     /**
1879      * Read and return a new SparseBooleanArray object from the parcel at the current
1880      * dataPosition().  Returns null if the previously written list object was
1881      * null.
1882      */
readSparseBooleanArray()1883     public final SparseBooleanArray readSparseBooleanArray() {
1884         int N = readInt();
1885         if (N < 0) {
1886             return null;
1887         }
1888         SparseBooleanArray sa = new SparseBooleanArray(N);
1889         readSparseBooleanArrayInternal(sa, N);
1890         return sa;
1891     }
1892 
1893     /**
1894      * Read and return a new ArrayList containing a particular object type from
1895      * the parcel that was written with {@link #writeTypedList} at the
1896      * current dataPosition().  Returns null if the
1897      * previously written list object was null.  The list <em>must</em> have
1898      * previously been written via {@link #writeTypedList} with the same object
1899      * type.
1900      *
1901      * @return A newly created ArrayList containing objects with the same data
1902      *         as those that were previously written.
1903      *
1904      * @see #writeTypedList
1905      */
createTypedArrayList(Parcelable.Creator<T> c)1906     public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) {
1907         int N = readInt();
1908         if (N < 0) {
1909             return null;
1910         }
1911         ArrayList<T> l = new ArrayList<T>(N);
1912         while (N > 0) {
1913             if (readInt() != 0) {
1914                 l.add(c.createFromParcel(this));
1915             } else {
1916                 l.add(null);
1917             }
1918             N--;
1919         }
1920         return l;
1921     }
1922 
1923     /**
1924      * Read into the given List items containing a particular object type
1925      * that were written with {@link #writeTypedList} at the
1926      * current dataPosition().  The list <em>must</em> have
1927      * previously been written via {@link #writeTypedList} with the same object
1928      * type.
1929      *
1930      * @return A newly created ArrayList containing objects with the same data
1931      *         as those that were previously written.
1932      *
1933      * @see #writeTypedList
1934      */
readTypedList(List<T> list, Parcelable.Creator<T> c)1935     public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) {
1936         int M = list.size();
1937         int N = readInt();
1938         int i = 0;
1939         for (; i < M && i < N; i++) {
1940             if (readInt() != 0) {
1941                 list.set(i, c.createFromParcel(this));
1942             } else {
1943                 list.set(i, null);
1944             }
1945         }
1946         for (; i<N; i++) {
1947             if (readInt() != 0) {
1948                 list.add(c.createFromParcel(this));
1949             } else {
1950                 list.add(null);
1951             }
1952         }
1953         for (; i<M; i++) {
1954             list.remove(N);
1955         }
1956     }
1957 
1958     /**
1959      * Read and return a new ArrayList containing String objects from
1960      * the parcel that was written with {@link #writeStringList} at the
1961      * current dataPosition().  Returns null if the
1962      * previously written list object was null.
1963      *
1964      * @return A newly created ArrayList containing strings with the same data
1965      *         as those that were previously written.
1966      *
1967      * @see #writeStringList
1968      */
createStringArrayList()1969     public final ArrayList<String> createStringArrayList() {
1970         int N = readInt();
1971         if (N < 0) {
1972             return null;
1973         }
1974         ArrayList<String> l = new ArrayList<String>(N);
1975         while (N > 0) {
1976             l.add(readString());
1977             N--;
1978         }
1979         return l;
1980     }
1981 
1982     /**
1983      * Read and return a new ArrayList containing IBinder objects from
1984      * the parcel that was written with {@link #writeBinderList} at the
1985      * current dataPosition().  Returns null if the
1986      * previously written list object was null.
1987      *
1988      * @return A newly created ArrayList containing strings with the same data
1989      *         as those that were previously written.
1990      *
1991      * @see #writeBinderList
1992      */
createBinderArrayList()1993     public final ArrayList<IBinder> createBinderArrayList() {
1994         int N = readInt();
1995         if (N < 0) {
1996             return null;
1997         }
1998         ArrayList<IBinder> l = new ArrayList<IBinder>(N);
1999         while (N > 0) {
2000             l.add(readStrongBinder());
2001             N--;
2002         }
2003         return l;
2004     }
2005 
2006     /**
2007      * Read into the given List items String objects that were written with
2008      * {@link #writeStringList} at the current dataPosition().
2009      *
2010      * @return A newly created ArrayList containing strings with the same data
2011      *         as those that were previously written.
2012      *
2013      * @see #writeStringList
2014      */
readStringList(List<String> list)2015     public final void readStringList(List<String> list) {
2016         int M = list.size();
2017         int N = readInt();
2018         int i = 0;
2019         for (; i < M && i < N; i++) {
2020             list.set(i, readString());
2021         }
2022         for (; i<N; i++) {
2023             list.add(readString());
2024         }
2025         for (; i<M; i++) {
2026             list.remove(N);
2027         }
2028     }
2029 
2030     /**
2031      * Read into the given List items IBinder objects that were written with
2032      * {@link #writeBinderList} at the current dataPosition().
2033      *
2034      * @return A newly created ArrayList containing strings with the same data
2035      *         as those that were previously written.
2036      *
2037      * @see #writeBinderList
2038      */
readBinderList(List<IBinder> list)2039     public final void readBinderList(List<IBinder> list) {
2040         int M = list.size();
2041         int N = readInt();
2042         int i = 0;
2043         for (; i < M && i < N; i++) {
2044             list.set(i, readStrongBinder());
2045         }
2046         for (; i<N; i++) {
2047             list.add(readStrongBinder());
2048         }
2049         for (; i<M; i++) {
2050             list.remove(N);
2051         }
2052     }
2053 
2054     /**
2055      * Read and return a new array containing a particular object type from
2056      * the parcel at the current dataPosition().  Returns null if the
2057      * previously written array was null.  The array <em>must</em> have
2058      * previously been written via {@link #writeTypedArray} with the same
2059      * object type.
2060      *
2061      * @return A newly created array containing objects with the same data
2062      *         as those that were previously written.
2063      *
2064      * @see #writeTypedArray
2065      */
createTypedArray(Parcelable.Creator<T> c)2066     public final <T> T[] createTypedArray(Parcelable.Creator<T> c) {
2067         int N = readInt();
2068         if (N < 0) {
2069             return null;
2070         }
2071         T[] l = c.newArray(N);
2072         for (int i=0; i<N; i++) {
2073             if (readInt() != 0) {
2074                 l[i] = c.createFromParcel(this);
2075             }
2076         }
2077         return l;
2078     }
2079 
readTypedArray(T[] val, Parcelable.Creator<T> c)2080     public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) {
2081         int N = readInt();
2082         if (N == val.length) {
2083             for (int i=0; i<N; i++) {
2084                 if (readInt() != 0) {
2085                     val[i] = c.createFromParcel(this);
2086                 } else {
2087                     val[i] = null;
2088                 }
2089             }
2090         } else {
2091             throw new RuntimeException("bad array lengths");
2092         }
2093     }
2094 
2095     /**
2096      * @deprecated
2097      * @hide
2098      */
2099     @Deprecated
readTypedArray(Parcelable.Creator<T> c)2100     public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
2101         return createTypedArray(c);
2102     }
2103 
2104     /**
2105      * Write a heterogeneous array of Parcelable objects into the Parcel.
2106      * Each object in the array is written along with its class name, so
2107      * that the correct class can later be instantiated.  As a result, this
2108      * has significantly more overhead than {@link #writeTypedArray}, but will
2109      * correctly handle an array containing more than one type of object.
2110      *
2111      * @param value The array of objects to be written.
2112      * @param parcelableFlags Contextual flags as per
2113      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
2114      *
2115      * @see #writeTypedArray
2116      */
writeParcelableArray(T[] value, int parcelableFlags)2117     public final <T extends Parcelable> void writeParcelableArray(T[] value,
2118             int parcelableFlags) {
2119         if (value != null) {
2120             int N = value.length;
2121             writeInt(N);
2122             for (int i=0; i<N; i++) {
2123                 writeParcelable(value[i], parcelableFlags);
2124             }
2125         } else {
2126             writeInt(-1);
2127         }
2128     }
2129 
2130     /**
2131      * Read a typed object from a parcel.  The given class loader will be
2132      * used to load any enclosed Parcelables.  If it is null, the default class
2133      * loader will be used.
2134      */
readValue(ClassLoader loader)2135     public final Object readValue(ClassLoader loader) {
2136         int type = readInt();
2137 
2138         switch (type) {
2139         case VAL_NULL:
2140             return null;
2141 
2142         case VAL_STRING:
2143             return readString();
2144 
2145         case VAL_INTEGER:
2146             return readInt();
2147 
2148         case VAL_MAP:
2149             return readHashMap(loader);
2150 
2151         case VAL_PARCELABLE:
2152             return readParcelable(loader);
2153 
2154         case VAL_SHORT:
2155             return (short) readInt();
2156 
2157         case VAL_LONG:
2158             return readLong();
2159 
2160         case VAL_FLOAT:
2161             return readFloat();
2162 
2163         case VAL_DOUBLE:
2164             return readDouble();
2165 
2166         case VAL_BOOLEAN:
2167             return readInt() == 1;
2168 
2169         case VAL_CHARSEQUENCE:
2170             return readCharSequence();
2171 
2172         case VAL_LIST:
2173             return readArrayList(loader);
2174 
2175         case VAL_BOOLEANARRAY:
2176             return createBooleanArray();
2177 
2178         case VAL_BYTEARRAY:
2179             return createByteArray();
2180 
2181         case VAL_STRINGARRAY:
2182             return readStringArray();
2183 
2184         case VAL_CHARSEQUENCEARRAY:
2185             return readCharSequenceArray();
2186 
2187         case VAL_IBINDER:
2188             return readStrongBinder();
2189 
2190         case VAL_OBJECTARRAY:
2191             return readArray(loader);
2192 
2193         case VAL_INTARRAY:
2194             return createIntArray();
2195 
2196         case VAL_LONGARRAY:
2197             return createLongArray();
2198 
2199         case VAL_BYTE:
2200             return readByte();
2201 
2202         case VAL_SERIALIZABLE:
2203             return readSerializable(loader);
2204 
2205         case VAL_PARCELABLEARRAY:
2206             return readParcelableArray(loader);
2207 
2208         case VAL_SPARSEARRAY:
2209             return readSparseArray(loader);
2210 
2211         case VAL_SPARSEBOOLEANARRAY:
2212             return readSparseBooleanArray();
2213 
2214         case VAL_BUNDLE:
2215             return readBundle(loader); // loading will be deferred
2216 
2217         case VAL_PERSISTABLEBUNDLE:
2218             return readPersistableBundle(loader);
2219 
2220         case VAL_SIZE:
2221             return readSize();
2222 
2223         case VAL_SIZEF:
2224             return readSizeF();
2225 
2226         default:
2227             int off = dataPosition() - 4;
2228             throw new RuntimeException(
2229                 "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off);
2230         }
2231     }
2232 
2233     /**
2234      * Read and return a new Parcelable from the parcel.  The given class loader
2235      * will be used to load any enclosed Parcelables.  If it is null, the default
2236      * class loader will be used.
2237      * @param loader A ClassLoader from which to instantiate the Parcelable
2238      * object, or null for the default class loader.
2239      * @return Returns the newly created Parcelable, or null if a null
2240      * object has been written.
2241      * @throws BadParcelableException Throws BadParcelableException if there
2242      * was an error trying to instantiate the Parcelable.
2243      */
readParcelable(ClassLoader loader)2244     public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
2245         Parcelable.Creator<T> creator = readParcelableCreator(loader);
2246         if (creator == null) {
2247             return null;
2248         }
2249         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
2250             return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
2251         }
2252         return creator.createFromParcel(this);
2253     }
2254 
2255     /** @hide */
readCreator(Parcelable.Creator<T> creator, ClassLoader loader)2256     public final <T extends Parcelable> T readCreator(Parcelable.Creator<T> creator,
2257             ClassLoader loader) {
2258         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
2259             return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
2260         }
2261         return creator.createFromParcel(this);
2262     }
2263 
2264     /** @hide */
readParcelableCreator( ClassLoader loader)2265     public final <T extends Parcelable> Parcelable.Creator<T> readParcelableCreator(
2266             ClassLoader loader) {
2267         String name = readString();
2268         if (name == null) {
2269             return null;
2270         }
2271         Parcelable.Creator<T> creator;
2272         synchronized (mCreators) {
2273             HashMap<String,Parcelable.Creator> map = mCreators.get(loader);
2274             if (map == null) {
2275                 map = new HashMap<String,Parcelable.Creator>();
2276                 mCreators.put(loader, map);
2277             }
2278             creator = map.get(name);
2279             if (creator == null) {
2280                 try {
2281                     Class c = loader == null ?
2282                         Class.forName(name) : Class.forName(name, true, loader);
2283                     Field f = c.getField("CREATOR");
2284                     creator = (Parcelable.Creator)f.get(null);
2285                 }
2286                 catch (IllegalAccessException e) {
2287                     Log.e(TAG, "Illegal access when unmarshalling: "
2288                                         + name, e);
2289                     throw new BadParcelableException(
2290                             "IllegalAccessException when unmarshalling: " + name);
2291                 }
2292                 catch (ClassNotFoundException e) {
2293                     Log.e(TAG, "Class not found when unmarshalling: "
2294                                         + name, e);
2295                     throw new BadParcelableException(
2296                             "ClassNotFoundException when unmarshalling: " + name);
2297                 }
2298                 catch (ClassCastException e) {
2299                     throw new BadParcelableException("Parcelable protocol requires a "
2300                                         + "Parcelable.Creator object called "
2301                                         + " CREATOR on class " + name);
2302                 }
2303                 catch (NoSuchFieldException e) {
2304                     throw new BadParcelableException("Parcelable protocol requires a "
2305                                         + "Parcelable.Creator object called "
2306                                         + " CREATOR on class " + name);
2307                 }
2308                 catch (NullPointerException e) {
2309                     throw new BadParcelableException("Parcelable protocol requires "
2310                             + "the CREATOR object to be static on class " + name);
2311                 }
2312                 if (creator == null) {
2313                     throw new BadParcelableException("Parcelable protocol requires a "
2314                                         + "Parcelable.Creator object called "
2315                                         + " CREATOR on class " + name);
2316                 }
2317 
2318                 map.put(name, creator);
2319             }
2320         }
2321 
2322         return creator;
2323     }
2324 
2325     /**
2326      * Read and return a new Parcelable array from the parcel.
2327      * The given class loader will be used to load any enclosed
2328      * Parcelables.
2329      * @return the Parcelable array, or null if the array is null
2330      */
readParcelableArray(ClassLoader loader)2331     public final Parcelable[] readParcelableArray(ClassLoader loader) {
2332         int N = readInt();
2333         if (N < 0) {
2334             return null;
2335         }
2336         Parcelable[] p = new Parcelable[N];
2337         for (int i = 0; i < N; i++) {
2338             p[i] = (Parcelable) readParcelable(loader);
2339         }
2340         return p;
2341     }
2342 
2343     /**
2344      * Read and return a new Serializable object from the parcel.
2345      * @return the Serializable object, or null if the Serializable name
2346      * wasn't found in the parcel.
2347      */
readSerializable()2348     public final Serializable readSerializable() {
2349         return readSerializable(null);
2350     }
2351 
readSerializable(final ClassLoader loader)2352     private final Serializable readSerializable(final ClassLoader loader) {
2353         String name = readString();
2354         if (name == null) {
2355             // For some reason we were unable to read the name of the Serializable (either there
2356             // is nothing left in the Parcel to read, or the next value wasn't a String), so
2357             // return null, which indicates that the name wasn't found in the parcel.
2358             return null;
2359         }
2360 
2361         byte[] serializedData = createByteArray();
2362         ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
2363         try {
2364             ObjectInputStream ois = new ObjectInputStream(bais) {
2365                 @Override
2366                 protected Class<?> resolveClass(ObjectStreamClass osClass)
2367                         throws IOException, ClassNotFoundException {
2368                     // try the custom classloader if provided
2369                     if (loader != null) {
2370                         Class<?> c = Class.forName(osClass.getName(), false, loader);
2371                         if (c != null) {
2372                             return c;
2373                         }
2374                     }
2375                     return super.resolveClass(osClass);
2376                 }
2377             };
2378             return (Serializable) ois.readObject();
2379         } catch (IOException ioe) {
2380             throw new RuntimeException("Parcelable encountered " +
2381                 "IOException reading a Serializable object (name = " + name +
2382                 ")", ioe);
2383         } catch (ClassNotFoundException cnfe) {
2384             throw new RuntimeException("Parcelable encountered " +
2385                 "ClassNotFoundException reading a Serializable object (name = "
2386                 + name + ")", cnfe);
2387         }
2388     }
2389 
2390     // Cache of previously looked up CREATOR.createFromParcel() methods for
2391     // particular classes.  Keys are the names of the classes, values are
2392     // Method objects.
2393     private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>
2394         mCreators = new HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>();
2395 
2396     /** @hide for internal use only. */
obtain(int obj)2397     static protected final Parcel obtain(int obj) {
2398         throw new UnsupportedOperationException();
2399     }
2400 
2401     /** @hide */
obtain(long obj)2402     static protected final Parcel obtain(long obj) {
2403         final Parcel[] pool = sHolderPool;
2404         synchronized (pool) {
2405             Parcel p;
2406             for (int i=0; i<POOL_SIZE; i++) {
2407                 p = pool[i];
2408                 if (p != null) {
2409                     pool[i] = null;
2410                     if (DEBUG_RECYCLE) {
2411                         p.mStack = new RuntimeException();
2412                     }
2413                     p.init(obj);
2414                     return p;
2415                 }
2416             }
2417         }
2418         return new Parcel(obj);
2419     }
2420 
Parcel(long nativePtr)2421     private Parcel(long nativePtr) {
2422         if (DEBUG_RECYCLE) {
2423             mStack = new RuntimeException();
2424         }
2425         //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
2426         init(nativePtr);
2427     }
2428 
init(long nativePtr)2429     private void init(long nativePtr) {
2430         if (nativePtr != 0) {
2431             mNativePtr = nativePtr;
2432             mOwnsNativeParcelObject = false;
2433         } else {
2434             mNativePtr = nativeCreate();
2435             mOwnsNativeParcelObject = true;
2436         }
2437     }
2438 
freeBuffer()2439     private void freeBuffer() {
2440         if (mOwnsNativeParcelObject) {
2441             nativeFreeBuffer(mNativePtr);
2442         }
2443     }
2444 
destroy()2445     private void destroy() {
2446         if (mNativePtr != 0) {
2447             if (mOwnsNativeParcelObject) {
2448                 nativeDestroy(mNativePtr);
2449             }
2450             mNativePtr = 0;
2451         }
2452     }
2453 
2454     @Override
finalize()2455     protected void finalize() throws Throwable {
2456         if (DEBUG_RECYCLE) {
2457             if (mStack != null) {
2458                 Log.w(TAG, "Client did not call Parcel.recycle()", mStack);
2459             }
2460         }
2461         destroy();
2462     }
2463 
readMapInternal(Map outVal, int N, ClassLoader loader)2464     /* package */ void readMapInternal(Map outVal, int N,
2465         ClassLoader loader) {
2466         while (N > 0) {
2467             Object key = readValue(loader);
2468             Object value = readValue(loader);
2469             outVal.put(key, value);
2470             N--;
2471         }
2472     }
2473 
readArrayMapInternal(ArrayMap outVal, int N, ClassLoader loader)2474     /* package */ void readArrayMapInternal(ArrayMap outVal, int N,
2475         ClassLoader loader) {
2476         if (DEBUG_ARRAY_MAP) {
2477             RuntimeException here =  new RuntimeException("here");
2478             here.fillInStackTrace();
2479             Log.d(TAG, "Reading " + N + " ArrayMap entries", here);
2480         }
2481         int startPos;
2482         while (N > 0) {
2483             if (DEBUG_ARRAY_MAP) startPos = dataPosition();
2484             String key = readString();
2485             Object value = readValue(loader);
2486             if (DEBUG_ARRAY_MAP) Log.d(TAG, "  Read #" + (N-1) + " "
2487                     + (dataPosition()-startPos) + " bytes: key=0x"
2488                     + Integer.toHexString((key != null ? key.hashCode() : 0)) + " " + key);
2489             outVal.append(key, value);
2490             N--;
2491         }
2492         outVal.validate();
2493     }
2494 
readArrayMapSafelyInternal(ArrayMap outVal, int N, ClassLoader loader)2495     /* package */ void readArrayMapSafelyInternal(ArrayMap outVal, int N,
2496         ClassLoader loader) {
2497         if (DEBUG_ARRAY_MAP) {
2498             RuntimeException here =  new RuntimeException("here");
2499             here.fillInStackTrace();
2500             Log.d(TAG, "Reading safely " + N + " ArrayMap entries", here);
2501         }
2502         while (N > 0) {
2503             String key = readString();
2504             if (DEBUG_ARRAY_MAP) Log.d(TAG, "  Read safe #" + (N-1) + ": key=0x"
2505                     + (key != null ? key.hashCode() : 0) + " " + key);
2506             Object value = readValue(loader);
2507             outVal.put(key, value);
2508             N--;
2509         }
2510     }
2511 
2512     /**
2513      * @hide For testing only.
2514      */
readArrayMap(ArrayMap outVal, ClassLoader loader)2515     public void readArrayMap(ArrayMap outVal, ClassLoader loader) {
2516         final int N = readInt();
2517         if (N < 0) {
2518             return;
2519         }
2520         readArrayMapInternal(outVal, N, loader);
2521     }
2522 
readListInternal(List outVal, int N, ClassLoader loader)2523     private void readListInternal(List outVal, int N,
2524         ClassLoader loader) {
2525         while (N > 0) {
2526             Object value = readValue(loader);
2527             //Log.d(TAG, "Unmarshalling value=" + value);
2528             outVal.add(value);
2529             N--;
2530         }
2531     }
2532 
readArrayInternal(Object[] outVal, int N, ClassLoader loader)2533     private void readArrayInternal(Object[] outVal, int N,
2534         ClassLoader loader) {
2535         for (int i = 0; i < N; i++) {
2536             Object value = readValue(loader);
2537             //Log.d(TAG, "Unmarshalling value=" + value);
2538             outVal[i] = value;
2539         }
2540     }
2541 
readSparseArrayInternal(SparseArray outVal, int N, ClassLoader loader)2542     private void readSparseArrayInternal(SparseArray outVal, int N,
2543         ClassLoader loader) {
2544         while (N > 0) {
2545             int key = readInt();
2546             Object value = readValue(loader);
2547             //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
2548             outVal.append(key, value);
2549             N--;
2550         }
2551     }
2552 
2553 
readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N)2554     private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) {
2555         while (N > 0) {
2556             int key = readInt();
2557             boolean value = this.readByte() == 1;
2558             //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
2559             outVal.append(key, value);
2560             N--;
2561         }
2562     }
2563 }
2564