From 4c6239b1564f123dac66600c8a63b509ba3bbcf5 Mon Sep 17 00:00:00 2001 From: Robert Wu Date: Mon, 24 Jan 2022 22:01:56 +0000 Subject: [PATCH] Don't call setInterface when querying protocol calculateDefaultMidiProtocol() is a function that figures out the block type of a specific MIDI device. This function is used whenever a MIDI 2.0 device is added. Currently, connection.setInterface() is always called in this function. When a different interface is set, the MIDI 1.0 interface in ALSA just stops. /dev/snd/midiC1D0 is no longer exposed. The solution in this CL is that Android should not call connection.setInterface() until the MIDI 2.0 interface has opened. This means that querying protocol on startup should not use setInterface. This way, the MIDI 1.0 interface should work up until the MIDI 2.0 interface is actually used. Bug: 216178160 Test: MidiScope and MidiKeyboard Change-Id: I53d7792d6d331abcddea2d1aedb394ff4dee0a9c --- .../android/server/usb/UsbUniversalMidiDevice.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbUniversalMidiDevice.java b/services/usb/java/com/android/server/usb/UsbUniversalMidiDevice.java index db0c80f189d3e..13d404caf6a2e 100644 --- a/services/usb/java/com/android/server/usb/UsbUniversalMidiDevice.java +++ b/services/usb/java/com/android/server/usb/UsbUniversalMidiDevice.java @@ -218,14 +218,13 @@ public final class UsbUniversalMidiDevice implements Closeable { if (doesInterfaceContainInput && doesInterfaceContainOutput) { UsbDeviceConnection connection = manager.openDevice(mUsbDevice); - if (!connection.claimInterface(interfaceDescriptor.toAndroid(mParser), true)) { - Log.d(TAG, "Can't claim control interface"); - continue; - } - int defaultMidiProtocol = mMidiBlockParser.calculateMidiType(connection, - interfaceDescriptor.getInterfaceNumber(), - interfaceDescriptor.getAlternateSetting()); + // The ALSA does not handle switching to the MIDI 2.0 interface correctly + // and stops exposing /dev/snd/midiC1D0 after calling connection.setInterface(). + // Thus, simply use the control interface (interface zero). + int defaultMidiProtocol = mMidiBlockParser.calculateMidiType(connection, + 0, + interfaceDescriptor.getAlternateSetting()); connection.close(); return defaultMidiProtocol; }