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

Commit c3c2d8da authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Support Parcel.write/readFileDescriptor" into aosp-main-future

parents 2efd2a18 44169e0c
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -434,7 +434,6 @@ public final class Parcel {
    @RavenwoodThrow
    private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
    @FastNative
    @RavenwoodThrow
    private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);

    private static native byte[] nativeCreateByteArray(long nativePtr);
@@ -456,7 +455,6 @@ public final class Parcel {
    @RavenwoodThrow
    private static native IBinder nativeReadStrongBinder(long nativePtr);
    @FastNative
    @RavenwoodThrow
    private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);

    private static native long nativeCreate();
+2 −0
Original line number Diff line number Diff line
@@ -381,6 +381,8 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
    }

    private static void closeInternal$ravenwood(FileDescriptor fd) {
        // Desktop JVM doesn't have FileDescriptor.close(), so we'll need to go to the ravenwood
        // side to close it.
        native_close$ravenwood(fd);
    }

+13 −6
Original line number Diff line number Diff line
@@ -25,19 +25,24 @@ import static android.os.ParcelFileDescriptor.MODE_WORLD_READABLE;
import static android.os.ParcelFileDescriptor.MODE_WORLD_WRITEABLE;
import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;

import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.ravenwood.common.JvmWorkaround;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;

public class ParcelFileDescriptor_host {
    private static final String TAG = "ParcelFileDescriptor_host";

    /**
     * Since we don't have a great way to keep an unmanaged {@code FileDescriptor} reference
     * alive, we keep a strong reference to the {@code RandomAccessFile} we used to open it. This
@@ -98,16 +103,18 @@ public class ParcelFileDescriptor_host {
        synchronized (sActive) {
            raf = sActive.remove(fd);
        }
        int fdInt = JvmWorkaround.getInstance().getFdInt(fd);
        try {
            if (raf != null) {
                raf.close();
            } else {
                // Odd, we don't remember opening this ourselves, but let's release the
                // underlying resource as requested
                System.err.println("Closing unknown FileDescriptor: " + fd);
                new FileOutputStream(fd).close();
                // This FD wasn't created by native_open$ravenwood().
                // The FD was passed to the PFD ctor. Just close it.
                Os.close(fd);
            }
        } catch (IOException ignored) {
        } catch (IOException | ErrnoException e) {
            Log.w(TAG, "Exception thrown while closing fd " + fdInt, e);
        }
    }
}
;
 No newline at end of file
+135 −12
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@
 */
package com.android.platform.test.ravenwood.nativesubstitution;

import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;

import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@@ -31,6 +36,8 @@ import java.util.concurrent.atomic.AtomicLong;
 * {@link ByteBuffer} wouldn't allow...)
 */
public class Parcel_host {
    private static final String TAG = "Parcel";

    private Parcel_host() {
    }

@@ -50,6 +57,11 @@ public class Parcel_host {
    // TODO Use the actual value from Parcel.java.
    private static final int OK = 0;

    private final Map<Integer, FileDescriptor> mFdMap = new ConcurrentHashMap<>();

    private static final int FD_PLACEHOLDER = 0xDEADBEEF;
    private static final int FD_PAYLOAD_SIZE = 8;

    private void validate() {
        if (mDeleted) {
            // TODO: Put more info
@@ -67,6 +79,7 @@ public class Parcel_host {
        return p;
    }

    /** Native method substitution */
    public static long nativeCreate() {
        final long id = sNextId.getAndIncrement();
        final Parcel_host p = new Parcel_host();
@@ -80,7 +93,8 @@ public class Parcel_host {
        mSize = 0;
        mPos = 0;
        mSensitive = false;
        mAllowFds = false;
        mAllowFds = true;
        mFdMap.clear();
    }

    private void updateSize() {
@@ -89,16 +103,19 @@ public class Parcel_host {
        }
    }

    /** Native method substitution */
    public static void nativeDestroy(long nativePtr) {
        getInstance(nativePtr).mDeleted = true;
        sInstances.remove(nativePtr);
    }

    /** Native method substitution */
    public static void nativeFreeBuffer(long nativePtr) {
        getInstance(nativePtr).freeBuffer();
    }

    public void freeBuffer() {
    /** Native method substitution */
    private void freeBuffer() {
        init();
    }

@@ -137,32 +154,47 @@ public class Parcel_host {
        }
    }

    /** Native method substitution */
    public static void nativeMarkSensitive(long nativePtr) {
        getInstance(nativePtr).mSensitive = true;
    }

    /** Native method substitution */
    public static int nativeDataSize(long nativePtr) {
        return getInstance(nativePtr).mSize;
    }

    /** Native method substitution */
    public static int nativeDataAvail(long nativePtr) {
        var p = getInstance(nativePtr);
        return p.mSize - p.mPos;
    }

    /** Native method substitution */
    public static int nativeDataPosition(long nativePtr) {
        return getInstance(nativePtr).mPos;
    }

    /** Native method substitution */
    public static int nativeDataCapacity(long nativePtr) {
        return getInstance(nativePtr).mBuffer.length;
    }

    /** Native method substitution */
    public static void nativeSetDataSize(long nativePtr, int size) {
        var p = getInstance(nativePtr);
        p.ensureCapacity(size);
        getInstance(nativePtr).mSize = size;
    }

    /** Native method substitution */
    public static void nativeSetDataPosition(long nativePtr, int pos) {
        var p = getInstance(nativePtr);
        // TODO: Should this change the size or the capacity??
        p.mPos = pos;
    }

    /** Native method substitution */
    public static void nativeSetDataCapacity(long nativePtr, int size) {
        if (size < 0) {
            throw new IllegalArgumentException("size < 0: size=" + size);
@@ -173,20 +205,25 @@ public class Parcel_host {
        }
    }

    /** Native method substitution */
    public static boolean nativePushAllowFds(long nativePtr, boolean allowFds) {
        var p = getInstance(nativePtr);
        var prev = p.mAllowFds;
        p.mAllowFds = allowFds;
        return prev;
    }

    /** Native method substitution */
    public static void nativeRestoreAllowFds(long nativePtr, boolean lastValue) {
        getInstance(nativePtr).mAllowFds = lastValue;
    }

    /** Native method substitution */
    public static void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len) {
        nativeWriteBlob(nativePtr, b, offset, len);
    }

    /** Native method substitution */
    public static void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len) {
        var p = getInstance(nativePtr);

@@ -205,6 +242,7 @@ public class Parcel_host {
        }
    }

    /** Native method substitution */
    public static int nativeWriteInt(long nativePtr, int value) {
        var p = getInstance(nativePtr);
        p.ensureMoreCapacity(Integer.BYTES);
@@ -219,14 +257,19 @@ public class Parcel_host {
        return OK;
    }

    /** Native method substitution */
    public static int nativeWriteLong(long nativePtr, long value) {
        nativeWriteInt(nativePtr, (int) (value >>> 32));
        nativeWriteInt(nativePtr, (int) (value));
        return OK;
    }

    /** Native method substitution */
    public static int nativeWriteFloat(long nativePtr, float val) {
        return nativeWriteInt(nativePtr, Float.floatToIntBits(val));
    }

    /** Native method substitution */
    public static int nativeWriteDouble(long nativePtr, double val) {
        return nativeWriteLong(nativePtr, Double.doubleToLongBits(val));
    }
@@ -235,6 +278,7 @@ public class Parcel_host {
        return ((val + 3) / 4) * 4;
    }

    /** Native method substitution */
    public static void nativeWriteString8(long nativePtr, String val) {
        if (val == null) {
            nativeWriteBlob(nativePtr, null, 0, 0);
@@ -243,15 +287,19 @@ public class Parcel_host {
            nativeWriteBlob(nativePtr, bytes, 0, bytes.length);
        }
    }

    /** Native method substitution */
    public static void nativeWriteString16(long nativePtr, String val) {
        // Just reuse String8
        nativeWriteString8(nativePtr, val);
    }

    /** Native method substitution */
    public static byte[] nativeCreateByteArray(long nativePtr) {
        return nativeReadBlob(nativePtr);
    }

    /** Native method substitution */
    public static boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen) {
        if (dest == null) {
            return false;
@@ -271,6 +319,7 @@ public class Parcel_host {
        return true;
    }

    /** Native method substitution */
    public static byte[] nativeReadBlob(long nativePtr) {
        var p = getInstance(nativePtr);
        if (p.mSize - p.mPos < 4) {
@@ -295,6 +344,8 @@ public class Parcel_host {

        return bytes;
    }

    /** Native method substitution */
    public static int nativeReadInt(long nativePtr) {
        var p = getInstance(nativePtr);

@@ -310,19 +361,24 @@ public class Parcel_host {

        return ret;
    }

    /** Native method substitution */
    public static long nativeReadLong(long nativePtr) {
        return (((long) nativeReadInt(nativePtr)) << 32)
                | (((long) nativeReadInt(nativePtr)) & 0xffff_ffffL);
    }

    /** Native method substitution */
    public static float nativeReadFloat(long nativePtr) {
        return Float.intBitsToFloat(nativeReadInt(nativePtr));
    }

    /** Native method substitution */
    public static double nativeReadDouble(long nativePtr) {
        return Double.longBitsToDouble(nativeReadLong(nativePtr));
    }

    /** Native method substitution */
    public static String nativeReadString8(long nativePtr) {
        final var bytes = nativeReadBlob(nativePtr);
        if (bytes == null) {
@@ -334,10 +390,13 @@ public class Parcel_host {
        return nativeReadString8(nativePtr);
    }

    /** Native method substitution */
    public static byte[] nativeMarshall(long nativePtr) {
        var p = getInstance(nativePtr);
        return Arrays.copyOf(p.mBuffer, p.mSize);
    }

    /** Native method substitution */
    public static void nativeUnmarshall(
            long nativePtr, byte[] data, int offset, int length) {
        var p = getInstance(nativePtr);
@@ -346,6 +405,8 @@ public class Parcel_host {
        p.mPos += length;
        p.updateSize();
    }

    /** Native method substitution */
    public static int nativeCompareData(long thisNativePtr, long otherNativePtr) {
        var a = getInstance(thisNativePtr);
        var b = getInstance(otherNativePtr);
@@ -355,6 +416,8 @@ public class Parcel_host {
            return -1;
        }
    }

    /** Native method substitution */
    public static boolean nativeCompareDataInRange(
            long ptrA, int offsetA, long ptrB, int offsetB, int length) {
        var a = getInstance(ptrA);
@@ -368,6 +431,8 @@ public class Parcel_host {
        return Arrays.equals(Arrays.copyOfRange(a.mBuffer, offsetA, offsetA + length),
                Arrays.copyOfRange(b.mBuffer, offsetB, offsetB + length));
    }

    /** Native method substitution */
    public static void nativeAppendFrom(
            long thisNativePtr, long otherNativePtr, int srcOffset, int length) {
        var dst = getInstance(thisNativePtr);
@@ -382,25 +447,83 @@ public class Parcel_host {
        // TODO: Update the other's position?
    }

    public static boolean nativeHasFileDescriptors(long nativePtr) {
        // Assume false for now, because we don't support writing FDs yet.
    /** Native method substitution */
    public static boolean nativeHasBinders(long nativePtr) {
        // Assume false for now, because we don't support adding binders.
        return false;
    }

    public static boolean nativeHasFileDescriptorsInRange(
    /** Native method substitution */
    public static boolean nativeHasBindersInRange(
            long nativePtr, int offset, int length) {
        // Assume false for now, because we don't support writing FDs yet.
        return false;
    }

    public static boolean nativeHasBinders(long nativePtr) {
        // Assume false for now, because we don't support adding binders.
        return false;
    /** Native method substitution */
    public static void nativeWriteFileDescriptor(long nativePtr, java.io.FileDescriptor val) {
        var p = getInstance(nativePtr);

        if (!p.mAllowFds) {
            // Simulate the FDS_NOT_ALLOWED case in frameworks/base/core/jni/android_util_Binder.cpp
            throw new RuntimeException("Not allowed to write file descriptors here");
        }

    public static boolean nativeHasBindersInRange(
            long nativePtr, int offset, int length) {
        // Assume false for now, because we don't support writing FDs yet.
        FileDescriptor dup = null;
        try {
            dup = Os.dup(val);
        } catch (ErrnoException e) {
            throw new RuntimeException(e);
        }
        p.mFdMap.put(p.mPos, dup);

        // Parcel.cpp writes two int32s for a FD.
        // Make sure FD_PAYLOAD_SIZE is in sync with this code.
        nativeWriteInt(nativePtr, FD_PLACEHOLDER);
        nativeWriteInt(nativePtr, FD_PLACEHOLDER);
    }

    /** Native method substitution */
    public static java.io.FileDescriptor nativeReadFileDescriptor(long nativePtr) {
        var p = getInstance(nativePtr);

        var pos = p.mPos;
        var fd = p.mFdMap.get(pos);

        if (fd == null) {
            Log.w(TAG, "nativeReadFileDescriptor: Not a FD at pos #" + pos);
            return null;
        }
        nativeReadInt(nativePtr);
        return fd;
    }

    /** Native method substitution */
    public static boolean nativeHasFileDescriptors(long nativePtr) {
        var p = getInstance(nativePtr);
        return p.mFdMap.size() > 0;
    }

    /** Native method substitution */
    public static boolean nativeHasFileDescriptorsInRange(long nativePtr, int offset, int length) {
        var p = getInstance(nativePtr);

        // Original code: hasFileDescriptorsInRange() in frameworks/native/libs/binder/Parcel.cpp
        if (offset < 0 || length < 0) {
            throw new IllegalArgumentException("Negative value not allowed: offset=" + offset
                    + " length=" + length);
        }
        long limit = (long) offset + (long) length;
        if (limit > p.mSize) {
            throw new IllegalArgumentException("Out of range: offset=" + offset
                    + " length=" + length + " dataSize=" + p.mSize);
        }

        for (var pos : p.mFdMap.keySet()) {
            if (offset <= pos && (pos + FD_PAYLOAD_SIZE - 1) < (offset + length)) {
                return true;
            }
        }
        return false;
    }
}
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -53,4 +53,9 @@ public final class Os {
    public static StructStat stat(String path) throws ErrnoException {
        return RavenwoodRuntimeNative.stat(path);
    }

    /** Ravenwood version of the OS API. */
    public static void close(FileDescriptor fd) throws ErrnoException {
        RavenwoodRuntimeNative.close(fd);
    }
}
Loading