Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Unified Diff: media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java

Issue 1085843003: Revert of Web MIDI: split build rules for media/midi (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
diff --git a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
new file mode 100644
index 0000000000000000000000000000000000000000..814bb17c46ea1542c21c65978ab064363507f83b
--- /dev/null
+++ b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
@@ -0,0 +1,264 @@
+// 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 android.os.Parcelable;
+
+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 events.
+ */
+ 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;
+
+ /**
+ * True when the enumeration is in progress.
+ */
+ private boolean mIsEnumeratingDevices;
+
+ /**
+ * The identifier of this factory.
+ */
+ private long mNativePointer;
+
+ private static final String ACTION_USB_PERMISSION =
+ "org.chromium.media.USB_PERMISSION";
+
+ /**
+ * Constructs a UsbMidiDeviceAndroid.
+ * @param context
+ * @param nativePointer The native pointer to which the created factory is associated.
+ */
+ UsbMidiDeviceFactoryAndroid(Context context, long nativePointer) {
+ mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+ mNativePointer = nativePointer;
+ mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Parcelable extra = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+ if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
+ requestDevicePermissionIfNecessary(context, (UsbDevice) extra);
+ }
+ if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
+ onUsbDeviceDetached((UsbDevice) extra);
+ }
+ if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
+ onUsbDevicePermissionRequestDone(context, intent);
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+ filter.addAction(ACTION_USB_PERMISSION);
+ context.registerReceiver(mReceiver, filter);
+ mRequestedDevices = new HashSet<UsbDevice>();
+ }
+
+ /**
+ * Constructs a UsbMidiDeviceAndroid.
+ * @param context
+ * @param nativePointer The native pointer to which the created factory is associated.
+ */
+ @CalledByNative
+ static UsbMidiDeviceFactoryAndroid create(Context context, long nativePointer) {
+ return new UsbMidiDeviceFactoryAndroid(context, 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, nativeOnUsbMidiDeviceRequestDone
+ * will be called.
+ *
+ * If there are no USB-MIDI interfaces, this function returns false.
+ * @param context
+ * @return true if some permission requests are in progress.
+ */
+ @CalledByNative
+ boolean enumerateDevices(Context context) {
+ assert !mIsEnumeratingDevices;
+ mIsEnumeratingDevices = true;
+ Map<String, UsbDevice> devices = mUsbManager.getDeviceList();
+ if (devices.isEmpty()) {
+ // No USB-MIDI devices are found.
+ mIsEnumeratingDevices = false;
+ return false;
+ }
+ for (UsbDevice device: devices.values()) {
+ requestDevicePermissionIfNecessary(context, device);
+ }
+ return true;
+ }
+
+ /**
+ * Request a device access permission if there is a MIDI interface in the device.
+ *
+ * @param context
+ * @param device a USB device
+ */
+ private void requestDevicePermissionIfNecessary(Context context, UsbDevice device) {
+ for (UsbDevice d: mRequestedDevices) {
+ if (d.getDeviceId() == device.getDeviceId()) {
+ // It is already requested.
+ return;
+ }
+ }
+
+ for (int i = 0; i < device.getInterfaceCount(); ++i) {
+ UsbInterface iface = device.getInterface(i);
+ if (iface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO
+ && iface.getInterfaceSubclass() == UsbMidiDeviceAndroid.MIDI_SUBCLASS) {
+ // There is at least one interface supporting MIDI.
+ mUsbManager.requestPermission(device, PendingIntent.getBroadcast(
+ context, 0, new Intent(ACTION_USB_PERMISSION), 0));
+ mRequestedDevices.add(device);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Called when a USB device is detached.
+ *
+ * @param device a USB device
+ */
+ private void onUsbDeviceDetached(UsbDevice device) {
+ for (UsbDevice usbDevice: mRequestedDevices) {
+ if (usbDevice.getDeviceId() == device.getDeviceId()) {
+ mRequestedDevices.remove(usbDevice);
+ break;
+ }
+ }
+ for (int i = 0; i < mDevices.size(); ++i) {
+ UsbMidiDeviceAndroid midiDevice = mDevices.get(i);
+ if (midiDevice.isClosed()) {
+ // Once a device is disconnected, the system may reassign its device ID to
+ // another device. So we should ignore disconnected ones.
+ continue;
+ }
+ if (midiDevice.getUsbDevice().getDeviceId() == device.getDeviceId()) {
+ midiDevice.close();
+ if (mIsEnumeratingDevices) {
+ // In this case, we don't have to keep mDevices sync with the devices list
+ // in MidiManagerUsb.
+ mDevices.remove(i);
+ return;
+ }
+ if (mNativePointer != 0) {
+ nativeOnUsbMidiDeviceDetached(mNativePointer, i);
+ }
+ return;
+ }
+ }
+ }
+
+ /**
+ * Called when the user accepts or rejects the permission request requested by
+ * EnumerateDevices.
+ *
+ * @param context
+ * @param intent
+ */
+ private void onUsbDevicePermissionRequestDone(Context context, Intent intent) {
+ UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+ UsbMidiDeviceAndroid midiDevice = null;
+ if (mRequestedDevices.contains(device)) {
+ mRequestedDevices.remove(device);
+ if (!intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
+ // The request was rejected.
+ device = null;
+ }
+ } else {
+ device = null;
+ }
+
+ if (device != null) {
+ for (UsbMidiDeviceAndroid registered: mDevices) {
+ if (!registered.isClosed()
+ && registered.getUsbDevice().getDeviceId() == device.getDeviceId()) {
+ // The device is already registered.
+ device = null;
+ break;
+ }
+ }
+ }
+
+ if (device != null) {
+ // Now we can add the device.
+ midiDevice = new UsbMidiDeviceAndroid(mUsbManager, device);
+ mDevices.add(midiDevice);
+ }
+
+ if (!mRequestedDevices.isEmpty()) {
+ return;
+ }
+ if (mNativePointer == 0) {
+ return;
+ }
+
+ if (mIsEnumeratingDevices) {
+ nativeOnUsbMidiDeviceRequestDone(mNativePointer, mDevices.toArray());
+ mIsEnumeratingDevices = false;
+ } else if (midiDevice != null) {
+ nativeOnUsbMidiDeviceAttached(mNativePointer, midiDevice);
+ }
+ }
+
+ /**
+ * Disconnects the native object.
+ * @param context
+ */
+ @CalledByNative
+ void close(Context context) {
+ mNativePointer = 0;
+ context.unregisterReceiver(mReceiver);
+ }
+
+ private static native void nativeOnUsbMidiDeviceRequestDone(
+ long nativeUsbMidiDeviceFactoryAndroid, Object[] devices);
+ private static native void nativeOnUsbMidiDeviceAttached(
+ long nativeUsbMidiDeviceFactoryAndroid, Object device);
+ private static native void nativeOnUsbMidiDeviceDetached(
+ long nativeUsbMidiDeviceFactoryAndroid, int index);
+}
« no previous file with comments | « media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java ('k') | media/base/android/media_jni_registrar.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698