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

Commit 36a9663d authored by Mike Lockwood's avatar Mike Lockwood Committed by Android Git Automerger
Browse files

am 3c525c15: Merge "Fix MidiDevice.MidiConnection lifecycle" into mnc-dev

* commit '3c525c15':
  Fix MidiDevice.MidiConnection lifecycle
parents a3a0bb4b 3c525c15
Loading
Loading
Loading
Loading
+32 −10
Original line number Diff line number Diff line
@@ -50,22 +50,44 @@ public final class MidiDevice implements Closeable {
     * Close this object to terminate the connection.
     */
    public class MidiConnection implements Closeable {
        private final IBinder mToken;
        private final MidiInputPort mInputPort;
        private final IMidiDeviceServer mInputPortDeviceServer;
        private final IBinder mInputPortToken;
        private final IBinder mOutputPortToken;
        private final CloseGuard mGuard = CloseGuard.get();
        private boolean mIsClosed;

        MidiConnection(IBinder token, MidiInputPort inputPort) {
            mToken = token;
            mInputPort = inputPort;
        MidiConnection(IBinder outputPortToken, MidiInputPort inputPort) {
            mInputPortDeviceServer = inputPort.getDeviceServer();
            mInputPortToken = inputPort.getToken();
            mOutputPortToken = outputPortToken;
            mGuard.open("close");
        }

        @Override
        public void close() throws IOException {
            synchronized (mGuard) {
                if (mIsClosed) return;
                mGuard.close();
                try {
                mDeviceServer.closePort(mToken);
                IoUtils.closeQuietly(mInputPort);
                    // close input port
                    mInputPortDeviceServer.closePort(mInputPortToken);
                    // close output port
                    mDeviceServer.closePort(mOutputPortToken);
                } catch (RemoteException e) {
                    Log.e(TAG, "RemoteException in MidiConnection.close");
                }
                mIsClosed = true;
            }
        }

        @Override
        protected void finalize() throws Throwable {
            try {
                mGuard.warnIfOpen();
                close();
            } finally {
                super.finalize();
            }
        }
    }

+8 −1
Original line number Diff line number Diff line
@@ -257,7 +257,14 @@ public final class MidiDeviceServer implements Closeable {
        public void connectPorts(IBinder token, ParcelFileDescriptor pfd,
                int outputPortNumber) {
            MidiInputPort inputPort = new MidiInputPort(pfd, outputPortNumber);
            mOutputPortDispatchers[outputPortNumber].getSender().connect(inputPort);
            MidiDispatcher dispatcher = mOutputPortDispatchers[outputPortNumber];
            synchronized (dispatcher) {
                dispatcher.getSender().connect(inputPort);
                int openCount = dispatcher.getReceiverCount();
                mOutputPortOpenCount[outputPortNumber] = openCount;
                updateDeviceStatus();
            }

            mInputPorts.add(inputPort);
            OutputPortClient client = new OutputPortClient(token, inputPort);
            synchronized (mPortClients) {
+19 −3
Original line number Diff line number Diff line
@@ -103,17 +103,33 @@ public final class MidiInputPort extends MidiReceiver implements Closeable {

    // used by MidiDevice.connectInputPort() to connect our socket directly to another device
    /* package */ ParcelFileDescriptor claimFileDescriptor() {
        synchronized (mGuard) {
            ParcelFileDescriptor pfd;
            synchronized (mBuffer) {
            ParcelFileDescriptor pfd = mParcelFileDescriptor;
            if (pfd != null) {
                pfd = mParcelFileDescriptor;
                if (pfd == null) return null;
                IoUtils.closeQuietly(mOutputStream);
                mParcelFileDescriptor = null;
                mOutputStream = null;
            }

            // Set mIsClosed = true so we will not call mDeviceServer.closePort() in close().
            // MidiDevice.MidiConnection.close() will do the cleanup instead.
            mIsClosed = true;
            return pfd;
        }
    }

    // used by MidiDevice.MidiConnection to close this port after the connection is closed
    /* package */ IBinder getToken() {
        return mToken;
    }

    // used by MidiDevice.MidiConnection to close this port after the connection is closed
    /* package */ IMidiDeviceServer getDeviceServer() {
        return mDeviceServer;
    }

    @Override
    public void close() throws IOException {
        synchronized (mGuard) {