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