Merge "USB MIDI: Replace bulkTransfer with requestWait" into tm-dev am: 0656f1c02a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18203204

Change-Id: I58bf732a4b3c0fe593ccf3a8f872727de9e14fc5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Robert Wu
2022-05-10 21:11:28 +00:00
committed by Automerger Merge Worker

View File

@@ -23,6 +23,7 @@ import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiDeviceInfo;
import android.media.midi.MidiDeviceServer; import android.media.midi.MidiDeviceServer;
import android.media.midi.MidiDeviceStatus; import android.media.midi.MidiDeviceStatus;
@@ -44,6 +45,7 @@ import libcore.io.IoUtils;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@@ -73,10 +75,10 @@ public final class UsbDirectMidiDevice implements Closeable {
// event schedulers for each input port of the physical device // event schedulers for each input port of the physical device
private MidiEventScheduler[] mEventSchedulers; private MidiEventScheduler[] mEventSchedulers;
// Arbitrary number for timeout to not continue sending/receiving number from // Arbitrary number for timeout to not continue sending to
// an inactive device. This number tries to balances the number of cycles and // an inactive device. This number tries to balances the number
// not being permanently stuck. // of cycles and not being permanently stuck.
private static final int BULK_TRANSFER_TIMEOUT_MILLISECONDS = 100; private static final int BULK_TRANSFER_TIMEOUT_MILLISECONDS = 10;
private ArrayList<UsbDeviceConnection> mUsbDeviceConnections; private ArrayList<UsbDeviceConnection> mUsbDeviceConnections;
private ArrayList<ArrayList<UsbEndpoint>> mInputUsbEndpoints; private ArrayList<ArrayList<UsbEndpoint>> mInputUsbEndpoints;
@@ -330,48 +332,55 @@ public final class UsbDirectMidiDevice implements Closeable {
new Thread("UsbDirectMidiDevice input thread " + portFinal) { new Thread("UsbDirectMidiDevice input thread " + portFinal) {
@Override @Override
public void run() { public void run() {
byte[] inputBuffer = new byte[endpointFinal.getMaxPacketSize()]; final UsbRequest request = new UsbRequest();
Log.d(TAG, "input buffer size: " + inputBuffer.length);
try { try {
request.initialize(connectionFinal, endpointFinal);
byte[] inputBuffer = new byte[endpointFinal.getMaxPacketSize()];
while (true) { while (true) {
// Record time of event immediately after waking. // Record time of event immediately after waking.
long timestamp = System.nanoTime(); long timestamp = System.nanoTime();
synchronized (mLock) {
if (!mIsOpen) break; if (!mIsOpen) break;
final ByteBuffer byteBuffer = ByteBuffer.wrap(inputBuffer);
if (!request.queue(byteBuffer)) {
Log.w(TAG, "Cannot queue request");
break;
}
final UsbRequest response = connectionFinal.requestWait();
if (response != request) {
Log.w(TAG, "Unexpected response");
continue;
}
int bytesRead = byteBuffer.position();
int nRead = connectionFinal.bulkTransfer(endpointFinal, if (bytesRead > 0) {
inputBuffer, inputBuffer.length,
BULK_TRANSFER_TIMEOUT_MILLISECONDS);
if (nRead > 0) {
if (DEBUG) { if (DEBUG) {
logByteArray("Input before conversion ", inputBuffer, logByteArray("Input before conversion ", inputBuffer,
0, nRead); 0, bytesRead);
} }
byte[] convertedArray; byte[] convertedArray;
if (mIsUniversalMidiDevice) { if (mIsUniversalMidiDevice) {
// For USB, each 32 bit word of a UMP is // For USB, each 32 bit word of a UMP is
// sent with the least significant byte first. // sent with the least significant byte first.
convertedArray = swapEndiannessPerWord(inputBuffer, convertedArray = swapEndiannessPerWord(inputBuffer,
nRead); bytesRead);
} else { } else {
convertedArray = convertedArray =
mUsbMidiPacketConverter.usbMidiToRawMidi( mUsbMidiPacketConverter.usbMidiToRawMidi(
inputBuffer, nRead); inputBuffer, bytesRead);
} }
if (DEBUG) { if (DEBUG) {
logByteArray("Input after conversion ", convertedArray, logByteArray("Input after conversion ", convertedArray,
0, convertedArray.length); 0, convertedArray.length);
} }
outputReceivers[portFinal].send(convertedArray, 0, outputReceivers[portFinal].send(convertedArray, 0,
convertedArray.length, timestamp); convertedArray.length, timestamp);
} }
} }
}
} catch (IOException e) { } catch (IOException e) {
Log.d(TAG, "reader thread exiting"); Log.d(TAG, "reader thread exiting");
} finally {
request.close();
} }
Log.d(TAG, "input thread exit"); Log.d(TAG, "input thread exit");
} }
@@ -564,6 +573,10 @@ public final class UsbDirectMidiDevice implements Closeable {
Log.e(TAG, "Usb Interface is null"); Log.e(TAG, "Usb Interface is null");
return false; return false;
} }
if (connection == null) {
Log.e(TAG, "UsbDeviceConnection is null");
return false;
}
if (!connection.claimInterface(usbInterface, true)) { if (!connection.claimInterface(usbInterface, true)) {
Log.e(TAG, "Can't claim interface"); Log.e(TAG, "Can't claim interface");
return false; return false;