UsbMidiDeviceAndroid.java revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.media; 6 7import android.hardware.usb.UsbConstants; 8import android.hardware.usb.UsbDevice; 9import android.hardware.usb.UsbDeviceConnection; 10import android.hardware.usb.UsbEndpoint; 11import android.hardware.usb.UsbInterface; 12import android.hardware.usb.UsbManager; 13import android.hardware.usb.UsbRequest; 14 15import org.chromium.base.CalledByNative; 16import org.chromium.base.JNINamespace; 17 18import java.nio.ByteBuffer; 19import java.util.HashMap; 20import java.util.Map; 21 22/** 23 * Owned by its native counterpart declared in usb_midi_device_android.h. 24 * Refer to that class for general comments. 25 */ 26@JNINamespace("media") 27class UsbMidiDeviceAndroid { 28 /** 29 * A connection handle for this device. 30 */ 31 private UsbDeviceConnection mConnection; 32 33 /** 34 * A map from endpoint number to UsbEndpoint. 35 */ 36 private final Map<Integer, UsbEndpoint> mEndpointMap; 37 38 /** 39 * A map from UsbEndpoint to UsbRequest associated to it. 40 */ 41 private final Map<UsbEndpoint, UsbRequest> mRequestMap; 42 43 /** 44 * Audio interface subclass code for MIDI. 45 */ 46 static final int MIDI_SUBCLASS = 3; 47 48 /** 49 * Constructs a UsbMidiDeviceAndroid. 50 * @param manager 51 * @param device The USB device which this object is assocated with. 52 */ 53 UsbMidiDeviceAndroid(UsbManager manager, UsbDevice device) { 54 mConnection = manager.openDevice(device); 55 mEndpointMap = new HashMap<Integer, UsbEndpoint>(); 56 mRequestMap = new HashMap<UsbEndpoint, UsbRequest>(); 57 58 for (int i = 0; i < device.getInterfaceCount(); ++i) { 59 UsbInterface iface = device.getInterface(i); 60 if (iface.getInterfaceClass() != UsbConstants.USB_CLASS_AUDIO || 61 iface.getInterfaceSubclass() != MIDI_SUBCLASS) { 62 continue; 63 } 64 mConnection.claimInterface(iface, true); 65 for (int j = 0; j < iface.getEndpointCount(); ++j) { 66 UsbEndpoint endpoint = iface.getEndpoint(j); 67 if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) { 68 mEndpointMap.put(endpoint.getEndpointNumber(), endpoint); 69 } 70 } 71 } 72 } 73 74 /** 75 * Sends a USB-MIDI data to the device. 76 * @param endpointNumber The endpoint number of the destination endpoint. 77 * @param bs The data to be sent. 78 */ 79 @CalledByNative 80 void send(int endpointNumber, byte[] bs) { 81 if (mConnection == null) { 82 return; 83 } 84 if (!mEndpointMap.containsKey(endpointNumber)) { 85 return; 86 } 87 UsbEndpoint endpoint = mEndpointMap.get(endpointNumber); 88 UsbRequest request; 89 if (mRequestMap.containsKey(endpoint)) { 90 request = mRequestMap.get(endpoint); 91 } else { 92 request = new UsbRequest(); 93 request.initialize(mConnection, endpoint); 94 mRequestMap.put(endpoint, request); 95 } 96 request.queue(ByteBuffer.wrap(bs), bs.length); 97 } 98 99 /** 100 * Returns the descriptors bytes of this device. 101 * @return The descriptors bytes of this device. 102 */ 103 @CalledByNative 104 byte[] getDescriptors() { 105 if (mConnection == null) { 106 return new byte[0]; 107 } 108 return mConnection.getRawDescriptors(); 109 } 110 111 /** 112 * Closes the device connection. 113 */ 114 @CalledByNative 115 void close() { 116 mEndpointMap.clear(); 117 for (UsbRequest request : mRequestMap.values()) { 118 request.close(); 119 } 120 mRequestMap.clear(); 121 if (mConnection != null) { 122 mConnection.close(); 123 mConnection = null; 124 } 125 } 126} 127