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