Implementing support for HIDL native handles in Java
This change implements the equivalent of the C++ native_handle_t type in
Java. Similar to the C++ type, the NativeHandle class wraps an arraylist
of FileDescriptor objects, along with a raw data stream (integer array).
Bug: 35098567
Test: Ran m, hidl_test (C++ and Java). Functionality tests are included
in a separate CL.
Change-Id: Ic53f9a49ae17ce5708577a586230126ab0e222c7
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index 0eb62c95..7a51db2 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -115,6 +115,13 @@
* @param val to write
*/
public native final void writeString(String val);
+ /**
+ * Writes a native handle (without duplicating the underlying
+ * file descriptors) to the end of the parcel.
+ *
+ * @param val to write
+ */
+ public native final void writeNativeHandle(NativeHandle val);
/**
* Writes an array of boolean values to the end of the parcel.
@@ -159,6 +166,11 @@
* @param val to write
*/
private native final void writeStringVector(String[] val);
+ /**
+ * Writes an array of native handles to the end of the parcel.
+ * @param val array of {@link NativeHandle} objects to write
+ */
+ private native final void writeNativeHandleVector(NativeHandle[] val);
/**
* Helper method to write a list of Booleans to val.
@@ -267,6 +279,14 @@
}
/**
+ * Helper method to write a list of native handles to the end of the parcel.
+ * @param val list of {@link NativeHandle} objects to write
+ */
+ public final void writeNativeHandleVector(ArrayList<NativeHandle> val) {
+ writeNativeHandleVector(val.toArray(new NativeHandle[val.size()]));
+ }
+
+ /**
* Write a hwbinder object to the end of the parcel.
* @param binder value to write
*/
@@ -328,6 +348,30 @@
* @throws IllegalArgumentException if the parcel has no more data
*/
public native final String readString();
+ /**
+ * Reads a native handle (without duplicating the underlying file
+ * descriptors) from the parcel. These file descriptors will only
+ * be open for the duration that the binder window is open. If they
+ * are needed further, you must call {@link NativeHandle#dup()}.
+ *
+ * @return a {@link NativeHandle} instance parsed from the parcel
+ * @throws IllegalArgumentException if the parcel has no more data
+ */
+ public native final NativeHandle readNativeHandle();
+ /**
+ * Reads an embedded native handle (without duplicating the underlying
+ * file descriptors) from the parcel. These file descriptors will only
+ * be open for the duration that the binder window is open. If they
+ * are needed further, you must call {@link NativeHandle#dup()}. You
+ * do not need to call close on the NativeHandle returned from this.
+ *
+ * @param parentHandle handle from which to read the embedded object
+ * @param offset offset into parent
+ * @return a {@link NativeHandle} instance parsed from the parcel
+ * @throws IllegalArgumentException if the parcel has no more data
+ */
+ public native final NativeHandle readEmbeddedNativeHandle(
+ long parentHandle, long offset);
/**
* Reads an array of boolean values from the parcel.
@@ -377,6 +421,12 @@
* @throws IllegalArgumentException if the parcel has no more data
*/
private native final String[] readStringVectorAsArray();
+ /**
+ * Reads an array of native handles from the parcel.
+ * @return array of {@link NativeHandle} objects
+ * @throws IllegalArgumentException if the parcel has no more data
+ */
+ private native final NativeHandle[] readNativeHandleAsArray();
/**
* Convenience method to read a Boolean vector as an ArrayList.
@@ -465,6 +515,15 @@
}
/**
+ * Convenience method to read a vector of native handles as an ArrayList.
+ * @return array of {@link NativeHandle} objects.
+ * @throws IllegalArgumentException if the parcel has no more data
+ */
+ public final ArrayList<NativeHandle> readNativeHandleVector() {
+ return new ArrayList<NativeHandle>(Arrays.asList(readNativeHandleAsArray()));
+ }
+
+ /**
* 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