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

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

Issue 1065743003: Reland: Web MIDI: split build rules for media/midi (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed patch set Created 5 years, 7 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 unified diff | Download patch
OLDNEW
(Empty)
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
5 package org.chromium.media;
6
7 import android.app.PendingIntent;
8 import android.content.BroadcastReceiver;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.content.IntentFilter;
12 import android.hardware.usb.UsbConstants;
13 import android.hardware.usb.UsbDevice;
14 import android.hardware.usb.UsbInterface;
15 import android.hardware.usb.UsbManager;
16 import android.os.Parcelable;
17
18 import org.chromium.base.CalledByNative;
19 import org.chromium.base.JNINamespace;
20
21 import java.util.ArrayList;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 /**
28 * Owned by its native counterpart declared in
29 * usb_midi_device_factory_android.h. Refer to that class for general comments.
30 */
31 @JNINamespace("media")
32 class UsbMidiDeviceFactoryAndroid {
33 /**
34 * The UsbManager of this system.
35 */
36 private UsbManager mUsbManager;
37
38 /**
39 * A BroadcastReceiver for USB device events.
40 */
41 private BroadcastReceiver mReceiver;
42
43 /**
44 * Accessible USB-MIDI devices got so far.
45 */
46 private final List<UsbMidiDeviceAndroid> mDevices = new ArrayList<UsbMidiDev iceAndroid>();
47
48 /**
49 * Devices whose access permission requested but not resolved so far.
50 */
51 private Set<UsbDevice> mRequestedDevices;
52
53 /**
54 * True when the enumeration is in progress.
55 */
56 private boolean mIsEnumeratingDevices;
57
58 /**
59 * The identifier of this factory.
60 */
61 private long mNativePointer;
62
63 private static final String ACTION_USB_PERMISSION =
64 "org.chromium.media.USB_PERMISSION";
65
66 /**
67 * Constructs a UsbMidiDeviceAndroid.
68 * @param context
69 * @param nativePointer The native pointer to which the created factory is a ssociated.
70 */
71 UsbMidiDeviceFactoryAndroid(Context context, long nativePointer) {
72 mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE) ;
73 mNativePointer = nativePointer;
74 mReceiver = new BroadcastReceiver() {
75 @Override
76 public void onReceive(Context context, Intent intent) {
77 Parcelable extra = intent.getParcelableExtra(UsbManager.EXTRA_DE VICE);
78 if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getActio n())) {
79 requestDevicePermissionIfNecessary(context, (UsbDevice) extr a);
80 }
81 if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getActio n())) {
82 onUsbDeviceDetached((UsbDevice) extra);
83 }
84 if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
85 onUsbDevicePermissionRequestDone(context, intent);
86 }
87 }
88 };
89 IntentFilter filter = new IntentFilter();
90 filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
91 filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
92 filter.addAction(ACTION_USB_PERMISSION);
93 context.registerReceiver(mReceiver, filter);
94 mRequestedDevices = new HashSet<UsbDevice>();
95 }
96
97 /**
98 * Constructs a UsbMidiDeviceAndroid.
99 * @param context
100 * @param nativePointer The native pointer to which the created factory is a ssociated.
101 */
102 @CalledByNative
103 static UsbMidiDeviceFactoryAndroid create(Context context, long nativePointe r) {
104 return new UsbMidiDeviceFactoryAndroid(context, nativePointer);
105 }
106
107 /**
108 * Enumerates USB-MIDI devices.
109 * If there are devices having USB-MIDI interfaces, this function requests p ermission for
110 * accessing the device to the user.
111 * When the permission request is accepted or rejected, nativeOnUsbMidiDevi ceRequestDone
112 * will be called.
113 *
114 * If there are no USB-MIDI interfaces, this function returns false.
115 * @param context
116 * @return true if some permission requests are in progress.
117 */
118 @CalledByNative
119 boolean enumerateDevices(Context context) {
120 assert !mIsEnumeratingDevices;
121 mIsEnumeratingDevices = true;
122 Map<String, UsbDevice> devices = mUsbManager.getDeviceList();
123 if (devices.isEmpty()) {
124 // No USB-MIDI devices are found.
125 mIsEnumeratingDevices = false;
126 return false;
127 }
128 for (UsbDevice device: devices.values()) {
129 requestDevicePermissionIfNecessary(context, device);
130 }
131 return true;
132 }
133
134 /**
135 * Request a device access permission if there is a MIDI interface in the de vice.
136 *
137 * @param context
138 * @param device a USB device
139 */
140 private void requestDevicePermissionIfNecessary(Context context, UsbDevice d evice) {
141 for (UsbDevice d: mRequestedDevices) {
142 if (d.getDeviceId() == device.getDeviceId()) {
143 // It is already requested.
144 return;
145 }
146 }
147
148 for (int i = 0; i < device.getInterfaceCount(); ++i) {
149 UsbInterface iface = device.getInterface(i);
150 if (iface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO
151 && iface.getInterfaceSubclass() == UsbMidiDeviceAndroid.MIDI _SUBCLASS) {
152 // There is at least one interface supporting MIDI.
153 mUsbManager.requestPermission(device, PendingIntent.getBroadcast (
154 context, 0, new Intent(ACTION_USB_PERMISSION), 0));
155 mRequestedDevices.add(device);
156 break;
157 }
158 }
159 }
160
161 /**
162 * Called when a USB device is detached.
163 *
164 * @param device a USB device
165 */
166 private void onUsbDeviceDetached(UsbDevice device) {
167 for (UsbDevice usbDevice: mRequestedDevices) {
168 if (usbDevice.getDeviceId() == device.getDeviceId()) {
169 mRequestedDevices.remove(usbDevice);
170 break;
171 }
172 }
173 for (int i = 0; i < mDevices.size(); ++i) {
174 UsbMidiDeviceAndroid midiDevice = mDevices.get(i);
175 if (midiDevice.isClosed()) {
176 // Once a device is disconnected, the system may reassign its de vice ID to
177 // another device. So we should ignore disconnected ones.
178 continue;
179 }
180 if (midiDevice.getUsbDevice().getDeviceId() == device.getDeviceId()) {
181 midiDevice.close();
182 if (mIsEnumeratingDevices) {
183 // In this case, we don't have to keep mDevices sync with th e devices list
184 // in MidiManagerUsb.
185 mDevices.remove(i);
186 return;
187 }
188 if (mNativePointer != 0) {
189 nativeOnUsbMidiDeviceDetached(mNativePointer, i);
190 }
191 return;
192 }
193 }
194 }
195
196 /**
197 * Called when the user accepts or rejects the permission request requested by
198 * EnumerateDevices.
199 *
200 * @param context
201 * @param intent
202 */
203 private void onUsbDevicePermissionRequestDone(Context context, Intent intent ) {
204 UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTR A_DEVICE);
205 UsbMidiDeviceAndroid midiDevice = null;
206 if (mRequestedDevices.contains(device)) {
207 mRequestedDevices.remove(device);
208 if (!intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, fal se)) {
209 // The request was rejected.
210 device = null;
211 }
212 } else {
213 device = null;
214 }
215
216 if (device != null) {
217 for (UsbMidiDeviceAndroid registered: mDevices) {
218 if (!registered.isClosed()
219 && registered.getUsbDevice().getDeviceId() == device.get DeviceId()) {
220 // The device is already registered.
221 device = null;
222 break;
223 }
224 }
225 }
226
227 if (device != null) {
228 // Now we can add the device.
229 midiDevice = new UsbMidiDeviceAndroid(mUsbManager, device);
230 mDevices.add(midiDevice);
231 }
232
233 if (!mRequestedDevices.isEmpty()) {
234 return;
235 }
236 if (mNativePointer == 0) {
237 return;
238 }
239
240 if (mIsEnumeratingDevices) {
241 nativeOnUsbMidiDeviceRequestDone(mNativePointer, mDevices.toArray()) ;
242 mIsEnumeratingDevices = false;
243 } else if (midiDevice != null) {
244 nativeOnUsbMidiDeviceAttached(mNativePointer, midiDevice);
245 }
246 }
247
248 /**
249 * Disconnects the native object.
250 * @param context
251 */
252 @CalledByNative
253 void close(Context context) {
254 mNativePointer = 0;
255 context.unregisterReceiver(mReceiver);
256 }
257
258 private static native void nativeOnUsbMidiDeviceRequestDone(
259 long nativeUsbMidiDeviceFactoryAndroid, Object[] devices);
260 private static native void nativeOnUsbMidiDeviceAttached(
261 long nativeUsbMidiDeviceFactoryAndroid, Object device);
262 private static native void nativeOnUsbMidiDeviceDetached(
263 long nativeUsbMidiDeviceFactoryAndroid, int index);
264 }
OLDNEW
« 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