Merge "Fix MidiDevice.MidiConnection lifecycle" into mnc-dev

This commit is contained in:
Mike Lockwood
2015-06-18 21:13:26 +00:00
committed by Android (Google) Code Review
3 changed files with 58 additions and 13 deletions

View File

@@ -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;
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 {
// 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();
}
}
}

View File

@@ -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) {

View File

@@ -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) {