| Index: media/midi/java/src/org/chromium/media/midi/UsbMidiDeviceAndroid.java
|
| diff --git a/media/midi/java/src/org/chromium/media/midi/UsbMidiDeviceAndroid.java b/media/midi/java/src/org/chromium/media/midi/UsbMidiDeviceAndroid.java
|
| deleted file mode 100644
|
| index 8b4122055698ec19aadb760f973ad4be2173ca10..0000000000000000000000000000000000000000
|
| --- a/media/midi/java/src/org/chromium/media/midi/UsbMidiDeviceAndroid.java
|
| +++ /dev/null
|
| @@ -1,326 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -package org.chromium.media.midi;
|
| -
|
| -import android.annotation.TargetApi;
|
| -import android.hardware.usb.UsbConstants;
|
| -import android.hardware.usb.UsbDevice;
|
| -import android.hardware.usb.UsbDeviceConnection;
|
| -import android.hardware.usb.UsbEndpoint;
|
| -import android.hardware.usb.UsbInterface;
|
| -import android.hardware.usb.UsbManager;
|
| -import android.hardware.usb.UsbRequest;
|
| -import android.os.Build;
|
| -import android.os.Handler;
|
| -import android.util.SparseArray;
|
| -
|
| -import org.chromium.base.annotations.CalledByNative;
|
| -import org.chromium.base.annotations.JNINamespace;
|
| -
|
| -import java.nio.ByteBuffer;
|
| -import java.util.Arrays;
|
| -import java.util.HashMap;
|
| -import java.util.Map;
|
| -
|
| -/**
|
| - * Owned by its native counterpart declared in usb_midi_device_android.h.
|
| - * Refer to that class for general comments.
|
| - */
|
| -@JNINamespace("media::midi")
|
| -class UsbMidiDeviceAndroid {
|
| - /**
|
| - * A connection handle for this device.
|
| - */
|
| - private final UsbDeviceConnection mConnection;
|
| -
|
| - /**
|
| - * A map from endpoint number to UsbEndpoint.
|
| - */
|
| - private final SparseArray<UsbEndpoint> mEndpointMap;
|
| -
|
| - /**
|
| - * A map from UsbEndpoint to UsbRequest associated to it.
|
| - */
|
| - private final Map<UsbEndpoint, UsbRequest> mRequestMap;
|
| -
|
| - /**
|
| - * The handler used for posting events on the main thread.
|
| - */
|
| - private final Handler mHandler;
|
| -
|
| - /**
|
| - * True if this device is closed.
|
| - */
|
| - private boolean mIsClosed;
|
| -
|
| - /**
|
| - * True if there is a thread processing input data.
|
| - */
|
| - private boolean mHasInputThread;
|
| -
|
| - /**
|
| - * The identifier of this device.
|
| - */
|
| - private long mNativePointer;
|
| -
|
| - /**
|
| - * The underlying USB device.
|
| - */
|
| - private UsbDevice mUsbDevice;
|
| -
|
| - /**
|
| - * Audio interface subclass code for MIDI.
|
| - */
|
| - static final int MIDI_SUBCLASS = 3;
|
| -
|
| - /**
|
| - * The request type to request a USB descriptor.
|
| - */
|
| - static final int REQUEST_GET_DESCRIPTOR = 0x06;
|
| -
|
| - /**
|
| - * The STRING descriptor type.
|
| - */
|
| - static final int STRING_DESCRIPTOR_TYPE = 0x03;
|
| -
|
| - /**
|
| - * Constructs a UsbMidiDeviceAndroid.
|
| - * @param manager
|
| - * @param device The USB device which this object is assocated with.
|
| - */
|
| - UsbMidiDeviceAndroid(UsbManager manager, UsbDevice device) {
|
| - mConnection = manager.openDevice(device);
|
| - mEndpointMap = new SparseArray<UsbEndpoint>();
|
| - mRequestMap = new HashMap<UsbEndpoint, UsbRequest>();
|
| - mHandler = new Handler();
|
| - mUsbDevice = device;
|
| - mIsClosed = false;
|
| - mHasInputThread = false;
|
| - mNativePointer = 0;
|
| -
|
| - for (int i = 0; i < device.getInterfaceCount(); ++i) {
|
| - UsbInterface iface = device.getInterface(i);
|
| - if (iface.getInterfaceClass() != UsbConstants.USB_CLASS_AUDIO
|
| - || iface.getInterfaceSubclass() != MIDI_SUBCLASS) {
|
| - continue;
|
| - }
|
| - mConnection.claimInterface(iface, true);
|
| - for (int j = 0; j < iface.getEndpointCount(); ++j) {
|
| - UsbEndpoint endpoint = iface.getEndpoint(j);
|
| - if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
|
| - mEndpointMap.put(endpoint.getEndpointNumber(), endpoint);
|
| - }
|
| - }
|
| - }
|
| - // Start listening for input endpoints.
|
| - // This function will create and run a thread if there is USB-MIDI endpoints in the
|
| - // device. Note that because UsbMidiDevice is shared among all tabs and the thread
|
| - // will be terminated when the device is disconnected, at most one thread can be created
|
| - // for each connected USB-MIDI device.
|
| - startListen(device);
|
| - }
|
| -
|
| - /**
|
| - * Starts listening for input endpoints.
|
| - */
|
| - private void startListen(final UsbDevice device) {
|
| - final Map<UsbEndpoint, ByteBuffer> bufferForEndpoints =
|
| - new HashMap<UsbEndpoint, ByteBuffer>();
|
| -
|
| - for (int i = 0; i < device.getInterfaceCount(); ++i) {
|
| - UsbInterface iface = device.getInterface(i);
|
| - if (iface.getInterfaceClass() != UsbConstants.USB_CLASS_AUDIO
|
| - || iface.getInterfaceSubclass() != MIDI_SUBCLASS) {
|
| - continue;
|
| - }
|
| - for (int j = 0; j < iface.getEndpointCount(); ++j) {
|
| - UsbEndpoint endpoint = iface.getEndpoint(j);
|
| - if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
|
| - ByteBuffer buffer = ByteBuffer.allocate(endpoint.getMaxPacketSize());
|
| - UsbRequest request = new UsbRequest();
|
| - request.initialize(mConnection, endpoint);
|
| - request.queue(buffer, buffer.remaining());
|
| - bufferForEndpoints.put(endpoint, buffer);
|
| - }
|
| - }
|
| - }
|
| - if (bufferForEndpoints.isEmpty()) {
|
| - return;
|
| - }
|
| - mHasInputThread = true;
|
| - // bufferForEndpoints must not be accessed hereafter on this thread.
|
| - new Thread() {
|
| - @Override
|
| - public void run() {
|
| - while (true) {
|
| - UsbRequest request = mConnection.requestWait();
|
| - if (request == null) {
|
| - // When the device is closed requestWait will fail.
|
| - break;
|
| - }
|
| - UsbEndpoint endpoint = request.getEndpoint();
|
| - if (endpoint.getDirection() != UsbConstants.USB_DIR_IN) {
|
| - continue;
|
| - }
|
| - ByteBuffer buffer = bufferForEndpoints.get(endpoint);
|
| - int length = getInputDataLength(buffer);
|
| - if (length > 0) {
|
| - buffer.rewind();
|
| - final byte[] bs = new byte[length];
|
| - buffer.get(bs, 0, length);
|
| - postOnDataEvent(endpoint.getEndpointNumber(), bs);
|
| - }
|
| - buffer.rewind();
|
| - request.queue(buffer, buffer.capacity());
|
| - }
|
| - }
|
| - }.start();
|
| - }
|
| -
|
| - /**
|
| - * Posts a data input event to the main thread.
|
| - */
|
| - private void postOnDataEvent(final int endpointNumber, final byte[] bs) {
|
| - mHandler.post(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - if (mIsClosed) {
|
| - return;
|
| - }
|
| - nativeOnData(mNativePointer, endpointNumber, bs);
|
| - }
|
| - });
|
| - }
|
| -
|
| - UsbDevice getUsbDevice() {
|
| - return mUsbDevice;
|
| - }
|
| -
|
| - boolean isClosed() {
|
| - return mIsClosed;
|
| - }
|
| -
|
| - /**
|
| - * Register the own native pointer.
|
| - */
|
| - @CalledByNative
|
| - void registerSelf(long nativePointer) {
|
| - mNativePointer = nativePointer;
|
| - }
|
| -
|
| - /**
|
| - * Sends a USB-MIDI data to the device.
|
| - * @param endpointNumber The endpoint number of the destination endpoint.
|
| - * @param bs The data to be sent.
|
| - */
|
| - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
|
| - @CalledByNative
|
| - void send(int endpointNumber, byte[] bs) {
|
| - if (mIsClosed) {
|
| - return;
|
| - }
|
| - UsbEndpoint endpoint = mEndpointMap.get(endpointNumber);
|
| - if (endpoint == null) {
|
| - return;
|
| - }
|
| - if (shouldUseBulkTransfer()) {
|
| - // We use bulkTransfer instead of UsbRequest.queue because queueing
|
| - // a UsbRequest is currently not thread safe.
|
| - // Note that this is not exactly correct because we don't care
|
| - // about the transfer attribute (bmAttribute) of the endpoint.
|
| - // See also:
|
| - // http://stackoverflow.com/questions/9644415/
|
| - // https://code.google.com/p/android/issues/detail?id=59467
|
| - //
|
| - // TODO(yhirano): Delete this block once the problem is fixed.
|
| - final int timeout = 100;
|
| - mConnection.bulkTransfer(endpoint, bs, bs.length, timeout);
|
| - } else {
|
| - UsbRequest request = mRequestMap.get(endpoint);
|
| - if (request == null) {
|
| - request = new UsbRequest();
|
| - request.initialize(mConnection, endpoint);
|
| - mRequestMap.put(endpoint, request);
|
| - }
|
| - request.queue(ByteBuffer.wrap(bs), bs.length);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Returns true if |bulkTransfer| should be used in |send|.
|
| - * See comments in |send|.
|
| - */
|
| - private boolean shouldUseBulkTransfer() {
|
| - return mHasInputThread;
|
| - }
|
| -
|
| - /**
|
| - * Returns the descriptors bytes of this device.
|
| - * @return The descriptors bytes of this device.
|
| - */
|
| - @CalledByNative
|
| - byte[] getDescriptors() {
|
| - if (mConnection == null) {
|
| - return new byte[0];
|
| - }
|
| - return mConnection.getRawDescriptors();
|
| - }
|
| -
|
| - /**
|
| - * Returns the string descriptor bytes for the given index
|
| - * @param index index of the descriptor
|
| - * @return the string descriptor bytes for the given index.
|
| - */
|
| - @CalledByNative
|
| - byte[] getStringDescriptor(int index) {
|
| - if (mConnection == null) {
|
| - return new byte[0];
|
| - }
|
| - byte[] buffer = new byte[255];
|
| - int type = UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD;
|
| - int request = REQUEST_GET_DESCRIPTOR;
|
| - int value = (STRING_DESCRIPTOR_TYPE << 8) | index;
|
| - int read = mConnection.controlTransfer(type, request, value, 0, buffer, buffer.length, 0);
|
| - if (read < 0) {
|
| - return new byte[0];
|
| - }
|
| - return Arrays.copyOf(buffer, read);
|
| - }
|
| -
|
| - /**
|
| - * Closes the device connection.
|
| - */
|
| - @CalledByNative
|
| - void close() {
|
| - mEndpointMap.clear();
|
| - for (UsbRequest request : mRequestMap.values()) {
|
| - request.close();
|
| - }
|
| - mRequestMap.clear();
|
| - mConnection.close();
|
| - mNativePointer = 0;
|
| - mIsClosed = true;
|
| - }
|
| -
|
| - /**
|
| - * Returns the length of a USB-MIDI input.
|
| - * Since the Android API doesn't provide us the length,
|
| - * we calculate it manually.
|
| - */
|
| - private static int getInputDataLength(ByteBuffer buffer) {
|
| - int position = buffer.position();
|
| - // We assume that the data length is always divisable by 4.
|
| - for (int i = 0; i < position; i += 4) {
|
| - // Since Code Index Number 0 is reserved, it is not a valid USB-MIDI data.
|
| - if (buffer.get(i) == 0) {
|
| - return i;
|
| - }
|
| - }
|
| - return position;
|
| - }
|
| -
|
| - private static native void nativeOnData(
|
| - long nativeUsbMidiDeviceAndroid, int endpointNumber, byte[] data);
|
| -}
|
|
|