|  | /* | 
|  | * Copyright (C) 2016 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | package android.os; | 
|  |  | 
|  | import android.annotation.IntDef; | 
|  | import android.annotation.SystemApi; | 
|  |  | 
|  | import libcore.util.NativeAllocationRegistry; | 
|  |  | 
|  | import java.lang.annotation.Retention; | 
|  | import java.lang.annotation.RetentionPolicy; | 
|  | import java.util.ArrayList; | 
|  | import java.util.Arrays; | 
|  |  | 
|  | /** @hide */ | 
|  | @SystemApi | 
|  | public class HwParcel { | 
|  | private static final String TAG = "HwParcel"; | 
|  |  | 
|  | @IntDef(prefix = { "STATUS_" }, value = { | 
|  | STATUS_SUCCESS, | 
|  | }) | 
|  | @Retention(RetentionPolicy.SOURCE) | 
|  | public @interface Status {} | 
|  |  | 
|  | /** | 
|  | * Success return error for a transaction. Written to parcels | 
|  | * using writeStatus. | 
|  | */ | 
|  | public static final int STATUS_SUCCESS      = 0; | 
|  |  | 
|  | private static final NativeAllocationRegistry sNativeRegistry; | 
|  |  | 
|  | private HwParcel(boolean allocate) { | 
|  | native_setup(allocate); | 
|  |  | 
|  | sNativeRegistry.registerNativeAllocation( | 
|  | this, | 
|  | mNativeContext); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Creates an initialized and empty parcel. | 
|  | */ | 
|  | public HwParcel() { | 
|  | native_setup(true /* allocate */); | 
|  |  | 
|  | sNativeRegistry.registerNativeAllocation( | 
|  | this, | 
|  | mNativeContext); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Writes an interface token into the parcel used to verify that | 
|  | * a transaction has made it to the write type of interface. | 
|  | * | 
|  | * @param interfaceName fully qualified name of interface message | 
|  | *     is being sent to. | 
|  | */ | 
|  | public native final void writeInterfaceToken(String interfaceName); | 
|  | /** | 
|  | * Writes a boolean value to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeBool(boolean val); | 
|  | /** | 
|  | * Writes a byte value to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeInt8(byte val); | 
|  | /** | 
|  | * Writes a short value to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeInt16(short val); | 
|  | /** | 
|  | * Writes a int value to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeInt32(int val); | 
|  | /** | 
|  | * Writes a long value to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeInt64(long val); | 
|  | /** | 
|  | * Writes a float value to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeFloat(float val); | 
|  | /** | 
|  | * Writes a double value to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeDouble(double val); | 
|  | /** | 
|  | * Writes a String value to the end of the parcel. | 
|  | * | 
|  | * Note, this will be converted to UTF-8 when it is written. | 
|  | * | 
|  | * @param val to write | 
|  | */ | 
|  | public native final void writeString(String val); | 
|  |  | 
|  | /** | 
|  | * Writes an array of boolean values to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeBoolVector(boolean[] val); | 
|  | /** | 
|  | * Writes an array of byte values to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeInt8Vector(byte[] val); | 
|  | /** | 
|  | * Writes an array of short values to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeInt16Vector(short[] val); | 
|  | /** | 
|  | * Writes an array of int values to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeInt32Vector(int[] val); | 
|  | /** | 
|  | * Writes an array of long values to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeInt64Vector(long[] val); | 
|  | /** | 
|  | * Writes an array of float values to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeFloatVector(float[] val); | 
|  | /** | 
|  | * Writes an array of double values to the end of the parcel. | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeDoubleVector(double[] val); | 
|  | /** | 
|  | * Writes an array of String values to the end of the parcel. | 
|  | * | 
|  | * Note, these will be converted to UTF-8 as they are written. | 
|  | * | 
|  | * @param val to write | 
|  | */ | 
|  | private native final void writeStringVector(String[] val); | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Booleans to val. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeBoolVector(ArrayList<Boolean> val) { | 
|  | final int n = val.size(); | 
|  | boolean[] array = new boolean[n]; | 
|  | for (int i = 0; i < n; ++i) { | 
|  | array[i] = val.get(i); | 
|  | } | 
|  |  | 
|  | writeBoolVector(array); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Booleans to the end of the parcel. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeInt8Vector(ArrayList<Byte> val) { | 
|  | final int n = val.size(); | 
|  | byte[] array = new byte[n]; | 
|  | for (int i = 0; i < n; ++i) { | 
|  | array[i] = val.get(i); | 
|  | } | 
|  |  | 
|  | writeInt8Vector(array); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Shorts to the end of the parcel. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeInt16Vector(ArrayList<Short> val) { | 
|  | final int n = val.size(); | 
|  | short[] array = new short[n]; | 
|  | for (int i = 0; i < n; ++i) { | 
|  | array[i] = val.get(i); | 
|  | } | 
|  |  | 
|  | writeInt16Vector(array); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Integers to the end of the parcel. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeInt32Vector(ArrayList<Integer> val) { | 
|  | final int n = val.size(); | 
|  | int[] array = new int[n]; | 
|  | for (int i = 0; i < n; ++i) { | 
|  | array[i] = val.get(i); | 
|  | } | 
|  |  | 
|  | writeInt32Vector(array); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Longs to the end of the parcel. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeInt64Vector(ArrayList<Long> val) { | 
|  | final int n = val.size(); | 
|  | long[] array = new long[n]; | 
|  | for (int i = 0; i < n; ++i) { | 
|  | array[i] = val.get(i); | 
|  | } | 
|  |  | 
|  | writeInt64Vector(array); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Floats to the end of the parcel. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeFloatVector(ArrayList<Float> val) { | 
|  | final int n = val.size(); | 
|  | float[] array = new float[n]; | 
|  | for (int i = 0; i < n; ++i) { | 
|  | array[i] = val.get(i); | 
|  | } | 
|  |  | 
|  | writeFloatVector(array); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Doubles to the end of the parcel. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeDoubleVector(ArrayList<Double> val) { | 
|  | final int n = val.size(); | 
|  | double[] array = new double[n]; | 
|  | for (int i = 0; i < n; ++i) { | 
|  | array[i] = val.get(i); | 
|  | } | 
|  |  | 
|  | writeDoubleVector(array); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method to write a list of Strings to the end of the parcel. | 
|  | * @param val list to write | 
|  | */ | 
|  | public final void writeStringVector(ArrayList<String> val) { | 
|  | writeStringVector(val.toArray(new String[val.size()])); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Write a hwbinder object to the end of the parcel. | 
|  | * @param binder value to write | 
|  | */ | 
|  | public native final void writeStrongBinder(IHwBinder binder); | 
|  |  | 
|  | /** | 
|  | * Checks to make sure that the interface name matches the name written by the parcel | 
|  | * sender by writeInterfaceToken | 
|  | * | 
|  | * @throws SecurityException interface doesn't match | 
|  | */ | 
|  | public native final void enforceInterface(String interfaceName); | 
|  |  | 
|  | /** | 
|  | * Reads a boolean value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final boolean readBool(); | 
|  | /** | 
|  | * Reads a byte value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final byte readInt8(); | 
|  | /** | 
|  | * Reads a short value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final short readInt16(); | 
|  | /** | 
|  | * Reads a int value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final int readInt32(); | 
|  | /** | 
|  | * Reads a long value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final long readInt64(); | 
|  | /** | 
|  | * Reads a float value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final float readFloat(); | 
|  | /** | 
|  | * Reads a double value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final double readDouble(); | 
|  | /** | 
|  | * Reads a String value from the current location in the parcel. | 
|  | * @return value parsed from the parcel | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final String readString(); | 
|  |  | 
|  | /** | 
|  | * Reads an array of boolean values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final boolean[] readBoolVectorAsArray(); | 
|  | /** | 
|  | * Reads an array of byte values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final byte[] readInt8VectorAsArray(); | 
|  | /** | 
|  | * Reads an array of short values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final short[] readInt16VectorAsArray(); | 
|  | /** | 
|  | * Reads an array of int values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final int[] readInt32VectorAsArray(); | 
|  | /** | 
|  | * Reads an array of long values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final long[] readInt64VectorAsArray(); | 
|  | /** | 
|  | * Reads an array of float values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final float[] readFloatVectorAsArray(); | 
|  | /** | 
|  | * Reads an array of double values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final double[] readDoubleVectorAsArray(); | 
|  | /** | 
|  | * Reads an array of String values from the parcel. | 
|  | * @return array of parsed values | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | private native final String[] readStringVectorAsArray(); | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a Boolean vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<Boolean> readBoolVector() { | 
|  | Boolean[] array = HwBlob.wrapArray(readBoolVectorAsArray()); | 
|  |  | 
|  | return new ArrayList<Boolean>(Arrays.asList(array)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a Byte vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<Byte> readInt8Vector() { | 
|  | Byte[] array = HwBlob.wrapArray(readInt8VectorAsArray()); | 
|  |  | 
|  | return new ArrayList<Byte>(Arrays.asList(array)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a Short vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<Short> readInt16Vector() { | 
|  | Short[] array = HwBlob.wrapArray(readInt16VectorAsArray()); | 
|  |  | 
|  | return new ArrayList<Short>(Arrays.asList(array)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a Integer vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<Integer> readInt32Vector() { | 
|  | Integer[] array = HwBlob.wrapArray(readInt32VectorAsArray()); | 
|  |  | 
|  | return new ArrayList<Integer>(Arrays.asList(array)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a Long vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<Long> readInt64Vector() { | 
|  | Long[] array = HwBlob.wrapArray(readInt64VectorAsArray()); | 
|  |  | 
|  | return new ArrayList<Long>(Arrays.asList(array)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a Float vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<Float> readFloatVector() { | 
|  | Float[] array = HwBlob.wrapArray(readFloatVectorAsArray()); | 
|  |  | 
|  | return new ArrayList<Float>(Arrays.asList(array)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a Double vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<Double> readDoubleVector() { | 
|  | Double[] array = HwBlob.wrapArray(readDoubleVectorAsArray()); | 
|  |  | 
|  | return new ArrayList<Double>(Arrays.asList(array)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convenience method to read a String vector as an ArrayList. | 
|  | * @return array of parsed values. | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public final ArrayList<String> readStringVector() { | 
|  | return new ArrayList<String>(Arrays.asList(readStringVectorAsArray())); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Reads a strong binder value from the parcel. | 
|  | * @return binder object read from parcel or null if no binder can be read | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final IHwBinder readStrongBinder(); | 
|  |  | 
|  | /** | 
|  | * Read opaque segment of data as a blob. | 
|  | * @return blob of size expectedSize | 
|  | * @throws IllegalArgumentException if the parcel has no more data | 
|  | */ | 
|  | public native final HwBlob readBuffer(long expectedSize); | 
|  |  | 
|  | /** | 
|  | * Read a buffer written using scatter gather. | 
|  | * | 
|  | * @param expectedSize size that buffer should be | 
|  | * @param parentHandle handle from which to read the embedded buffer | 
|  | * @param offset offset into parent | 
|  | * @param nullable whether or not to allow for a null return | 
|  | * @return blob of data with size expectedSize | 
|  | * @throws NoSuchElementException if an embedded buffer is not available to read | 
|  | * @throws IllegalArgumentException if expectedSize < 0 | 
|  | * @throws NullPointerException if the transaction specified the blob to be null | 
|  | *    but nullable is false | 
|  | */ | 
|  | public native final HwBlob readEmbeddedBuffer( | 
|  | long expectedSize, long parentHandle, long offset, | 
|  | boolean nullable); | 
|  |  | 
|  | /** | 
|  | * Write a buffer into the transaction. | 
|  | * @param blob blob to write into the parcel. | 
|  | */ | 
|  | public native final void writeBuffer(HwBlob blob); | 
|  | /** | 
|  | * Write a status value into the blob. | 
|  | * @param status value to write | 
|  | */ | 
|  | public native final void writeStatus(int status); | 
|  | /** | 
|  | * @throws IllegalArgumentException if a success vaue cannot be read | 
|  | * @throws RemoteException if success value indicates a transaction error | 
|  | */ | 
|  | public native final void verifySuccess(); | 
|  | /** | 
|  | * Should be called to reduce memory pressure when this object no longer needs | 
|  | * to be written to. | 
|  | */ | 
|  | public native final void releaseTemporaryStorage(); | 
|  | /** | 
|  | * Should be called when object is no longer needed to reduce possible memory | 
|  | * pressure if the Java GC does not get to this object in time. | 
|  | */ | 
|  | public native final void release(); | 
|  |  | 
|  | /** | 
|  | * Sends the parcel to the specified destination. | 
|  | */ | 
|  | public native final void send(); | 
|  |  | 
|  | // Returns address of the "freeFunction". | 
|  | private static native final long native_init(); | 
|  |  | 
|  | private native final void native_setup(boolean allocate); | 
|  |  | 
|  | static { | 
|  | long freeFunction = native_init(); | 
|  |  | 
|  | sNativeRegistry = new NativeAllocationRegistry( | 
|  | HwParcel.class.getClassLoader(), | 
|  | freeFunction, | 
|  | 128 /* size */); | 
|  | } | 
|  |  | 
|  | private long mNativeContext; | 
|  | } | 
|  |  |