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.SystemApi; 21 22 import libcore.util.NativeAllocationRegistry; 23 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 import java.util.ArrayList; 27 import java.util.Arrays; 28 29 /** @hide */ 30 @SystemApi 31 public class HwParcel { 32 private static final String TAG = "HwParcel"; 33 34 @IntDef(prefix = { "STATUS_" }, value = { 35 STATUS_SUCCESS, 36 }) 37 @Retention(RetentionPolicy.SOURCE) 38 public @interface Status {} 39 40 /** 41 * Success return error for a transaction. Written to parcels 42 * using writeStatus. 43 */ 44 public static final int STATUS_SUCCESS = 0; 45 46 private static final NativeAllocationRegistry sNativeRegistry; 47 48 private HwParcel(boolean allocate) { 49 native_setup(allocate); 50 51 sNativeRegistry.registerNativeAllocation( 52 this, 53 mNativeContext); 54 } 55 56 /** 57 * Creates an initialized and empty parcel. 58 */ 59 public HwParcel() { 60 native_setup(true /* allocate */); 61 62 sNativeRegistry.registerNativeAllocation( 63 this, 64 mNativeContext); 65 } 66 67 /** 68 * Writes an interface token into the parcel used to verify that 69 * a transaction has made it to the write type of interface. 70 * 71 * @param interfaceName fully qualified name of interface message 72 * is being sent to. 73 */ 74 public native final void writeInterfaceToken(String interfaceName); 75 /** 76 * Writes a boolean value to the end of the parcel. 77 * @param val to write 78 */ 79 public native final void writeBool(boolean val); 80 /** 81 * Writes a byte value to the end of the parcel. 82 * @param val to write 83 */ 84 public native final void writeInt8(byte val); 85 /** 86 * Writes a short value to the end of the parcel. 87 * @param val to write 88 */ 89 public native final void writeInt16(short val); 90 /** 91 * Writes a int value to the end of the parcel. 92 * @param val to write 93 */ 94 public native final void writeInt32(int val); 95 /** 96 * Writes a long value to the end of the parcel. 97 * @param val to write 98 */ 99 public native final void writeInt64(long val); 100 /** 101 * Writes a float value to the end of the parcel. 102 * @param val to write 103 */ 104 public native final void writeFloat(float val); 105 /** 106 * Writes a double value to the end of the parcel. 107 * @param val to write 108 */ 109 public native final void writeDouble(double val); 110 /** 111 * Writes a String value to the end of the parcel. 112 * 113 * Note, this will be converted to UTF-8 when it is written. 114 * 115 * @param val to write 116 */ 117 public native final void writeString(String val); 118 119 /** 120 * Writes an array of boolean values to the end of the parcel. 121 * @param val to write 122 */ 123 private native final void writeBoolVector(boolean[] val); 124 /** 125 * Writes an array of byte values to the end of the parcel. 126 * @param val to write 127 */ 128 private native final void writeInt8Vector(byte[] val); 129 /** 130 * Writes an array of short values to the end of the parcel. 131 * @param val to write 132 */ 133 private native final void writeInt16Vector(short[] val); 134 /** 135 * Writes an array of int values to the end of the parcel. 136 * @param val to write 137 */ 138 private native final void writeInt32Vector(int[] val); 139 /** 140 * Writes an array of long values to the end of the parcel. 141 * @param val to write 142 */ 143 private native final void writeInt64Vector(long[] val); 144 /** 145 * Writes an array of float values to the end of the parcel. 146 * @param val to write 147 */ 148 private native final void writeFloatVector(float[] val); 149 /** 150 * Writes an array of double values to the end of the parcel. 151 * @param val to write 152 */ 153 private native final void writeDoubleVector(double[] val); 154 /** 155 * Writes an array of String values to the end of the parcel. 156 * 157 * Note, these will be converted to UTF-8 as they are written. 158 * 159 * @param val to write 160 */ 161 private native final void writeStringVector(String[] val); 162 163 /** 164 * Helper method to write a list of Booleans to val. 165 * @param val list to write 166 */ 167 public final void writeBoolVector(ArrayList<Boolean> val) { 168 final int n = val.size(); 169 boolean[] array = new boolean[n]; 170 for (int i = 0; i < n; ++i) { 171 array[i] = val.get(i); 172 } 173 174 writeBoolVector(array); 175 } 176 177 /** 178 * Helper method to write a list of Booleans to the end of the parcel. 179 * @param val list to write 180 */ 181 public final void writeInt8Vector(ArrayList<Byte> val) { 182 final int n = val.size(); 183 byte[] array = new byte[n]; 184 for (int i = 0; i < n; ++i) { 185 array[i] = val.get(i); 186 } 187 188 writeInt8Vector(array); 189 } 190 191 /** 192 * Helper method to write a list of Shorts to the end of the parcel. 193 * @param val list to write 194 */ 195 public final void writeInt16Vector(ArrayList<Short> val) { 196 final int n = val.size(); 197 short[] array = new short[n]; 198 for (int i = 0; i < n; ++i) { 199 array[i] = val.get(i); 200 } 201 202 writeInt16Vector(array); 203 } 204 205 /** 206 * Helper method to write a list of Integers to the end of the parcel. 207 * @param val list to write 208 */ 209 public final void writeInt32Vector(ArrayList<Integer> val) { 210 final int n = val.size(); 211 int[] array = new int[n]; 212 for (int i = 0; i < n; ++i) { 213 array[i] = val.get(i); 214 } 215 216 writeInt32Vector(array); 217 } 218 219 /** 220 * Helper method to write a list of Longs to the end of the parcel. 221 * @param val list to write 222 */ 223 public final void writeInt64Vector(ArrayList<Long> val) { 224 final int n = val.size(); 225 long[] array = new long[n]; 226 for (int i = 0; i < n; ++i) { 227 array[i] = val.get(i); 228 } 229 230 writeInt64Vector(array); 231 } 232 233 /** 234 * Helper method to write a list of Floats to the end of the parcel. 235 * @param val list to write 236 */ 237 public final void writeFloatVector(ArrayList<Float> val) { 238 final int n = val.size(); 239 float[] array = new float[n]; 240 for (int i = 0; i < n; ++i) { 241 array[i] = val.get(i); 242 } 243 244 writeFloatVector(array); 245 } 246 247 /** 248 * Helper method to write a list of Doubles to the end of the parcel. 249 * @param val list to write 250 */ 251 public final void writeDoubleVector(ArrayList<Double> val) { 252 final int n = val.size(); 253 double[] array = new double[n]; 254 for (int i = 0; i < n; ++i) { 255 array[i] = val.get(i); 256 } 257 258 writeDoubleVector(array); 259 } 260 261 /** 262 * Helper method to write a list of Strings to the end of the parcel. 263 * @param val list to write 264 */ 265 public final void writeStringVector(ArrayList<String> val) { 266 writeStringVector(val.toArray(new String[val.size()])); 267 } 268 269 /** 270 * Write a hwbinder object to the end of the parcel. 271 * @param binder value to write 272 */ 273 public native final void writeStrongBinder(IHwBinder binder); 274 275 /** 276 * Checks to make sure that the interface name matches the name written by the parcel 277 * sender by writeInterfaceToken 278 * 279 * @throws SecurityException interface doesn't match 280 */ 281 public native final void enforceInterface(String interfaceName); 282 283 /** 284 * Reads a boolean value from the current location in the parcel. 285 * @return value parsed from the parcel 286 * @throws IllegalArgumentException if the parcel has no more data 287 */ 288 public native final boolean readBool(); 289 /** 290 * Reads a byte value from the current location in the parcel. 291 * @return value parsed from the parcel 292 * @throws IllegalArgumentException if the parcel has no more data 293 */ 294 public native final byte readInt8(); 295 /** 296 * Reads a short value from the current location in the parcel. 297 * @return value parsed from the parcel 298 * @throws IllegalArgumentException if the parcel has no more data 299 */ 300 public native final short readInt16(); 301 /** 302 * Reads a int value from the current location in the parcel. 303 * @return value parsed from the parcel 304 * @throws IllegalArgumentException if the parcel has no more data 305 */ 306 public native final int readInt32(); 307 /** 308 * Reads a long value from the current location in the parcel. 309 * @return value parsed from the parcel 310 * @throws IllegalArgumentException if the parcel has no more data 311 */ 312 public native final long readInt64(); 313 /** 314 * Reads a float value from the current location in the parcel. 315 * @return value parsed from the parcel 316 * @throws IllegalArgumentException if the parcel has no more data 317 */ 318 public native final float readFloat(); 319 /** 320 * Reads a double value from the current location in the parcel. 321 * @return value parsed from the parcel 322 * @throws IllegalArgumentException if the parcel has no more data 323 */ 324 public native final double readDouble(); 325 /** 326 * Reads a String value from the current location in the parcel. 327 * @return value parsed from the parcel 328 * @throws IllegalArgumentException if the parcel has no more data 329 */ 330 public native final String readString(); 331 332 /** 333 * Reads an array of boolean values from the parcel. 334 * @return array of parsed values 335 * @throws IllegalArgumentException if the parcel has no more data 336 */ 337 private native final boolean[] readBoolVectorAsArray(); 338 /** 339 * Reads an array of byte values from the parcel. 340 * @return array of parsed values 341 * @throws IllegalArgumentException if the parcel has no more data 342 */ 343 private native final byte[] readInt8VectorAsArray(); 344 /** 345 * Reads an array of short values from the parcel. 346 * @return array of parsed values 347 * @throws IllegalArgumentException if the parcel has no more data 348 */ 349 private native final short[] readInt16VectorAsArray(); 350 /** 351 * Reads an array of int values from the parcel. 352 * @return array of parsed values 353 * @throws IllegalArgumentException if the parcel has no more data 354 */ 355 private native final int[] readInt32VectorAsArray(); 356 /** 357 * Reads an array of long values from the parcel. 358 * @return array of parsed values 359 * @throws IllegalArgumentException if the parcel has no more data 360 */ 361 private native final long[] readInt64VectorAsArray(); 362 /** 363 * Reads an array of float values from the parcel. 364 * @return array of parsed values 365 * @throws IllegalArgumentException if the parcel has no more data 366 */ 367 private native final float[] readFloatVectorAsArray(); 368 /** 369 * Reads an array of double values from the parcel. 370 * @return array of parsed values 371 * @throws IllegalArgumentException if the parcel has no more data 372 */ 373 private native final double[] readDoubleVectorAsArray(); 374 /** 375 * Reads an array of String values from the parcel. 376 * @return array of parsed values 377 * @throws IllegalArgumentException if the parcel has no more data 378 */ 379 private native final String[] readStringVectorAsArray(); 380 381 /** 382 * Convenience method to read a Boolean vector as an ArrayList. 383 * @return array of parsed values. 384 * @throws IllegalArgumentException if the parcel has no more data 385 */ 386 public final ArrayList<Boolean> readBoolVector() { 387 Boolean[] array = HwBlob.wrapArray(readBoolVectorAsArray()); 388 389 return new ArrayList<Boolean>(Arrays.asList(array)); 390 } 391 392 /** 393 * Convenience method to read a Byte vector as an ArrayList. 394 * @return array of parsed values. 395 * @throws IllegalArgumentException if the parcel has no more data 396 */ 397 public final ArrayList<Byte> readInt8Vector() { 398 Byte[] array = HwBlob.wrapArray(readInt8VectorAsArray()); 399 400 return new ArrayList<Byte>(Arrays.asList(array)); 401 } 402 403 /** 404 * Convenience method to read a Short vector as an ArrayList. 405 * @return array of parsed values. 406 * @throws IllegalArgumentException if the parcel has no more data 407 */ 408 public final ArrayList<Short> readInt16Vector() { 409 Short[] array = HwBlob.wrapArray(readInt16VectorAsArray()); 410 411 return new ArrayList<Short>(Arrays.asList(array)); 412 } 413 414 /** 415 * Convenience method to read a Integer vector as an ArrayList. 416 * @return array of parsed values. 417 * @throws IllegalArgumentException if the parcel has no more data 418 */ 419 public final ArrayList<Integer> readInt32Vector() { 420 Integer[] array = HwBlob.wrapArray(readInt32VectorAsArray()); 421 422 return new ArrayList<Integer>(Arrays.asList(array)); 423 } 424 425 /** 426 * Convenience method to read a Long vector as an ArrayList. 427 * @return array of parsed values. 428 * @throws IllegalArgumentException if the parcel has no more data 429 */ 430 public final ArrayList<Long> readInt64Vector() { 431 Long[] array = HwBlob.wrapArray(readInt64VectorAsArray()); 432 433 return new ArrayList<Long>(Arrays.asList(array)); 434 } 435 436 /** 437 * Convenience method to read a Float vector as an ArrayList. 438 * @return array of parsed values. 439 * @throws IllegalArgumentException if the parcel has no more data 440 */ 441 public final ArrayList<Float> readFloatVector() { 442 Float[] array = HwBlob.wrapArray(readFloatVectorAsArray()); 443 444 return new ArrayList<Float>(Arrays.asList(array)); 445 } 446 447 /** 448 * Convenience method to read a Double vector as an ArrayList. 449 * @return array of parsed values. 450 * @throws IllegalArgumentException if the parcel has no more data 451 */ 452 public final ArrayList<Double> readDoubleVector() { 453 Double[] array = HwBlob.wrapArray(readDoubleVectorAsArray()); 454 455 return new ArrayList<Double>(Arrays.asList(array)); 456 } 457 458 /** 459 * Convenience method to read a String vector as an ArrayList. 460 * @return array of parsed values. 461 * @throws IllegalArgumentException if the parcel has no more data 462 */ 463 public final ArrayList<String> readStringVector() { 464 return new ArrayList<String>(Arrays.asList(readStringVectorAsArray())); 465 } 466 467 /** 468 * Reads a strong binder value from the parcel. 469 * @return binder object read from parcel or null if no binder can be read 470 * @throws IllegalArgumentException if the parcel has no more data 471 */ 472 public native final IHwBinder readStrongBinder(); 473 474 /** 475 * Read opaque segment of data as a blob. 476 * @return blob of size expectedSize 477 * @throws IllegalArgumentException if the parcel has no more data 478 */ 479 public native final HwBlob readBuffer(long expectedSize); 480 481 /** 482 * Read a buffer written using scatter gather. 483 * 484 * @param expectedSize size that buffer should be 485 * @param parentHandle handle from which to read the embedded buffer 486 * @param offset offset into parent 487 * @param nullable whether or not to allow for a null return 488 * @return blob of data with size expectedSize 489 * @throws NoSuchElementException if an embedded buffer is not available to read 490 * @throws IllegalArgumentException if expectedSize < 0 491 * @throws NullPointerException if the transaction specified the blob to be null 492 * but nullable is false 493 */ 494 public native final HwBlob readEmbeddedBuffer( 495 long expectedSize, long parentHandle, long offset, 496 boolean nullable); 497 498 /** 499 * Write a buffer into the transaction. 500 * @param blob blob to write into the parcel. 501 */ 502 public native final void writeBuffer(HwBlob blob); 503 /** 504 * Write a status value into the blob. 505 * @param status value to write 506 */ 507 public native final void writeStatus(int status); 508 /** 509 * @throws IllegalArgumentException if a success vaue cannot be read 510 * @throws RemoteException if success value indicates a transaction error 511 */ 512 public native final void verifySuccess(); 513 /** 514 * Should be called to reduce memory pressure when this object no longer needs 515 * to be written to. 516 */ 517 public native final void releaseTemporaryStorage(); 518 /** 519 * Should be called when object is no longer needed to reduce possible memory 520 * pressure if the Java GC does not get to this object in time. 521 */ 522 public native final void release(); 523 524 /** 525 * Sends the parcel to the specified destination. 526 */ 527 public native final void send(); 528 529 // Returns address of the "freeFunction". 530 private static native final long native_init(); 531 532 private native final void native_setup(boolean allocate); 533 534 static { 535 long freeFunction = native_init(); 536 537 sNativeRegistry = new NativeAllocationRegistry( 538 HwParcel.class.getClassLoader(), 539 freeFunction, 540 128 /* size */); 541 } 542 543 private long mNativeContext; 544 } 545 546