1 /* 2 * Copyright (C) 2016 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 17 package android.os; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.compat.annotation.UnsupportedAppUsage; 24 25 import dalvik.annotation.optimization.FastNative; 26 27 import libcore.util.NativeAllocationRegistry; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.util.ArrayList; 32 import java.util.Arrays; 33 34 /** @hide */ 35 @SystemApi 36 public class HwParcel { 37 private static final String TAG = "HwParcel"; 38 39 /** @hide */ 40 @IntDef(prefix = { "STATUS_" }, value = { 41 STATUS_SUCCESS, 42 }) 43 @Retention(RetentionPolicy.SOURCE) 44 public @interface Status {} 45 46 /** 47 * Success return error for a transaction. Written to parcels 48 * using writeStatus. 49 */ 50 public static final int STATUS_SUCCESS = 0; 51 52 private static final NativeAllocationRegistry sNativeRegistry; 53 54 @UnsupportedAppUsage HwParcel(boolean allocate)55 private HwParcel(boolean allocate) { 56 native_setup(allocate); 57 58 sNativeRegistry.registerNativeAllocation( 59 this, 60 mNativeContext); 61 } 62 63 /** 64 * Creates an initialized and empty parcel. 65 */ HwParcel()66 public HwParcel() { 67 native_setup(true /* allocate */); 68 69 sNativeRegistry.registerNativeAllocation( 70 this, 71 mNativeContext); 72 } 73 74 /** 75 * Writes an interface token into the parcel used to verify that 76 * a transaction has made it to the right type of interface. 77 * 78 * @param interfaceName fully qualified name of interface message 79 * is being sent to. 80 */ 81 @FastNative writeInterfaceToken(String interfaceName)82 public native final void writeInterfaceToken(String interfaceName); 83 /** 84 * Writes a boolean value to the end of the parcel. 85 * @param val to write 86 */ 87 @FastNative writeBool(boolean val)88 public native final void writeBool(boolean val); 89 /** 90 * Writes a byte value to the end of the parcel. 91 * @param val to write 92 */ 93 @FastNative writeInt8(byte val)94 public native final void writeInt8(byte val); 95 /** 96 * Writes a short value to the end of the parcel. 97 * @param val to write 98 */ 99 @FastNative writeInt16(short val)100 public native final void writeInt16(short val); 101 /** 102 * Writes a int value to the end of the parcel. 103 * @param val to write 104 */ 105 @FastNative writeInt32(int val)106 public native final void writeInt32(int val); 107 /** 108 * Writes a long value to the end of the parcel. 109 * @param val to write 110 */ 111 @FastNative writeInt64(long val)112 public native final void writeInt64(long val); 113 /** 114 * Writes a float value to the end of the parcel. 115 * @param val to write 116 */ 117 @FastNative writeFloat(float val)118 public native final void writeFloat(float val); 119 /** 120 * Writes a double value to the end of the parcel. 121 * @param val to write 122 */ 123 @FastNative writeDouble(double val)124 public native final void writeDouble(double val); 125 /** 126 * Writes a String value to the end of the parcel. 127 * 128 * Note, this will be converted to UTF-8 when it is written. 129 * 130 * @param val to write 131 */ 132 @FastNative writeString(String val)133 public native final void writeString(String val); 134 /** 135 * Writes a native handle (without duplicating the underlying 136 * file descriptors) to the end of the parcel. 137 * 138 * @param val to write 139 */ 140 @FastNative writeNativeHandle(@ullable NativeHandle val)141 public native final void writeNativeHandle(@Nullable NativeHandle val); 142 143 /** 144 * Writes an array of boolean values to the end of the parcel. 145 * @param val to write 146 */ 147 @FastNative writeBoolVector(boolean[] val)148 private native final void writeBoolVector(boolean[] val); 149 /** 150 * Writes an array of byte values to the end of the parcel. 151 * @param val to write 152 */ 153 @FastNative writeInt8Vector(byte[] val)154 private native final void writeInt8Vector(byte[] val); 155 /** 156 * Writes an array of short values to the end of the parcel. 157 * @param val to write 158 */ 159 @FastNative writeInt16Vector(short[] val)160 private native final void writeInt16Vector(short[] val); 161 /** 162 * Writes an array of int values to the end of the parcel. 163 * @param val to write 164 */ 165 @FastNative writeInt32Vector(int[] val)166 private native final void writeInt32Vector(int[] val); 167 /** 168 * Writes an array of long values to the end of the parcel. 169 * @param val to write 170 */ 171 @FastNative writeInt64Vector(long[] val)172 private native final void writeInt64Vector(long[] val); 173 /** 174 * Writes an array of float values to the end of the parcel. 175 * @param val to write 176 */ 177 @FastNative writeFloatVector(float[] val)178 private native final void writeFloatVector(float[] val); 179 /** 180 * Writes an array of double values to the end of the parcel. 181 * @param val to write 182 */ 183 @FastNative writeDoubleVector(double[] val)184 private native final void writeDoubleVector(double[] val); 185 /** 186 * Writes an array of String values to the end of the parcel. 187 * 188 * Note, these will be converted to UTF-8 as they are written. 189 * 190 * @param val to write 191 */ 192 @FastNative writeStringVector(String[] val)193 private native final void writeStringVector(String[] val); 194 /** 195 * Writes an array of native handles to the end of the parcel. 196 * 197 * Individual elements may be null but not the whole array. 198 * 199 * @param val array of {@link NativeHandle} objects to write 200 */ 201 @FastNative writeNativeHandleVector(NativeHandle[] val)202 private native final void writeNativeHandleVector(NativeHandle[] val); 203 204 /** 205 * Helper method to write a list of Booleans to val. 206 * @param val list to write 207 */ writeBoolVector(ArrayList<Boolean> val)208 public final void writeBoolVector(ArrayList<Boolean> val) { 209 final int n = val.size(); 210 boolean[] array = new boolean[n]; 211 for (int i = 0; i < n; ++i) { 212 array[i] = val.get(i); 213 } 214 215 writeBoolVector(array); 216 } 217 218 /** 219 * Helper method to write a list of Booleans to the end of the parcel. 220 * @param val list to write 221 */ writeInt8Vector(ArrayList<Byte> val)222 public final void writeInt8Vector(ArrayList<Byte> val) { 223 final int n = val.size(); 224 byte[] array = new byte[n]; 225 for (int i = 0; i < n; ++i) { 226 array[i] = val.get(i); 227 } 228 229 writeInt8Vector(array); 230 } 231 232 /** 233 * Helper method to write a list of Shorts to the end of the parcel. 234 * @param val list to write 235 */ writeInt16Vector(ArrayList<Short> val)236 public final void writeInt16Vector(ArrayList<Short> val) { 237 final int n = val.size(); 238 short[] array = new short[n]; 239 for (int i = 0; i < n; ++i) { 240 array[i] = val.get(i); 241 } 242 243 writeInt16Vector(array); 244 } 245 246 /** 247 * Helper method to write a list of Integers to the end of the parcel. 248 * @param val list to write 249 */ writeInt32Vector(ArrayList<Integer> val)250 public final void writeInt32Vector(ArrayList<Integer> val) { 251 final int n = val.size(); 252 int[] array = new int[n]; 253 for (int i = 0; i < n; ++i) { 254 array[i] = val.get(i); 255 } 256 257 writeInt32Vector(array); 258 } 259 260 /** 261 * Helper method to write a list of Longs to the end of the parcel. 262 * @param val list to write 263 */ writeInt64Vector(ArrayList<Long> val)264 public final void writeInt64Vector(ArrayList<Long> val) { 265 final int n = val.size(); 266 long[] array = new long[n]; 267 for (int i = 0; i < n; ++i) { 268 array[i] = val.get(i); 269 } 270 271 writeInt64Vector(array); 272 } 273 274 /** 275 * Helper method to write a list of Floats to the end of the parcel. 276 * @param val list to write 277 */ writeFloatVector(ArrayList<Float> val)278 public final void writeFloatVector(ArrayList<Float> val) { 279 final int n = val.size(); 280 float[] array = new float[n]; 281 for (int i = 0; i < n; ++i) { 282 array[i] = val.get(i); 283 } 284 285 writeFloatVector(array); 286 } 287 288 /** 289 * Helper method to write a list of Doubles to the end of the parcel. 290 * @param val list to write 291 */ writeDoubleVector(ArrayList<Double> val)292 public final void writeDoubleVector(ArrayList<Double> val) { 293 final int n = val.size(); 294 double[] array = new double[n]; 295 for (int i = 0; i < n; ++i) { 296 array[i] = val.get(i); 297 } 298 299 writeDoubleVector(array); 300 } 301 302 /** 303 * Helper method to write a list of Strings to the end of the parcel. 304 * @param val list to write 305 */ writeStringVector(ArrayList<String> val)306 public final void writeStringVector(ArrayList<String> val) { 307 writeStringVector(val.toArray(new String[val.size()])); 308 } 309 310 /** 311 * Helper method to write a list of native handles to the end of the parcel. 312 * @param val list of {@link NativeHandle} objects to write 313 */ writeNativeHandleVector(@onNull ArrayList<NativeHandle> val)314 public final void writeNativeHandleVector(@NonNull ArrayList<NativeHandle> val) { 315 writeNativeHandleVector(val.toArray(new NativeHandle[val.size()])); 316 } 317 318 /** 319 * Write a hwbinder object to the end of the parcel. 320 * @param binder value to write 321 */ 322 @FastNative writeStrongBinder(IHwBinder binder)323 public native final void writeStrongBinder(IHwBinder binder); 324 325 /** 326 * Write a HidlMemory object (without duplicating the underlying file descriptors) to the end 327 * of the parcel. 328 * 329 * @param memory value to write 330 */ 331 @FastNative writeHidlMemory(@onNull HidlMemory memory)332 public native final void writeHidlMemory(@NonNull HidlMemory memory); 333 334 /** 335 * Checks to make sure that the interface name matches the name written by the parcel 336 * sender by writeInterfaceToken 337 * 338 * @throws SecurityException interface doesn't match 339 */ enforceInterface(String interfaceName)340 public native final void enforceInterface(String interfaceName); 341 342 /** 343 * Reads a boolean value from the current location in the parcel. 344 * @return value parsed from the parcel 345 * @throws IllegalArgumentException if the parcel has no more data 346 */ 347 @FastNative readBool()348 public native final boolean readBool(); 349 /** 350 * Reads a byte value from the current location in the parcel. 351 * @return value parsed from the parcel 352 * @throws IllegalArgumentException if the parcel has no more data 353 */ 354 @FastNative readInt8()355 public native final byte readInt8(); 356 /** 357 * Reads a short value from the current location in the parcel. 358 * @return value parsed from the parcel 359 * @throws IllegalArgumentException if the parcel has no more data 360 */ 361 @FastNative readInt16()362 public native final short readInt16(); 363 /** 364 * Reads a int value from the current location in the parcel. 365 * @return value parsed from the parcel 366 * @throws IllegalArgumentException if the parcel has no more data 367 */ 368 @FastNative readInt32()369 public native final int readInt32(); 370 /** 371 * Reads a long value from the current location in the parcel. 372 * @return value parsed from the parcel 373 * @throws IllegalArgumentException if the parcel has no more data 374 */ 375 @FastNative readInt64()376 public native final long readInt64(); 377 /** 378 * Reads a float value from the current location in the parcel. 379 * @return value parsed from the parcel 380 * @throws IllegalArgumentException if the parcel has no more data 381 */ 382 @FastNative readFloat()383 public native final float readFloat(); 384 /** 385 * Reads a double value from the current location in the parcel. 386 * @return value parsed from the parcel 387 * @throws IllegalArgumentException if the parcel has no more data 388 */ 389 @FastNative readDouble()390 public native final double readDouble(); 391 /** 392 * Reads a String value from the current location in the parcel. 393 * @return value parsed from the parcel 394 * @throws IllegalArgumentException if the parcel has no more data 395 */ 396 @FastNative readString()397 public native final String readString(); 398 /** 399 * Reads a native handle (without duplicating the underlying file 400 * descriptors) from the parcel. These file descriptors will only 401 * be open for the duration that the binder window is open. If they 402 * are needed further, you must call {@link NativeHandle#dup()}. 403 * 404 * @return a {@link NativeHandle} instance parsed from the parcel 405 * @throws IllegalArgumentException if the parcel has no more data 406 */ 407 @FastNative readNativeHandle()408 public native final @Nullable NativeHandle readNativeHandle(); 409 /** 410 * Reads an embedded native handle (without duplicating the underlying 411 * file descriptors) from the parcel. These file descriptors will only 412 * be open for the duration that the binder window is open. If they 413 * are needed further, you must call {@link NativeHandle#dup()}. You 414 * do not need to call close on the NativeHandle returned from this. 415 * 416 * @param parentHandle handle from which to read the embedded object 417 * @param offset offset into parent 418 * @return a {@link NativeHandle} instance parsed from the parcel 419 * @throws IllegalArgumentException if the parcel has no more data 420 */ 421 @FastNative readEmbeddedNativeHandle( long parentHandle, long offset)422 public native final @Nullable NativeHandle readEmbeddedNativeHandle( 423 long parentHandle, long offset); 424 425 /** 426 * Reads an array of boolean values from the parcel. 427 * @return array of parsed values 428 * @throws IllegalArgumentException if the parcel has no more data 429 */ 430 @FastNative readBoolVectorAsArray()431 private native final boolean[] readBoolVectorAsArray(); 432 /** 433 * Reads an array of byte values from the parcel. 434 * @return array of parsed values 435 * @throws IllegalArgumentException if the parcel has no more data 436 */ 437 @FastNative readInt8VectorAsArray()438 private native final byte[] readInt8VectorAsArray(); 439 /** 440 * Reads an array of short values from the parcel. 441 * @return array of parsed values 442 * @throws IllegalArgumentException if the parcel has no more data 443 */ 444 @FastNative readInt16VectorAsArray()445 private native final short[] readInt16VectorAsArray(); 446 /** 447 * Reads an array of int values from the parcel. 448 * @return array of parsed values 449 * @throws IllegalArgumentException if the parcel has no more data 450 */ 451 @FastNative readInt32VectorAsArray()452 private native final int[] readInt32VectorAsArray(); 453 /** 454 * Reads an array of long values from the parcel. 455 * @return array of parsed values 456 * @throws IllegalArgumentException if the parcel has no more data 457 */ 458 @FastNative readInt64VectorAsArray()459 private native final long[] readInt64VectorAsArray(); 460 /** 461 * Reads an array of float values from the parcel. 462 * @return array of parsed values 463 * @throws IllegalArgumentException if the parcel has no more data 464 */ 465 @FastNative readFloatVectorAsArray()466 private native final float[] readFloatVectorAsArray(); 467 /** 468 * Reads an array of double values from the parcel. 469 * @return array of parsed values 470 * @throws IllegalArgumentException if the parcel has no more data 471 */ 472 @FastNative readDoubleVectorAsArray()473 private native final double[] readDoubleVectorAsArray(); 474 /** 475 * Reads an array of String values from the parcel. 476 * @return array of parsed values 477 * @throws IllegalArgumentException if the parcel has no more data 478 */ 479 @FastNative readStringVectorAsArray()480 private native final String[] readStringVectorAsArray(); 481 /** 482 * Reads an array of native handles from the parcel. 483 * @return array of {@link NativeHandle} objects 484 * @throws IllegalArgumentException if the parcel has no more data 485 */ 486 @FastNative readNativeHandleAsArray()487 private native final NativeHandle[] readNativeHandleAsArray(); 488 489 /** 490 * Convenience method to read a Boolean vector as an ArrayList. 491 * @return array of parsed values. 492 * @throws IllegalArgumentException if the parcel has no more data 493 */ readBoolVector()494 public final ArrayList<Boolean> readBoolVector() { 495 Boolean[] array = HwBlob.wrapArray(readBoolVectorAsArray()); 496 497 return new ArrayList<Boolean>(Arrays.asList(array)); 498 } 499 500 /** 501 * Convenience method to read a Byte vector as an ArrayList. 502 * @return array of parsed values. 503 * @throws IllegalArgumentException if the parcel has no more data 504 */ readInt8Vector()505 public final ArrayList<Byte> readInt8Vector() { 506 Byte[] array = HwBlob.wrapArray(readInt8VectorAsArray()); 507 508 return new ArrayList<Byte>(Arrays.asList(array)); 509 } 510 511 /** 512 * Convenience method to read a Short vector as an ArrayList. 513 * @return array of parsed values. 514 * @throws IllegalArgumentException if the parcel has no more data 515 */ readInt16Vector()516 public final ArrayList<Short> readInt16Vector() { 517 Short[] array = HwBlob.wrapArray(readInt16VectorAsArray()); 518 519 return new ArrayList<Short>(Arrays.asList(array)); 520 } 521 522 /** 523 * Convenience method to read a Integer vector as an ArrayList. 524 * @return array of parsed values. 525 * @throws IllegalArgumentException if the parcel has no more data 526 */ readInt32Vector()527 public final ArrayList<Integer> readInt32Vector() { 528 Integer[] array = HwBlob.wrapArray(readInt32VectorAsArray()); 529 530 return new ArrayList<Integer>(Arrays.asList(array)); 531 } 532 533 /** 534 * Convenience method to read a Long vector as an ArrayList. 535 * @return array of parsed values. 536 * @throws IllegalArgumentException if the parcel has no more data 537 */ readInt64Vector()538 public final ArrayList<Long> readInt64Vector() { 539 Long[] array = HwBlob.wrapArray(readInt64VectorAsArray()); 540 541 return new ArrayList<Long>(Arrays.asList(array)); 542 } 543 544 /** 545 * Convenience method to read a Float vector as an ArrayList. 546 * @return array of parsed values. 547 * @throws IllegalArgumentException if the parcel has no more data 548 */ readFloatVector()549 public final ArrayList<Float> readFloatVector() { 550 Float[] array = HwBlob.wrapArray(readFloatVectorAsArray()); 551 552 return new ArrayList<Float>(Arrays.asList(array)); 553 } 554 555 /** 556 * Convenience method to read a Double vector as an ArrayList. 557 * @return array of parsed values. 558 * @throws IllegalArgumentException if the parcel has no more data 559 */ readDoubleVector()560 public final ArrayList<Double> readDoubleVector() { 561 Double[] array = HwBlob.wrapArray(readDoubleVectorAsArray()); 562 563 return new ArrayList<Double>(Arrays.asList(array)); 564 } 565 566 /** 567 * Convenience method to read a String vector as an ArrayList. 568 * @return array of parsed values. 569 * @throws IllegalArgumentException if the parcel has no more data 570 */ readStringVector()571 public final ArrayList<String> readStringVector() { 572 return new ArrayList<String>(Arrays.asList(readStringVectorAsArray())); 573 } 574 575 /** 576 * Convenience method to read a vector of native handles as an ArrayList. 577 * @return array of {@link NativeHandle} objects. 578 * @throws IllegalArgumentException if the parcel has no more data 579 */ readNativeHandleVector()580 public final @NonNull ArrayList<NativeHandle> readNativeHandleVector() { 581 return new ArrayList<NativeHandle>(Arrays.asList(readNativeHandleAsArray())); 582 } 583 584 /** 585 * Reads a strong binder value from the parcel. 586 * @return binder object read from parcel or null if no binder can be read 587 * @throws IllegalArgumentException if the parcel has no more data 588 */ 589 @FastNative readStrongBinder()590 public native final IHwBinder readStrongBinder(); 591 592 /** 593 * Reads a HidlMemory value (without duplicating the underlying file 594 * descriptors) from the parcel. These file descriptors will only 595 * be open for the duration that the binder window is open. If they 596 * are needed further, you must call {@link HidlMemory#dup()}, which makes you also 597 * responsible for calling {@link HidlMemory#close()}. 598 * 599 * @return HidlMemory object read from parcel. 600 * @throws IllegalArgumentException if the parcel has no more data or is otherwise corrupt. 601 */ 602 @FastNative 603 @NonNull readHidlMemory()604 public native final HidlMemory readHidlMemory(); 605 606 /** 607 * Reads an embedded HidlMemory (without duplicating the underlying 608 * file descriptors) from the parcel. These file descriptors will only 609 * be open for the duration that the binder window is open. If they 610 * are needed further, you must call {@link HidlMemory#dup()}. You 611 * do not need to call close on the HidlMemory returned from this. 612 * 613 * @param fieldHandle handle of the field, obtained from the {@link HwBlob}. 614 * @param parentHandle parentHandle from which to read the embedded object 615 * @param offset offset into parent 616 * @return a {@link HidlMemory} instance parsed from the parcel 617 * @throws IllegalArgumentException if the parcel has no more data 618 */ 619 @FastNative 620 @NonNull 621 public native final @Nullable readEmbeddedHidlMemory(long fieldHandle, long parentHandle, long offset)622 HidlMemory readEmbeddedHidlMemory(long fieldHandle, long parentHandle, long offset); 623 624 /** 625 * Read opaque segment of data as a blob. 626 * @return blob of size expectedSize 627 * @throws IllegalArgumentException if the parcel has no more data 628 */ 629 @FastNative readBuffer(long expectedSize)630 public native final HwBlob readBuffer(long expectedSize); 631 632 /** 633 * Read a buffer written using scatter gather. 634 * 635 * @param expectedSize size that buffer should be 636 * @param parentHandle handle from which to read the embedded buffer 637 * @param offset offset into parent 638 * @param nullable whether or not to allow for a null return 639 * @return blob of data with size expectedSize 640 * @throws NoSuchElementException if an embedded buffer is not available to read 641 * @throws IllegalArgumentException if expectedSize < 0 642 * @throws NullPointerException if the transaction specified the blob to be null 643 * but nullable is false 644 */ 645 @FastNative readEmbeddedBuffer( long expectedSize, long parentHandle, long offset, boolean nullable)646 public native final HwBlob readEmbeddedBuffer( 647 long expectedSize, long parentHandle, long offset, 648 boolean nullable); 649 650 /** 651 * Write a buffer into the transaction. 652 * @param blob blob to write into the parcel. 653 */ 654 @FastNative writeBuffer(HwBlob blob)655 public native final void writeBuffer(HwBlob blob); 656 /** 657 * Write a status value into the blob. 658 * @param status value to write 659 */ 660 @FastNative writeStatus(int status)661 public native final void writeStatus(int status); 662 /** 663 * @throws IllegalArgumentException if a success vaue cannot be read 664 * @throws RemoteException if success value indicates a transaction error 665 */ 666 @FastNative verifySuccess()667 public native final void verifySuccess(); 668 /** 669 * Should be called to reduce memory pressure when this object no longer needs 670 * to be written to. 671 */ 672 @FastNative releaseTemporaryStorage()673 public native final void releaseTemporaryStorage(); 674 /** 675 * Should be called when object is no longer needed to reduce possible memory 676 * pressure if the Java GC does not get to this object in time. 677 */ 678 @FastNative release()679 public native final void release(); 680 681 /** 682 * Sends the parcel to the specified destination. 683 */ send()684 public native final void send(); 685 686 // Returns address of the "freeFunction". native_init()687 private static native final long native_init(); 688 689 @FastNative native_setup(boolean allocate)690 private native final void native_setup(boolean allocate); 691 692 static { 693 long freeFunction = native_init(); 694 695 sNativeRegistry = new NativeAllocationRegistry( 696 HwParcel.class.getClassLoader(), 697 freeFunction, 698 128 /* size */); 699 } 700 701 private long mNativeContext; 702 } 703 704