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.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.annotation.TestApi; 23 24 import libcore.util.NativeAllocationRegistry; 25 26 /** 27 * Represents fixed sized allocation of marshalled data used. Helper methods 28 * allow for access to the unmarshalled data in a variety of ways. 29 * 30 * @hide 31 */ 32 @SystemApi 33 @TestApi 34 public class HwBlob { 35 private static final String TAG = "HwBlob"; 36 37 private static final NativeAllocationRegistry sNativeRegistry; 38 HwBlob(int size)39 public HwBlob(int size) { 40 native_setup(size); 41 42 sNativeRegistry.registerNativeAllocation( 43 this, 44 mNativeContext); 45 } 46 47 /** 48 * @param offset offset to unmarshall a boolean from 49 * @return the unmarshalled boolean value 50 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 51 */ getBool(long offset)52 public native final boolean getBool(long offset); 53 /** 54 * @param offset offset to unmarshall a byte from 55 * @return the unmarshalled byte value 56 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 57 */ getInt8(long offset)58 public native final byte getInt8(long offset); 59 /** 60 * @param offset offset to unmarshall a short from 61 * @return the unmarshalled short value 62 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 63 */ getInt16(long offset)64 public native final short getInt16(long offset); 65 /** 66 * @param offset offset to unmarshall an int from 67 * @return the unmarshalled int value 68 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 69 */ getInt32(long offset)70 public native final int getInt32(long offset); 71 /** 72 * @param offset offset to unmarshall a long from 73 * @return the unmarshalled long value 74 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 75 */ getInt64(long offset)76 public native final long getInt64(long offset); 77 /** 78 * @param offset offset to unmarshall a float from 79 * @return the unmarshalled float value 80 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 81 */ getFloat(long offset)82 public native final float getFloat(long offset); 83 /** 84 * @param offset offset to unmarshall a double from 85 * @return the unmarshalled double value 86 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 87 */ getDouble(long offset)88 public native final double getDouble(long offset); 89 /** 90 * @param offset offset to unmarshall a string from 91 * @return the unmarshalled string value 92 * @throws IndexOutOfBoundsException when offset is out of this HwBlob 93 */ getString(long offset)94 public native final String getString(long offset); 95 /** 96 * For embedded fields that follow a two-step approach for reading, first obtain their field 97 * handle using this method, and pass that field handle to the respective 98 * HwParcel.readEmbedded*() method. 99 * @param offset The field offset. 100 * @return The field handle. 101 */ getFieldHandle(long offset)102 public native final long getFieldHandle(long offset); 103 104 /** 105 * Copy the blobs data starting from the given byte offset into the range, copying 106 * a total of size elements. 107 * 108 * @param offset starting location in blob 109 * @param array destination array 110 * @param size total number of elements to copy 111 * @throws IllegalArgumentException array.length < size 112 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jboolean)] out of the blob. 113 */ copyToBoolArray(long offset, boolean[] array, int size)114 public native final void copyToBoolArray(long offset, boolean[] array, int size); 115 /** 116 * Copy the blobs data starting from the given byte offset into the range, copying 117 * a total of size elements. 118 * 119 * @param offset starting location in blob 120 * @param array destination array 121 * @param size total number of elements to copy 122 * @throws IllegalArgumentException array.length < size 123 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jbyte)] out of the blob. 124 */ copyToInt8Array(long offset, byte[] array, int size)125 public native final void copyToInt8Array(long offset, byte[] array, int size); 126 /** 127 * Copy the blobs data starting from the given byte offset into the range, copying 128 * a total of size elements. 129 * 130 * @param offset starting location in blob 131 * @param array destination array 132 * @param size total number of elements to copy 133 * @throws IllegalArgumentException array.length < size 134 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jshort)] out of the blob. 135 */ copyToInt16Array(long offset, short[] array, int size)136 public native final void copyToInt16Array(long offset, short[] array, int size); 137 /** 138 * Copy the blobs data starting from the given byte offset into the range, copying 139 * a total of size elements. 140 * 141 * @param offset starting location in blob 142 * @param array destination array 143 * @param size total number of elements to copy 144 * @throws IllegalArgumentException array.length < size 145 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jint)] out of the blob. 146 */ copyToInt32Array(long offset, int[] array, int size)147 public native final void copyToInt32Array(long offset, int[] array, int size); 148 /** 149 * Copy the blobs data starting from the given byte offset into the range, copying 150 * a total of size elements. 151 * 152 * @param offset starting location in blob 153 * @param array destination array 154 * @param size total number of elements to copy 155 * @throws IllegalArgumentException array.length < size 156 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jlong)] out of the blob. 157 */ copyToInt64Array(long offset, long[] array, int size)158 public native final void copyToInt64Array(long offset, long[] array, int size); 159 /** 160 * Copy the blobs data starting from the given byte offset into the range, copying 161 * a total of size elements. 162 * 163 * @param offset starting location in blob 164 * @param array destination array 165 * @param size total number of elements to copy 166 * @throws IllegalArgumentException array.length < size 167 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jfloat)] out of the blob. 168 */ copyToFloatArray(long offset, float[] array, int size)169 public native final void copyToFloatArray(long offset, float[] array, int size); 170 /** 171 * Copy the blobs data starting from the given byte offset into the range, copying 172 * a total of size elements. 173 * 174 * @param offset starting location in blob 175 * @param array destination array 176 * @param size total number of elements to copy 177 * @throws IllegalArgumentException array.length < size 178 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jdouble)] out of the blob. 179 */ copyToDoubleArray(long offset, double[] array, int size)180 public native final void copyToDoubleArray(long offset, double[] array, int size); 181 182 /** 183 * Writes a boolean value at an offset. 184 * 185 * @param offset location to write value 186 * @param x value to write 187 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jboolean)] is out of range 188 */ putBool(long offset, boolean x)189 public native final void putBool(long offset, boolean x); 190 /** 191 * Writes a byte value at an offset. 192 * 193 * @param offset location to write value 194 * @param x value to write 195 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jbyte)] is out of range 196 */ putInt8(long offset, byte x)197 public native final void putInt8(long offset, byte x); 198 /** 199 * Writes a short value at an offset. 200 * 201 * @param offset location to write value 202 * @param x value to write 203 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jshort)] is out of range 204 */ putInt16(long offset, short x)205 public native final void putInt16(long offset, short x); 206 /** 207 * Writes a int value at an offset. 208 * 209 * @param offset location to write value 210 * @param x value to write 211 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jint)] is out of range 212 */ putInt32(long offset, int x)213 public native final void putInt32(long offset, int x); 214 /** 215 * Writes a long value at an offset. 216 * 217 * @param offset location to write value 218 * @param x value to write 219 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jlong)] is out of range 220 */ putInt64(long offset, long x)221 public native final void putInt64(long offset, long x); 222 /** 223 * Writes a float value at an offset. 224 * 225 * @param offset location to write value 226 * @param x value to write 227 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jfloat)] is out of range 228 */ putFloat(long offset, float x)229 public native final void putFloat(long offset, float x); 230 /** 231 * Writes a double value at an offset. 232 * 233 * @param offset location to write value 234 * @param x value to write 235 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jdouble)] is out of range 236 */ putDouble(long offset, double x)237 public native final void putDouble(long offset, double x); 238 /** 239 * Writes a string value at an offset. 240 * 241 * @param offset location to write value 242 * @param x value to write 243 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jstring)] is out of range 244 */ putString(long offset, String x)245 public native final void putString(long offset, String x); 246 /** 247 * Writes a native handle (without duplicating the underlying file descriptors) at an offset. 248 * 249 * @param offset location to write value 250 * @param x a {@link NativeHandle} instance to write 251 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jobject)] is out of range 252 */ putNativeHandle(long offset, @Nullable NativeHandle x)253 public native final void putNativeHandle(long offset, @Nullable NativeHandle x); 254 255 /** 256 * Put a boolean array contiguously at an offset in the blob. 257 * 258 * @param offset location to write values 259 * @param x array to write 260 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jboolean)] out of the blob. 261 */ putBoolArray(long offset, boolean[] x)262 public native final void putBoolArray(long offset, boolean[] x); 263 /** 264 * Put a byte array contiguously at an offset in the blob. 265 * 266 * @param offset location to write values 267 * @param x array to write 268 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jbyte)] out of the blob. 269 */ putInt8Array(long offset, byte[] x)270 public native final void putInt8Array(long offset, byte[] x); 271 /** 272 * Put a short array contiguously at an offset in the blob. 273 * 274 * @param offset location to write values 275 * @param x array to write 276 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jshort)] out of the blob. 277 */ putInt16Array(long offset, short[] x)278 public native final void putInt16Array(long offset, short[] x); 279 /** 280 * Put a int array contiguously at an offset in the blob. 281 * 282 * @param offset location to write values 283 * @param x array to write 284 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jint)] out of the blob. 285 */ putInt32Array(long offset, int[] x)286 public native final void putInt32Array(long offset, int[] x); 287 /** 288 * Put a long array contiguously at an offset in the blob. 289 * 290 * @param offset location to write values 291 * @param x array to write 292 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jlong)] out of the blob. 293 */ putInt64Array(long offset, long[] x)294 public native final void putInt64Array(long offset, long[] x); 295 /** 296 * Put a float array contiguously at an offset in the blob. 297 * 298 * @param offset location to write values 299 * @param x array to write 300 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jfloat)] out of the blob. 301 */ putFloatArray(long offset, float[] x)302 public native final void putFloatArray(long offset, float[] x); 303 /** 304 * Put a double array contiguously at an offset in the blob. 305 * 306 * @param offset location to write values 307 * @param x array to write 308 * @throws IndexOutOfBoundsException [offset, offset + size * sizeof(jdouble)] out of the blob. 309 */ putDoubleArray(long offset, double[] x)310 public native final void putDoubleArray(long offset, double[] x); 311 312 /** 313 * Write another HwBlob into this blob at the specified location. 314 * 315 * @param offset location to write value 316 * @param blob data to write 317 * @throws IndexOutOfBoundsException if [offset, offset + blob's size] outside of the range of 318 * this blob. 319 */ putBlob(long offset, HwBlob blob)320 public native final void putBlob(long offset, HwBlob blob); 321 322 /** 323 * Writes a HidlMemory instance (without duplicating the underlying file descriptors) at an 324 * offset. 325 * 326 * @param offset location to write value 327 * @param mem a {@link HidlMemory} instance to write 328 * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jobject)] is out of range 329 */ putHidlMemory(long offset, @NonNull HidlMemory mem)330 public final void putHidlMemory(long offset, @NonNull HidlMemory mem) { 331 putNativeHandle(offset + 0 /* offset of 'handle' field. */, mem.getHandle()); 332 putInt64(offset + 16 /* offset of 'size' field. */, mem.getSize()); 333 putString(offset + 24 /* offset of 'name' field. */, mem.getName()); 334 } 335 336 /** 337 * @return current handle of HwBlob for reference in a parcelled binder transaction 338 */ handle()339 public native final long handle(); 340 341 /** 342 * Convert a primitive to a wrapped array for boolean. 343 * 344 * @param array from array 345 * @return transformed array 346 */ wrapArray(@onNull boolean[] array)347 public static Boolean[] wrapArray(@NonNull boolean[] array) { 348 final int n = array.length; 349 Boolean[] wrappedArray = new Boolean[n]; 350 for (int i = 0; i < n; ++i) { 351 wrappedArray[i] = array[i]; 352 } 353 return wrappedArray; 354 } 355 356 /** 357 * Convert a primitive to a wrapped array for long. 358 * 359 * @param array from array 360 * @return transformed array 361 */ wrapArray(@onNull long[] array)362 public static Long[] wrapArray(@NonNull long[] array) { 363 final int n = array.length; 364 Long[] wrappedArray = new Long[n]; 365 for (int i = 0; i < n; ++i) { 366 wrappedArray[i] = array[i]; 367 } 368 return wrappedArray; 369 } 370 371 /** 372 * Convert a primitive to a wrapped array for byte. 373 * 374 * @param array from array 375 * @return transformed array 376 */ wrapArray(@onNull byte[] array)377 public static Byte[] wrapArray(@NonNull byte[] array) { 378 final int n = array.length; 379 Byte[] wrappedArray = new Byte[n]; 380 for (int i = 0; i < n; ++i) { 381 wrappedArray[i] = array[i]; 382 } 383 return wrappedArray; 384 } 385 386 /** 387 * Convert a primitive to a wrapped array for short. 388 * 389 * @param array from array 390 * @return transformed array 391 */ wrapArray(@onNull short[] array)392 public static Short[] wrapArray(@NonNull short[] array) { 393 final int n = array.length; 394 Short[] wrappedArray = new Short[n]; 395 for (int i = 0; i < n; ++i) { 396 wrappedArray[i] = array[i]; 397 } 398 return wrappedArray; 399 } 400 401 /** 402 * Convert a primitive to a wrapped array for int. 403 * 404 * @param array from array 405 * @return transformed array 406 */ wrapArray(@onNull int[] array)407 public static Integer[] wrapArray(@NonNull int[] array) { 408 final int n = array.length; 409 Integer[] wrappedArray = new Integer[n]; 410 for (int i = 0; i < n; ++i) { 411 wrappedArray[i] = array[i]; 412 } 413 return wrappedArray; 414 } 415 416 /** 417 * Convert a primitive to a wrapped array for float. 418 * 419 * @param array from array 420 * @return transformed array 421 */ wrapArray(@onNull float[] array)422 public static Float[] wrapArray(@NonNull float[] array) { 423 final int n = array.length; 424 Float[] wrappedArray = new Float[n]; 425 for (int i = 0; i < n; ++i) { 426 wrappedArray[i] = array[i]; 427 } 428 return wrappedArray; 429 } 430 431 /** 432 * Convert a primitive to a wrapped array for double. 433 * 434 * @param array from array 435 * @return transformed array 436 */ wrapArray(@onNull double[] array)437 public static Double[] wrapArray(@NonNull double[] array) { 438 final int n = array.length; 439 Double[] wrappedArray = new Double[n]; 440 for (int i = 0; i < n; ++i) { 441 wrappedArray[i] = array[i]; 442 } 443 return wrappedArray; 444 } 445 446 // Returns address of the "freeFunction". native_init()447 private static native final long native_init(); 448 native_setup(int size)449 private native final void native_setup(int size); 450 451 static { 452 long freeFunction = native_init(); 453 454 sNativeRegistry = new NativeAllocationRegistry( 455 HwBlob.class.getClassLoader(), 456 freeFunction, 457 128 /* size */); 458 } 459 460 private long mNativeContext; 461 } 462 463 464