Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edf35dd8 authored by Robert Wu's avatar Robert Wu Committed by Android (Google) Code Review
Browse files

Merge "USB MIDI: Extend bulkTransfer timeout"

parents e5862263 8c7028e8
Loading
Loading
Loading
Loading
+53 −9
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.usb;
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.usb.UsbConfiguration;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
@@ -76,10 +77,10 @@ public final class UsbDirectMidiDevice implements Closeable {
    // event schedulers for each input port of the physical device
    private MidiEventScheduler[] mEventSchedulers;

    // Arbitrary number for timeout to not continue sending to
    // an inactive device. This number tries to balances the number
    // of cycles and not being permanently stuck.
    private static final int BULK_TRANSFER_TIMEOUT_MILLISECONDS = 10;
    // Timeout for sending a packet to a device.
    // If bulkTransfer times out, retry sending the packet up to 20 times.
    private static final int BULK_TRANSFER_TIMEOUT_MILLISECONDS = 50;
    private static final int BULK_TRANSFER_NUMBER_OF_RETRIES = 20;

    // Arbitrary number for timeout when closing a thread
    private static final int THREAD_JOIN_TIMEOUT_MILLISECONDS = 200;
@@ -386,10 +387,15 @@ public final class UsbDirectMidiDevice implements Closeable {
                                    break;
                                }
                                final UsbRequest response = connectionFinal.requestWait();
                                if (response != request) {
                                    Log.w(TAG, "Unexpected response");
                                if (response == null) {
                                    Log.w(TAG, "Response is null");
                                    break;
                                }
                                if (request != response) {
                                    Log.w(TAG, "Skipping response");
                                    continue;
                                }

                                int bytesRead = byteBuffer.position();

                                if (bytesRead > 0) {
@@ -513,9 +519,47 @@ public final class UsbDirectMidiDevice implements Closeable {
                                            convertedArray.length);
                                }

                                connectionFinal.bulkTransfer(endpointFinal, convertedArray,
                                        convertedArray.length,
                                boolean isInterrupted = false;
                                // Split the packet into multiple if they are greater than the
                                // endpoint's max packet size.
                                for (int curPacketStart = 0;
                                        curPacketStart < convertedArray.length &&
                                        isInterrupted == false;
                                        curPacketStart += endpointFinal.getMaxPacketSize()) {
                                    int transferResult = -1;
                                    int retryCount = 0;
                                    int curPacketSize = Math.min(endpointFinal.getMaxPacketSize(),
                                            convertedArray.length - curPacketStart);

                                    // Keep trying to send the packet until the result is
                                    // successful or until the retry limit is reached.
                                    while (transferResult < 0 && retryCount <=
                                            BULK_TRANSFER_NUMBER_OF_RETRIES) {
                                        transferResult = connectionFinal.bulkTransfer(
                                                endpointFinal,
                                                convertedArray,
                                                curPacketStart,
                                                curPacketSize,
                                                BULK_TRANSFER_TIMEOUT_MILLISECONDS);
                                        retryCount++;

                                        if (Thread.currentThread().interrupted()) {
                                            Log.w(TAG, "output thread interrupted after send");
                                            isInterrupted = true;
                                            break;
                                        }
                                        if (transferResult < 0) {
                                            Log.d(TAG, "retrying packet. retryCount = "
                                                    + retryCount + " result = " + transferResult);
                                            if (retryCount > BULK_TRANSFER_NUMBER_OF_RETRIES) {
                                                Log.w(TAG, "Skipping packet because timeout");
                                            }
                                        }
                                    }
                                }
                                if (isInterrupted == true) {
                                    break;
                                }
                                eventSchedulerFinal.addEventToPool(event);
                            }
                        } catch (NullPointerException e) {