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