diff --git a/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java b/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java index 0fa79df3e008d..04c52f7253e95 100644 --- a/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java +++ b/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java @@ -84,7 +84,7 @@ public final class UsbDirectMidiDevice implements Closeable { private final Object mLock = new Object(); private boolean mIsOpen; - private final UsbMidiPacketConverter mUsbMidiPacketConverter = new UsbMidiPacketConverter(); + private UsbMidiPacketConverter mUsbMidiPacketConverter; private final MidiDeviceServer.Callback mCallback = new MidiDeviceServer.Callback() { @@ -264,6 +264,11 @@ public final class UsbDirectMidiDevice implements Closeable { Log.d(TAG, "openLocked()"); UsbManager manager = mContext.getSystemService(UsbManager.class); + // Converting from raw MIDI to USB MIDI is not thread-safe. + // UsbMidiPacketConverter creates a converter from raw MIDI + // to USB MIDI for each USB output. + mUsbMidiPacketConverter = new UsbMidiPacketConverter(mNumOutputs); + mUsbDeviceConnections = new ArrayList(mUsbInterfaces.size()); mInputUsbEndpoints = new ArrayList>(mUsbInterfaces.size()); mOutputUsbEndpoints = new ArrayList>(mUsbInterfaces.size()); @@ -415,7 +420,7 @@ public final class UsbDirectMidiDevice implements Closeable { } else { convertedArray = mUsbMidiPacketConverter.rawMidiToUsbMidi( - event.data, event.count); + event.data, event.count, portFinal); } if (DEBUG) { @@ -518,6 +523,8 @@ public final class UsbDirectMidiDevice implements Closeable { mInputUsbEndpoints = null; mOutputUsbEndpoints = null; + mUsbMidiPacketConverter = null; + mIsOpen = false; } diff --git a/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java b/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java index 7c93c7668fa22..56bb23681741f 100644 --- a/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java +++ b/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java @@ -74,8 +74,15 @@ public class UsbMidiPacketConverter { private static final byte SYSEX_START_EXCLUSIVE = (byte) 0xF0; private static final byte SYSEX_END_EXCLUSIVE = (byte) 0xF7; - private UsbMidiEncoder mUsbMidiEncoder = new UsbMidiEncoder(); private UsbMidiDecoder mUsbMidiDecoder = new UsbMidiDecoder(); + private UsbMidiEncoder[] mUsbMidiEncoders; + + public UsbMidiPacketConverter(int numEncoders) { + mUsbMidiEncoders = new UsbMidiEncoder[numEncoders]; + for (int i = 0; i < numEncoders; i++) { + mUsbMidiEncoders[i] = new UsbMidiEncoder(); + } + } /** * Converts a USB MIDI array into a raw MIDI array. @@ -93,10 +100,11 @@ public class UsbMidiPacketConverter { * * @param midiBytes the raw MIDI bytes to convert * @param size the size of usbMidiBytes + * @param encoderId which encoder to use * @return byte array of USB MIDI packets */ - public byte[] rawMidiToUsbMidi(byte[] midiBytes, int size) { - return mUsbMidiEncoder.encode(midiBytes, size); + public byte[] rawMidiToUsbMidi(byte[] midiBytes, int size, int encoderId) { + return mUsbMidiEncoders[encoderId].encode(midiBytes, size); } private class UsbMidiDecoder {