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

Commit bc600d32 authored by Steven Moreland's avatar Steven Moreland Committed by android-build-merger
Browse files

Merge "Implementing support for HIDL native handles in Java" am: 1e1d8d24 am: 65808029

am: 4a656644

Change-Id: I649a10172d93beae9063ec2170e60aa4967ba0be
parents 6e68dc71 4a656644
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -906,6 +906,7 @@ java_library {
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/NativeHandle.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/util/AndroidException.java",
    ],
@@ -1451,6 +1452,7 @@ droiddoc {
        "core/java/android/os/IHwInterface.java",
        "core/java/android/os/DeadObjectException.java",
        "core/java/android/os/DeadSystemException.java",
        "core/java/android/os/NativeHandle.java",
        "core/java/android/os/RemoteException.java",
        "core/java/android/util/AndroidException.java",
    ],
+18 −0
Original line number Diff line number Diff line
@@ -3835,6 +3835,7 @@ package android.os {
    method public final void putInt64Array(long, long[]);
    method public final void putInt8(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 static java.lang.Boolean[] wrapArray(boolean[]);
    method public static java.lang.Long[] wrapArray(long[]);
@@ -3854,6 +3855,7 @@ package android.os {
    method public final double readDouble();
    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.NativeHandle readEmbeddedNativeHandle(long, long);
    method public final float readFloat();
    method public final java.util.ArrayList<java.lang.Float> readFloatVector();
    method public final short readInt16();
@@ -3864,6 +3866,8 @@ package android.os {
    method public final java.util.ArrayList<java.lang.Long> readInt64Vector();
    method public final byte readInt8();
    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.util.ArrayList<java.lang.String> readStringVector();
    method public final android.os.IHwBinder readStrongBinder();
@@ -3887,6 +3891,8 @@ package android.os {
    method public final void writeInt8(byte);
    method public final void writeInt8Vector(java.util.ArrayList<java.lang.Byte>);
    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 writeString(java.lang.String);
    method public final void writeStringVector(java.util.ArrayList<java.lang.String>);
@@ -3932,6 +3938,18 @@ package android.os {
    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 {
    method public void userActivity(long, int, int);
    field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
+8 −0
Original line number Diff line number Diff line
@@ -232,6 +232,14 @@ public class HwBlob {
     * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jstring)] is out of range
     */
    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.
+59 −0
Original line number Diff line number Diff line
@@ -115,6 +115,13 @@ public class HwParcel {
     * @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 @@ public class HwParcel {
     * @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.
@@ -266,6 +278,14 @@ public class HwParcel {
        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.
     * @param binder value to write
@@ -328,6 +348,30 @@ public class HwParcel {
     * @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 @@ public class HwParcel {
     * @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.
@@ -464,6 +514,15 @@ public class HwParcel {
        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.
     * @return binder object read from parcel or null if no binder can be read
+191 −0
Original line number 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