summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authoryhirano <yhirano@chromium.org>2015-02-26 18:44:10 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-27 02:45:02 +0000
commit7a529cc2c07eb8bf0bdbf757061c0146c216bff7 (patch)
tree6f123d71c9335c402a970e47037807abc7a011cb /media
parentb8f5639f294a8849a50de6fffe421c044377f8e8 (diff)
downloadchromium_src-7a529cc2c07eb8bf0bdbf757061c0146c216bff7.zip
chromium_src-7a529cc2c07eb8bf0bdbf757061c0146c216bff7.tar.gz
chromium_src-7a529cc2c07eb8bf0bdbf757061c0146c216bff7.tar.bz2
[MIDI][Android] Support device detach event.
This CL introduces device detach support for Android Web MIDI. BUG=460901 Review URL: https://codereview.chromium.org/956853004 Cr-Commit-Position: refs/heads/master@{#318384}
Diffstat (limited to 'media')
-rw-r--r--media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java4
-rw-r--r--media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java59
-rw-r--r--media/midi/midi_manager_usb.cc18
-rw-r--r--media/midi/midi_manager_usb.h1
-rw-r--r--media/midi/midi_manager_usb_unittest.cc25
-rw-r--r--media/midi/usb_midi_device.h2
-rw-r--r--media/midi/usb_midi_device_factory_android.cc8
-rw-r--r--media/midi/usb_midi_device_factory_android.h1
-rw-r--r--media/midi/usb_midi_input_stream.cc14
-rw-r--r--media/midi/usb_midi_input_stream.h3
10 files changed, 107 insertions, 28 deletions
diff --git a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
index 35520b4..2f80b96 100644
--- a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
@@ -187,6 +187,10 @@ class UsbMidiDeviceAndroid {
return mUsbDevice;
}
+ boolean isClosed() {
+ return mIsClosed;
+ }
+
/**
* Register the own native pointer.
*/
diff --git a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
index 5eafee6..814bb17 100644
--- a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
@@ -78,6 +78,9 @@ class UsbMidiDeviceFactoryAndroid {
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);
}
@@ -85,6 +88,7 @@ class UsbMidiDeviceFactoryAndroid {
};
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>();
@@ -134,6 +138,13 @@ class UsbMidiDeviceFactoryAndroid {
* @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
@@ -148,6 +159,41 @@ class UsbMidiDeviceFactoryAndroid {
}
/**
+ * 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.
*
@@ -168,6 +214,17 @@ class UsbMidiDeviceFactoryAndroid {
}
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);
@@ -202,4 +259,6 @@ class UsbMidiDeviceFactoryAndroid {
long nativeUsbMidiDeviceFactoryAndroid, Object[] devices);
private static native void nativeOnUsbMidiDeviceAttached(
long nativeUsbMidiDeviceFactoryAndroid, Object device);
+ private static native void nativeOnUsbMidiDeviceDetached(
+ long nativeUsbMidiDeviceFactoryAndroid, int index);
}
diff --git a/media/midi/midi_manager_usb.cc b/media/midi/midi_manager_usb.cc
index 3b6c885..8faba06 100644
--- a/media/midi/midi_manager_usb.cc
+++ b/media/midi/midi_manager_usb.cc
@@ -74,6 +74,24 @@ void MidiManagerUsb::OnDeviceAttached(scoped_ptr<UsbMidiDevice> device) {
AddPorts(devices_.back(), device_id);
}
+void MidiManagerUsb::OnDeviceDetached(size_t index) {
+ if (index >= devices_.size()) {
+ return;
+ }
+ UsbMidiDevice* device = devices_[index];
+ for (size_t i = 0; i < output_streams_.size(); ++i) {
+ if (output_streams_[i]->jack().device == device) {
+ SetOutputPortState(i, MIDI_PORT_DISCONNECTED);
+ }
+ }
+ const std::vector<UsbMidiJack>& input_jacks = input_stream_->jacks();
+ for (size_t i = 0; i < input_jacks.size(); ++i) {
+ if (input_jacks[i].device == device) {
+ SetInputPortState(i, MIDI_PORT_DISCONNECTED);
+ }
+ }
+}
+
void MidiManagerUsb::OnReceivedData(size_t jack_index,
const uint8* data,
size_t size,
diff --git a/media/midi/midi_manager_usb.h b/media/midi/midi_manager_usb.h
index 357b5da..ea9b589 100644
--- a/media/midi/midi_manager_usb.h
+++ b/media/midi/midi_manager_usb.h
@@ -45,6 +45,7 @@ class MEDIA_EXPORT MidiManagerUsb : public MidiManager,
size_t size,
base::TimeTicks time) override;
void OnDeviceAttached(scoped_ptr<UsbMidiDevice> device) override;
+ void OnDeviceDetached(size_t index) override;
// UsbMidiInputStream::Delegate implementation.
void OnReceivedData(size_t jack_index,
diff --git a/media/midi/midi_manager_usb_unittest.cc b/media/midi/midi_manager_usb_unittest.cc
index efcf604..0afb98b 100644
--- a/media/midi/midi_manager_usb_unittest.cc
+++ b/media/midi/midi_manager_usb_unittest.cc
@@ -243,13 +243,12 @@ TEST_F(MidiManagerUsbTest, Initialize) {
ASSERT_EQ(1u, input_ports().size());
ASSERT_EQ(2u, output_ports().size());
ASSERT_TRUE(manager_->input_stream());
- std::vector<UsbMidiInputStream::JackUniqueKey> keys =
- manager_->input_stream()->RegisteredJackKeysForTesting();
+ std::vector<UsbMidiJack> jacks = manager_->input_stream()->jacks();
ASSERT_EQ(2u, manager_->output_streams().size());
EXPECT_EQ(2u, manager_->output_streams()[0]->jack().jack_id);
EXPECT_EQ(3u, manager_->output_streams()[1]->jack().jack_id);
- ASSERT_EQ(1u, keys.size());
- EXPECT_EQ(2, keys[0].endpoint_number);
+ ASSERT_EQ(1u, jacks.size());
+ EXPECT_EQ(2, jacks[0].endpoint_number());
EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_.TakeLog());
}
@@ -285,13 +284,12 @@ TEST_F(MidiManagerUsbTest, InitializeMultipleDevices) {
ASSERT_EQ(2u, input_ports().size());
ASSERT_EQ(4u, output_ports().size());
ASSERT_TRUE(manager_->input_stream());
- std::vector<UsbMidiInputStream::JackUniqueKey> keys =
- manager_->input_stream()->RegisteredJackKeysForTesting();
+ std::vector<UsbMidiJack> jacks = manager_->input_stream()->jacks();
ASSERT_EQ(4u, manager_->output_streams().size());
EXPECT_EQ(2u, manager_->output_streams()[0]->jack().jack_id);
EXPECT_EQ(3u, manager_->output_streams()[1]->jack().jack_id);
- ASSERT_EQ(2u, keys.size());
- EXPECT_EQ(2, keys[0].endpoint_number);
+ ASSERT_EQ(2u, jacks.size());
+ EXPECT_EQ(2, jacks[0].endpoint_number());
EXPECT_EQ(
"UsbMidiDevice::GetDescriptor\n"
@@ -484,10 +482,9 @@ TEST_F(MidiManagerUsbTest, AttachDevice) {
ASSERT_EQ(0u, input_ports().size());
ASSERT_EQ(0u, output_ports().size());
ASSERT_TRUE(manager_->input_stream());
- std::vector<UsbMidiInputStream::JackUniqueKey> keys =
- manager_->input_stream()->RegisteredJackKeysForTesting();
+ std::vector<UsbMidiJack> jacks = manager_->input_stream()->jacks();
ASSERT_EQ(0u, manager_->output_streams().size());
- ASSERT_EQ(0u, keys.size());
+ ASSERT_EQ(0u, jacks.size());
EXPECT_EQ("", logger_.TakeLog());
scoped_ptr<FakeUsbMidiDevice> new_device(new FakeUsbMidiDevice(&logger_));
@@ -497,12 +494,12 @@ TEST_F(MidiManagerUsbTest, AttachDevice) {
ASSERT_EQ(1u, input_ports().size());
ASSERT_EQ(2u, output_ports().size());
ASSERT_TRUE(manager_->input_stream());
- keys = manager_->input_stream()->RegisteredJackKeysForTesting();
+ jacks = manager_->input_stream()->jacks();
ASSERT_EQ(2u, manager_->output_streams().size());
EXPECT_EQ(2u, manager_->output_streams()[0]->jack().jack_id);
EXPECT_EQ(3u, manager_->output_streams()[1]->jack().jack_id);
- ASSERT_EQ(1u, keys.size());
- EXPECT_EQ(2, keys[0].endpoint_number);
+ ASSERT_EQ(1u, jacks.size());
+ EXPECT_EQ(2, jacks[0].endpoint_number());
EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_.TakeLog());
}
diff --git a/media/midi/usb_midi_device.h b/media/midi/usb_midi_device.h
index 4552f16..3216614 100644
--- a/media/midi/usb_midi_device.h
+++ b/media/midi/usb_midi_device.h
@@ -33,6 +33,8 @@ class MEDIA_EXPORT UsbMidiDeviceDelegate {
// Called when a USB-MIDI device is attached.
virtual void OnDeviceAttached(scoped_ptr<UsbMidiDevice> device) = 0;
+ // Called when a USB-MIDI device is detached.
+ virtual void OnDeviceDetached(size_t index) = 0;
};
// UsbMidiDevice represents a USB-MIDI device.
diff --git a/media/midi/usb_midi_device_factory_android.cc b/media/midi/usb_midi_device_factory_android.cc
index 840e109..6302572 100644
--- a/media/midi/usb_midi_device_factory_android.cc
+++ b/media/midi/usb_midi_device_factory_android.cc
@@ -83,6 +83,14 @@ void UsbMidiDeviceFactoryAndroid::OnUsbMidiDeviceAttached(
new UsbMidiDeviceAndroid(raw_device, delegate_)));
}
+// Called from the Java world.
+void UsbMidiDeviceFactoryAndroid::OnUsbMidiDeviceDetached(
+ JNIEnv* env,
+ jobject caller,
+ jint index) {
+ delegate_->OnDeviceDetached(index);
+}
+
bool UsbMidiDeviceFactoryAndroid::RegisterUsbMidiDeviceFactory(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/media/midi/usb_midi_device_factory_android.h b/media/midi/usb_midi_device_factory_android.h
index 6c5ce17..7beb9fd 100644
--- a/media/midi/usb_midi_device_factory_android.h
+++ b/media/midi/usb_midi_device_factory_android.h
@@ -32,6 +32,7 @@ class MEDIA_EXPORT UsbMidiDeviceFactoryAndroid : public UsbMidiDevice::Factory {
jobject caller,
jobjectArray devices);
void OnUsbMidiDeviceAttached(JNIEnv* env, jobject caller, jobject device);
+ void OnUsbMidiDeviceDetached(JNIEnv* env, jobject caller, jint index);
static bool RegisterUsbMidiDeviceFactory(JNIEnv* env);
diff --git a/media/midi/usb_midi_input_stream.cc b/media/midi/usb_midi_input_stream.cc
index 97e3079..63ca24b 100644
--- a/media/midi/usb_midi_input_stream.cc
+++ b/media/midi/usb_midi_input_stream.cc
@@ -47,6 +47,7 @@ void UsbMidiInputStream::Add(const UsbMidiJack& jack) {
jack.endpoint_number(),
jack.cable_number);
+ jacks_.push_back(jack);
DCHECK(jack_dictionary_.end() == jack_dictionary_.find(key));
jack_dictionary_.insert(std::make_pair(key, jack_dictionary_.size()));
}
@@ -89,17 +90,4 @@ void UsbMidiInputStream::ProcessOnePacket(UsbMidiDevice* device,
delegate_->OnReceivedData(it->second, &packet[1], packet_size, time);
}
-std::vector<UsbMidiInputStream::JackUniqueKey>
-UsbMidiInputStream::RegisteredJackKeysForTesting() const {
- std::vector<JackUniqueKey> result(jack_dictionary_.size(),
- JackUniqueKey(0, 0, 0));
- for (std::map<JackUniqueKey, size_t>::const_iterator it =
- jack_dictionary_.begin();
- it != jack_dictionary_.end(); ++it) {
- DCHECK_LT(it->second, result.size());
- result[it->second] = it->first;
- }
- return result;
-}
-
} // namespace media
diff --git a/media/midi/usb_midi_input_stream.h b/media/midi/usb_midi_input_stream.h
index 8b97fbf..bd12706 100644
--- a/media/midi/usb_midi_input_stream.h
+++ b/media/midi/usb_midi_input_stream.h
@@ -60,7 +60,7 @@ class MEDIA_EXPORT UsbMidiInputStream {
size_t size,
base::TimeTicks time);
- std::vector<JackUniqueKey> RegisteredJackKeysForTesting() const;
+ const std::vector<UsbMidiJack>& jacks() const { return jacks_; }
private:
static const size_t kPacketSize = 4;
@@ -71,6 +71,7 @@ class MEDIA_EXPORT UsbMidiInputStream {
const uint8* packet,
base::TimeTicks time);
+ std::vector<UsbMidiJack> jacks_;
// A map from UsbMidiJack to its index in |jacks_|.
std::map<JackUniqueKey, size_t> jack_dictionary_;