diff options
author | Mike Lockwood <lockwood@google.com> | 2015-06-18 10:05:17 -0700 |
---|---|---|
committer | Mike Lockwood <lockwood@google.com> | 2015-06-18 12:31:40 -0700 |
commit | 2aef7e3559e9e2c78287a00b3f693b6dc19e56f0 (patch) | |
tree | 65dd4907732c3f23f48e4240b99695e543084378 /media | |
parent | 13e54ff0ebc5fe6f425c16d9d30ea9ecd5db1348 (diff) | |
download | frameworks_base-2aef7e3559e9e2c78287a00b3f693b6dc19e56f0.zip frameworks_base-2aef7e3559e9e2c78287a00b3f693b6dc19e56f0.tar.gz frameworks_base-2aef7e3559e9e2c78287a00b3f693b6dc19e56f0.tar.bz2 |
Fix MidiDevice.MidiConnection lifecycle
Update device server's MidiDeviceStatus when a connection is made to one of its output ports.
After connecting an input port to an output port using MidiDevice.connectPorts(),
do not call IMidiDeviceServer.closePort() until MidiDevice.MidiConnection.close() is called.
While I was in there, added missing CloseGuard support to the MidiDevice.MidiConnection class.
This fixes a problem resulting in UsbMidiDevice closing the device's ALSA driver too soon.
Bug: 21850709
Change-Id: I0c120f76b42eec8a143161e46dba73fbec5e4f31
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/midi/MidiDevice.java | 42 | ||||
-rw-r--r-- | media/java/android/media/midi/MidiDeviceServer.java | 9 | ||||
-rw-r--r-- | media/java/android/media/midi/MidiInputPort.java | 22 |
3 files changed, 59 insertions, 14 deletions
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java index 7998a92..93fb6d2 100644 --- a/media/java/android/media/midi/MidiDevice.java +++ b/media/java/android/media/midi/MidiDevice.java @@ -50,21 +50,43 @@ 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; - - MidiConnection(IBinder token, MidiInputPort inputPort) { - mToken = token; - mInputPort = inputPort; + private final IMidiDeviceServer mInputPortDeviceServer; + private final IBinder mInputPortToken; + private final IBinder mOutputPortToken; + private final CloseGuard mGuard = CloseGuard.get(); + private boolean mIsClosed; + + 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 { + // 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 { - mDeviceServer.closePort(mToken); - IoUtils.closeQuietly(mInputPort); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in MidiConnection.close"); + mGuard.warnIfOpen(); + close(); + } finally { + super.finalize(); } } } diff --git a/media/java/android/media/midi/MidiDeviceServer.java b/media/java/android/media/midi/MidiDeviceServer.java index 1212b64..19ff624 100644 --- a/media/java/android/media/midi/MidiDeviceServer.java +++ b/media/java/android/media/midi/MidiDeviceServer.java @@ -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) { diff --git a/media/java/android/media/midi/MidiInputPort.java b/media/java/android/media/midi/MidiInputPort.java index af5a86c..db41b10 100644 --- a/media/java/android/media/midi/MidiInputPort.java +++ b/media/java/android/media/midi/MidiInputPort.java @@ -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 (mBuffer) { - ParcelFileDescriptor pfd = mParcelFileDescriptor; - if (pfd != null) { + synchronized (mGuard) { + ParcelFileDescriptor pfd; + synchronized (mBuffer) { + 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) { |