165 lines
5.5 KiB
Java
Executable File
165 lines
5.5 KiB
Java
Executable File
// 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;
|
|
|
|
import android.app.PendingIntent;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.hardware.usb.UsbConstants;
|
|
import android.hardware.usb.UsbDevice;
|
|
import android.hardware.usb.UsbInterface;
|
|
import android.hardware.usb.UsbManager;
|
|
|
|
import org.chromium.base.CalledByNative;
|
|
import org.chromium.base.JNINamespace;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* Owned by its native counterpart declared in
|
|
* usb_midi_device_factory_android.h. Refer to that class for general comments.
|
|
*/
|
|
@JNINamespace("media")
|
|
class UsbMidiDeviceFactoryAndroid {
|
|
/**
|
|
* The UsbManager of this system.
|
|
*/
|
|
private UsbManager mUsbManager;
|
|
|
|
/**
|
|
* A BroadcastReceiver for USB device permission requests.
|
|
*/
|
|
private BroadcastReceiver mReceiver;
|
|
|
|
/**
|
|
* Accessible USB-MIDI devices got so far.
|
|
*/
|
|
private final List<UsbMidiDeviceAndroid> mDevices = new ArrayList<UsbMidiDeviceAndroid>();
|
|
|
|
/**
|
|
* Devices whose access permission requested but not resolved so far.
|
|
*/
|
|
private Set<UsbDevice> mRequestedDevices;
|
|
|
|
/**
|
|
* The identifier of this factory.
|
|
*/
|
|
private long mNativePointer;
|
|
|
|
private static final String ACTION_USB_PERMISSION =
|
|
"org.chromium.media.USB_PERMISSION";
|
|
|
|
/**
|
|
* Constructs a UsbMidiDeviceAndroid.
|
|
* @param natviePointer The native pointer to which the created factory is associated.
|
|
*/
|
|
UsbMidiDeviceFactoryAndroid(long nativePointer) {
|
|
mNativePointer = nativePointer;
|
|
}
|
|
|
|
/**
|
|
* Constructs a UsbMidiDeviceAndroid.
|
|
* @param nativePointer The native pointer to which the created factory is associated.
|
|
*/
|
|
@CalledByNative
|
|
static UsbMidiDeviceFactoryAndroid create(long nativePointer) {
|
|
return new UsbMidiDeviceFactoryAndroid(nativePointer);
|
|
}
|
|
|
|
/**
|
|
* Enumerates USB-MIDI devices.
|
|
* If there are devices having USB-MIDI interfaces, this function requests permission for
|
|
* accessing the device to the user.
|
|
* When the permission request is accepted or rejected onRequestDone will be called.
|
|
*
|
|
* If there are no USB-MIDI interfaces, this function returns false.
|
|
* @return true if some permission requests are in progress.
|
|
*/
|
|
@CalledByNative
|
|
boolean enumerateDevices(Context context) {
|
|
mUsbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
|
|
Map<String, UsbDevice> devices = mUsbManager.getDeviceList();
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
|
context, 0, new Intent(ACTION_USB_PERMISSION), 0);
|
|
mRequestedDevices = new HashSet<UsbDevice>();
|
|
for (UsbDevice device : devices.values()) {
|
|
boolean found = false;
|
|
for (int i = 0; i < device.getInterfaceCount() && !found; ++i) {
|
|
UsbInterface iface = device.getInterface(i);
|
|
if (iface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO &&
|
|
iface.getInterfaceSubclass() == UsbMidiDeviceAndroid.MIDI_SUBCLASS) {
|
|
found = true;
|
|
}
|
|
}
|
|
if (found) {
|
|
mUsbManager.requestPermission(device, pendingIntent);
|
|
mRequestedDevices.add(device);
|
|
}
|
|
}
|
|
if (mRequestedDevices.isEmpty()) {
|
|
// No USB-MIDI devices are found.
|
|
return false;
|
|
}
|
|
|
|
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
|
|
mReceiver = new BroadcastReceiver() {
|
|
public void onReceive(Context context, Intent intent) {
|
|
if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
|
|
onRequestDone(context, intent);
|
|
}
|
|
}
|
|
};
|
|
context.registerReceiver(mReceiver, filter);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Called when the user accepts or rejects the permission request requested by
|
|
* EnumerateDevices.
|
|
* If all permission requests are responded, this function calls
|
|
* nativeOnUsbMidiDeviceRequestDone with the accessible USB-MIDI devices.
|
|
*/
|
|
private void onRequestDone(Context context, Intent intent) {
|
|
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
|
if (!mRequestedDevices.contains(device)) {
|
|
// We are not interested in the device.
|
|
return;
|
|
}
|
|
mRequestedDevices.remove(device);
|
|
if (!intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
|
|
// The request was rejected.
|
|
device = null;
|
|
}
|
|
if (device != null) {
|
|
// Now we can add the device.
|
|
mDevices.add(new UsbMidiDeviceAndroid(mUsbManager, device));
|
|
}
|
|
if (mRequestedDevices.isEmpty()) {
|
|
// All requests are done.
|
|
context.unregisterReceiver(mReceiver);
|
|
if (mNativePointer != 0) {
|
|
nativeOnUsbMidiDeviceRequestDone(mNativePointer, mDevices.toArray());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disconnects the native object.
|
|
*/
|
|
@CalledByNative
|
|
void close() {
|
|
mNativePointer = 0;
|
|
}
|
|
|
|
private static native void nativeOnUsbMidiDeviceRequestDone(
|
|
long nativeUsbMidiDeviceFactoryAndroid, Object[] devices);
|
|
}
|