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

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

Issue 2418493002: //media/midi: use top level namespace midi rather than media.midi (Closed)
Patch Set: TAG name change s/media_midi/midi/ Created 4 years, 2 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.midi;
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.annotations.CalledByNative;
19 import org.chromium.base.annotations.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::midi")
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 = "org.chromium.media.USB_ PERMISSION";
64
65 /**
66 * Constructs a UsbMidiDeviceAndroid.
67 * @param context
68 * @param nativePointer The native pointer to which the created factory is a ssociated.
69 */
70 UsbMidiDeviceFactoryAndroid(Context context, long nativePointer) {
71 mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE) ;
72 mNativePointer = nativePointer;
73 mReceiver = new BroadcastReceiver() {
74 @Override
75 public void onReceive(Context context, Intent intent) {
76 Parcelable extra = intent.getParcelableExtra(UsbManager.EXTRA_DE VICE);
77 if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getActio n())) {
78 requestDevicePermissionIfNecessary(context, (UsbDevice) extr a);
79 }
80 if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getActio n())) {
81 onUsbDeviceDetached((UsbDevice) extra);
82 }
83 if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
84 onUsbDevicePermissionRequestDone(context, intent);
85 }
86 }
87 };
88 IntentFilter filter = new IntentFilter();
89 filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
90 filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
91 filter.addAction(ACTION_USB_PERMISSION);
92 context.registerReceiver(mReceiver, filter);
93 mRequestedDevices = new HashSet<UsbDevice>();
94 }
95
96 /**
97 * Constructs a UsbMidiDeviceAndroid.
98 * @param context
99 * @param nativePointer The native pointer to which the created factory is a ssociated.
100 */
101 @CalledByNative
102 static UsbMidiDeviceFactoryAndroid create(Context context, long nativePointe r) {
103 return new UsbMidiDeviceFactoryAndroid(context, nativePointer);
104 }
105
106 /**
107 * Enumerates USB-MIDI devices.
108 * If there are devices having USB-MIDI interfaces, this function requests p ermission for
109 * accessing the device to the user.
110 * When the permission request is accepted or rejected, nativeOnUsbMidiDevi ceRequestDone
111 * will be called.
112 *
113 * If there are no USB-MIDI interfaces, this function returns false.
114 * @param context
115 * @return true if some permission requests are in progress.
116 */
117 @CalledByNative
118 boolean enumerateDevices(Context context) {
119 assert !mIsEnumeratingDevices;
120 mIsEnumeratingDevices = true;
121 Map<String, UsbDevice> devices = mUsbManager.getDeviceList();
122 if (devices.isEmpty()) {
123 // No USB-MIDI devices are found.
124 mIsEnumeratingDevices = false;
125 return false;
126 }
127 for (UsbDevice device : devices.values()) {
128 requestDevicePermissionIfNecessary(context, device);
129 }
130 return !mRequestedDevices.isEmpty();
131 }
132
133 /**
134 * Request a device access permission if there is a MIDI interface in the de vice.
135 *
136 * @param context
137 * @param device a USB device
138 */
139 private void requestDevicePermissionIfNecessary(Context context, UsbDevice d evice) {
140 for (UsbDevice d : mRequestedDevices) {
141 if (d.getDeviceId() == device.getDeviceId()) {
142 // It is already requested.
143 return;
144 }
145 }
146
147 for (int i = 0; i < device.getInterfaceCount(); ++i) {
148 UsbInterface iface = device.getInterface(i);
149 if (iface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO
150 && iface.getInterfaceSubclass() == UsbMidiDeviceAndroid.MIDI _SUBCLASS) {
151 // There is at least one interface supporting MIDI.
152 mUsbManager.requestPermission(
153 device, PendingIntent.getBroadcast(
154 context, 0, new Intent(ACTION_USB_PERMIS SION), 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

Powered by Google App Engine
This is Rietveld 408576698