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
17package android.os;
18
19import android.annotation.IntDef;
20import android.annotation.SystemApi;
21
22import libcore.util.NativeAllocationRegistry;
23
24import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
26import java.util.ArrayList;
27import java.util.Arrays;
28
29/** @hide */
30@SystemApi
31public 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