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