Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e1d8d24 authored by Steven Moreland's avatar Steven Moreland Committed by Gerrit Code Review
Browse files

Merge "Implementing support for HIDL native handles in Java"

parents 1f077d90 9850dd97
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -898,6 +898,7 @@ java_library {
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/NativeHandle.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/util/AndroidException.java",
        "core/java/android/util/AndroidException.java",
    ],
    ],
@@ -1444,6 +1445,7 @@ droiddoc {
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/NativeHandle.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/util/AndroidException.java",
        "core/java/android/util/AndroidException.java",
    ],
    ],
+18 −0
Original line number Original line Diff line number Diff line
@@ -3726,6 +3726,7 @@ package android.os {
    method public final void putInt64Array(long, long[]);
    method public final void putInt64Array(long, long[]);
    method public final void putInt8(long, byte);
    method public final void putInt8(long, byte);
    method public final void putInt8Array(long, byte[]);
    method public final void putInt8Array(long, byte[]);
    method public final void putNativeHandle(long, android.os.NativeHandle);
    method public final void putString(long, java.lang.String);
    method public final void putString(long, java.lang.String);
    method public static java.lang.Boolean[] wrapArray(boolean[]);
    method public static java.lang.Boolean[] wrapArray(boolean[]);
    method public static java.lang.Long[] wrapArray(long[]);
    method public static java.lang.Long[] wrapArray(long[]);
@@ -3745,6 +3746,7 @@ package android.os {
    method public final double readDouble();
    method public final double readDouble();
    method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
    method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
    method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
    method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
    method public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
    method public final float readFloat();
    method public final float readFloat();
    method public final java.util.ArrayList<java.lang.Float> readFloatVector();
    method public final java.util.ArrayList<java.lang.Float> readFloatVector();
    method public final short readInt16();
    method public final short readInt16();
@@ -3755,6 +3757,8 @@ package android.os {
    method public final java.util.ArrayList<java.lang.Long> readInt64Vector();
    method public final java.util.ArrayList<java.lang.Long> readInt64Vector();
    method public final byte readInt8();
    method public final byte readInt8();
    method public final java.util.ArrayList<java.lang.Byte> readInt8Vector();
    method public final java.util.ArrayList<java.lang.Byte> readInt8Vector();
    method public final android.os.NativeHandle readNativeHandle();
    method public final java.util.ArrayList<android.os.NativeHandle> readNativeHandleVector();
    method public final java.lang.String readString();
    method public final java.lang.String readString();
    method public final java.util.ArrayList<java.lang.String> readStringVector();
    method public final java.util.ArrayList<java.lang.String> readStringVector();
    method public final android.os.IHwBinder readStrongBinder();
    method public final android.os.IHwBinder readStrongBinder();
@@ -3778,6 +3782,8 @@ package android.os {
    method public final void writeInt8(byte);
    method public final void writeInt8(byte);
    method public final void writeInt8Vector(java.util.ArrayList<java.lang.Byte>);
    method public final void writeInt8Vector(java.util.ArrayList<java.lang.Byte>);
    method public final void writeInterfaceToken(java.lang.String);
    method public final void writeInterfaceToken(java.lang.String);
    method public final void writeNativeHandle(android.os.NativeHandle);
    method public final void writeNativeHandleVector(java.util.ArrayList<android.os.NativeHandle>);
    method public final void writeStatus(int);
    method public final void writeStatus(int);
    method public final void writeString(java.lang.String);
    method public final void writeString(java.lang.String);
    method public final void writeStringVector(java.util.ArrayList<java.lang.String>);
    method public final void writeStringVector(java.util.ArrayList<java.lang.String>);
@@ -3822,6 +3828,18 @@ package android.os {
    field public static final android.os.Parcelable.Creator<android.os.IncidentReportArgs> CREATOR;
    field public static final android.os.Parcelable.Creator<android.os.IncidentReportArgs> CREATOR;
  }
  }


  public final class NativeHandle implements java.io.Closeable {
    ctor public NativeHandle();
    ctor public NativeHandle(java.io.FileDescriptor, boolean);
    ctor public NativeHandle(java.io.FileDescriptor[], int[], boolean);
    method public void close() throws java.io.IOException;
    method public android.os.NativeHandle dup() throws java.io.IOException;
    method public java.io.FileDescriptor getFileDescriptor();
    method public java.io.FileDescriptor[] getFileDescriptors();
    method public int[] getInts();
    method public boolean hasSingleFileDescriptor();
  }

  public final class PowerManager {
  public final class PowerManager {
    method public void userActivity(long, int, int);
    method public void userActivity(long, int, int);
    field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
    field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
+8 −0
Original line number Original line Diff line number Diff line
@@ -232,6 +232,14 @@ public class HwBlob {
     * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jstring)] is out of range
     * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jstring)] is out of range
     */
     */
    public native final void putString(long offset, String x);
    public native final void putString(long offset, String x);
    /**
     * Writes a native handle (without duplicating the underlying file descriptors) at an offset.
     *
     * @param offset location to write value
     * @param x a {@link NativeHandle} instance to write
     * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jobject)] is out of range
     */
    public native final void putNativeHandle(long offset, NativeHandle x);


    /**
    /**
     * Put a boolean array contiguously at an offset in the blob.
     * Put a boolean array contiguously at an offset in the blob.
+59 −0
Original line number Original line Diff line number Diff line
@@ -115,6 +115,13 @@ public class HwParcel {
     * @param val to write
     * @param val to write
     */
     */
    public native final void writeString(String val);
    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.
     * Writes an array of boolean values to the end of the parcel.
@@ -159,6 +166,11 @@ public class HwParcel {
     * @param val to write
     * @param val to write
     */
     */
    private native final void writeStringVector(String[] val);
    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.
     * Helper method to write a list of Booleans to val.
@@ -266,6 +278,14 @@ public class HwParcel {
        writeStringVector(val.toArray(new String[val.size()]));
        writeStringVector(val.toArray(new String[val.size()]));
    }
    }


    /**
     * 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.
     * Write a hwbinder object to the end of the parcel.
     * @param binder value to write
     * @param binder value to write
@@ -328,6 +348,30 @@ public class HwParcel {
     * @throws IllegalArgumentException if the parcel has no more data
     * @throws IllegalArgumentException if the parcel has no more data
     */
     */
    public native final String readString();
    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.
     * Reads an array of boolean values from the parcel.
@@ -377,6 +421,12 @@ public class HwParcel {
     * @throws IllegalArgumentException if the parcel has no more data
     * @throws IllegalArgumentException if the parcel has no more data
     */
     */
    private native final String[] readStringVectorAsArray();
    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.
     * Convenience method to read a Boolean vector as an ArrayList.
@@ -464,6 +514,15 @@ public class HwParcel {
        return new ArrayList<String>(Arrays.asList(readStringVectorAsArray()));
        return new ArrayList<String>(Arrays.asList(readStringVectorAsArray()));
    }
    }


    /**
     * 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.
     * Reads a strong binder value from the parcel.
     * @return binder object read from parcel or null if no binder can be read
     * @return binder object read from parcel or null if no binder can be read
+191 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2018 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.NonNull;
import android.annotation.SystemApi;
import android.system.ErrnoException;
import android.system.Os;

import java.io.Closeable;
import java.io.FileDescriptor;

/**
 * Collection representing a set of open file descriptors and an opaque data stream.
 *
 * @hide
 */
@SystemApi
public final class NativeHandle implements Closeable {
    // whether this object owns mFds
    private boolean mOwn = false;
    private FileDescriptor[] mFds;
    private int[] mInts;

    /**
     * Constructs a {@link NativeHandle} object containing
     * zero file descriptors and an empty data stream.
     */
    public NativeHandle() {
        this(new FileDescriptor[0], new int[0], false);
    }

    /**
     * Constructs a {@link NativeHandle} object containing the given
     * {@link FileDescriptor} object and an empty data stream.
     */
    public NativeHandle(@NonNull FileDescriptor descriptor, boolean own) {
        this(new FileDescriptor[] {descriptor}, new int[0], own);
    }

    /**
     * Convenience method for creating a list of file descriptors.
     *
     * @hide
     */
    private static FileDescriptor[] createFileDescriptorArray(@NonNull int[] fds) {
        FileDescriptor[] list = new FileDescriptor[fds.length];
        for (int i = 0; i < fds.length; i++) {
            FileDescriptor descriptor = new FileDescriptor();
            descriptor.setInt$(fds[i]);
            list[i] = descriptor;
        }
        return list;
    }

    /**
     * Convenience method for instantiating a {@link NativeHandle} from JNI. It does
     * not take ownership of the int[] params. It does not dupe the FileDescriptors.
     *
     * @hide
     */
    private NativeHandle(@NonNull int[] fds, @NonNull int[] ints, boolean own) {
        this(createFileDescriptorArray(fds), ints, own);
    }

    /**
     * Instantiate an opaque {@link NativeHandle} from fds and integers.
     *
     * @param own whether the fds are owned by this object and should be closed
     */
    public NativeHandle(@NonNull FileDescriptor[] fds, @NonNull int[] ints, boolean own) {
        mFds = fds.clone();
        mInts = ints.clone();
        mOwn = own;
    }

    /**
     * Returns whether this {@link NativeHandle} object contains a single file
     * descriptor and nothing else.
     *
     * @return a boolean value
     */
    public boolean hasSingleFileDescriptor() {
        return mFds.length == 1 && mInts.length == 0;
    }

    /**
     * Explicitly duplicate NativeHandle (this dups all file descritptors).
     */
    public NativeHandle dup() throws java.io.IOException {
        FileDescriptor[] fds = new FileDescriptor[mFds.length];
        try {
            for (int i = 0; i < mFds.length; i++) {
                fds[i] = Os.dup(mFds[i]);
            }
        } catch (ErrnoException e) {
            e.rethrowAsIOException();
        }
        return new NativeHandle(fds, mInts, true /*own*/);
    }

    /**
     * Closes the file descriptors if they are owned by this object.
     *
     * This also invalidates the object.
     */
    @Override
    public void close() throws java.io.IOException {
        if (!mOwn) {
            return;
        }

        try {
            for (FileDescriptor fd : mFds) {
                Os.close(fd);
            }
        } catch (ErrnoException e) {
            e.rethrowAsIOException();
        }

        mOwn = false;
        mFds = null;
        mInts = null;
    }

    /**
     * Returns the underlying lone file descriptor.
     *
     * @return a {@link FileDescriptor} object
     * @throws IllegalStateException if this object contains either zero or
     *         more than one file descriptor, or a non-empty data stream.
     */
    public FileDescriptor getFileDescriptor() {
        if (!hasSingleFileDescriptor()) {
            throw new IllegalStateException(
                    "NativeHandle is not single file descriptor. Contents must"
                    + " be retreived through getFileDescriptors and getInts.");
        }

        return mFds[0];
    }

    /**
     * Convenience method for fetching this object's file descriptors from JNI.
     * @return a mutable copy of the underlying file descriptors (as an int[])
     *
     * @hide
     */
    private int[] getFdsAsIntArray() {
        int numFds = mFds.length;
        int[] fds = new int[numFds];

        for (int i = 0; i < numFds; i++) {
            fds[i] = mFds[i].getInt$();
        }

        return fds;
    }

    /**
     * Fetch file descriptors.
     *
     * @return the fds.
     */
    public FileDescriptor[] getFileDescriptors() {
        return mFds;
    }

    /**
     * Fetch opaque ints. Note: This object retains ownership of the data.
     *
     * @return the opaque data stream.
     */
    public int[] getInts() {
        return mInts;
    }
}
Loading