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