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