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