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

Commit 8a299287 authored by Khoa Hong's avatar Khoa Hong Committed by Automerger Merge Worker
Browse files

Merge "Add protections against queueing a UsbRequest when the underlying...

Merge "Add protections against queueing a UsbRequest when the underlying UsbDeviceConnection is closed." into rvc-dev am: 046dc1b7 am: a4ebf141 am: c1c23d0e am: 4119e4ae am: fce17d77 am: 864175c8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20210471



Change-Id: I70e4fb3012819dc2f1697923cbce21f59ad779f3
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents df53ce5d 864175c8
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -107,6 +107,34 @@ public class UsbDeviceConnection {
        }
    }

    /**
     * This is meant to be called by UsbRequest's queue() in order to synchronize on
     * UsbDeviceConnection's mLock to prevent the connection being closed while queueing.
     */
    /* package */ boolean queueRequest(UsbRequest request, ByteBuffer buffer, int length) {
        synchronized (mLock) {
            if (!isOpen()) {
                return false;
            }

            return request.queueIfConnectionOpen(buffer, length);
        }
    }

    /**
     * This is meant to be called by UsbRequest's queue() in order to synchronize on
     * UsbDeviceConnection's mLock to prevent the connection being closed while queueing.
     */
    /* package */ boolean queueRequest(UsbRequest request, @Nullable ByteBuffer buffer) {
        synchronized (mLock) {
            if (!isOpen()) {
                return false;
            }

            return request.queueIfConnectionOpen(buffer);
        }
    }

    /**
     * Releases all system resources related to the device.
     * Once the object is closed it cannot be used again.
+58 −10
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ public class UsbRequest {
     * Releases all resources related to this request.
     */
    public void close() {
        synchronized (mLock) {
            if (mNativeContext != 0) {
                mEndpoint = null;
                mConnection = null;
@@ -120,6 +121,7 @@ public class UsbRequest {
                mCloseGuard.close();
            }
        }
    }

    @Override
    protected void finalize() throws Throwable {
@@ -191,10 +193,32 @@ public class UsbRequest {
     */
    @Deprecated
    public boolean queue(ByteBuffer buffer, int length) {
        UsbDeviceConnection connection = mConnection;
        if (connection == null) {
            // The expected exception by CTS Verifier - USB Device test
            throw new NullPointerException("invalid connection");
        }

        // Calling into the underlying UsbDeviceConnection to synchronize on its lock, to prevent
        // the connection being closed while queueing.
        return connection.queueRequest(this, buffer, length);
    }

    /**
     * This is meant to be called from UsbDeviceConnection after synchronizing using the lock over
     * there, to prevent the connection being closed while queueing.
     */
    /* package */ boolean queueIfConnectionOpen(ByteBuffer buffer, int length) {
        UsbDeviceConnection connection = mConnection;
        if (connection == null || !connection.isOpen()) {
            // The expected exception by CTS Verifier - USB Device test
            throw new NullPointerException("invalid connection");
        }

        boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
        boolean result;

        if (mConnection.getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P
        if (connection.getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P
                && length > MAX_USBFS_BUFFER_SIZE) {
            length = MAX_USBFS_BUFFER_SIZE;
        }
@@ -243,6 +267,28 @@ public class UsbRequest {
     * @return true if the queueing operation succeeded
     */
    public boolean queue(@Nullable ByteBuffer buffer) {
        UsbDeviceConnection connection = mConnection;
        if (connection == null) {
            // The expected exception by CTS Verifier - USB Device test
            throw new IllegalStateException("invalid connection");
        }

        // Calling into the underlying UsbDeviceConnection to synchronize on its lock, to prevent
        // the connection being closed while queueing.
        return connection.queueRequest(this, buffer);
    }

    /**
     * This is meant to be called from UsbDeviceConnection after synchronizing using the lock over
     * there, to prevent the connection being closed while queueing.
     */
    /* package */ boolean queueIfConnectionOpen(@Nullable ByteBuffer buffer) {
        UsbDeviceConnection connection = mConnection;
        if (connection == null || !connection.isOpen()) {
            // The expected exception by CTS Verifier - USB Device test
            throw new IllegalStateException("invalid connection");
        }

        // Request need to be initialized
        Preconditions.checkState(mNativeContext != 0, "request is not initialized");

@@ -260,7 +306,7 @@ public class UsbRequest {
                mIsUsingNewQueue = true;
                wasQueued = native_queue(null, 0, 0);
            } else {
                if (mConnection.getContext().getApplicationInfo().targetSdkVersion
                if (connection.getContext().getApplicationInfo().targetSdkVersion
                        < Build.VERSION_CODES.P) {
                    // Can only send/receive MAX_USBFS_BUFFER_SIZE bytes at once
                    Preconditions.checkArgumentInRange(buffer.remaining(), 0, MAX_USBFS_BUFFER_SIZE,
@@ -363,11 +409,12 @@ public class UsbRequest {
     * @return true if cancelling succeeded
     */
    public boolean cancel() {
        if (mConnection == null) {
        UsbDeviceConnection connection = mConnection;
        if (connection == null) {
            return false;
        }

        return mConnection.cancelRequest(this);
        return connection.cancelRequest(this);
    }

    /**
@@ -382,7 +429,8 @@ public class UsbRequest {
     * @return true if cancelling succeeded.
     */
    /* package */ boolean cancelIfOpen() {
        if (mNativeContext == 0 || (mConnection != null && !mConnection.isOpen())) {
        UsbDeviceConnection connection = mConnection;
        if (mNativeContext == 0 || (connection != null && !connection.isOpen())) {
            Log.w(TAG,
                    "Detected attempt to cancel a request on a connection which isn't open");
            return false;