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