summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authoryhirano <yhirano@chromium.org>2015-02-26 17:01:15 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-27 01:01:56 +0000
commit2fff1004b744b9eb72ecbfbd82c269b3de4172de (patch)
treed4b4c985640a2442d75934161af1ee252c168f20 /media
parent780cc4645ee81e7b29e23753b29be1db790e0d1d (diff)
downloadchromium_src-2fff1004b744b9eb72ecbfbd82c269b3de4172de.zip
chromium_src-2fff1004b744b9eb72ecbfbd82c269b3de4172de.tar.gz
chromium_src-2fff1004b744b9eb72ecbfbd82c269b3de4172de.tar.bz2
[MIDI][Android] Support device attach event.
This CL introduces device attach support for Android Web MIDI. BUG=460901 Review URL: https://codereview.chromium.org/943213003 Cr-Commit-Position: refs/heads/master@{#318364}
Diffstat (limited to 'media')
-rw-r--r--media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java10
-rw-r--r--media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java144
-rw-r--r--media/midi/midi_manager_usb.cc86
-rw-r--r--media/midi/midi_manager_usb.h2
-rw-r--r--media/midi/midi_manager_usb_unittest.cc49
-rw-r--r--media/midi/usb_midi_device.h5
-rw-r--r--media/midi/usb_midi_device_factory_android.cc17
-rw-r--r--media/midi/usb_midi_device_factory_android.h1
-rw-r--r--media/midi/usb_midi_input_stream.cc22
-rw-r--r--media/midi/usb_midi_input_stream.h5
-rw-r--r--media/midi/usb_midi_input_stream_unittest.cc38
11 files changed, 255 insertions, 124 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 27a734a..35520b4 100644
--- a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
@@ -65,6 +65,11 @@ class UsbMidiDeviceAndroid {
private long mNativePointer;
/**
+ * The underlying USB device.
+ */
+ private UsbDevice mUsbDevice;
+
+ /**
* Audio interface subclass code for MIDI.
*/
static final int MIDI_SUBCLASS = 3;
@@ -79,6 +84,7 @@ class UsbMidiDeviceAndroid {
mEndpointMap = new SparseArray<UsbEndpoint>();
mRequestMap = new HashMap<UsbEndpoint, UsbRequest>();
mHandler = new Handler();
+ mUsbDevice = device;
mIsClosed = false;
mHasInputThread = false;
mNativePointer = 0;
@@ -177,6 +183,10 @@ class UsbMidiDeviceAndroid {
});
}
+ UsbDevice getUsbDevice() {
+ return mUsbDevice;
+ }
+
/**
* 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 60b73c5..5eafee6 100644
--- a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java
@@ -13,6 +13,7 @@ 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;
@@ -35,7 +36,7 @@ class UsbMidiDeviceFactoryAndroid {
private UsbManager mUsbManager;
/**
- * A BroadcastReceiver for USB device permission requests.
+ * A BroadcastReceiver for USB device events.
*/
private BroadcastReceiver mReceiver;
@@ -50,6 +51,11 @@ class UsbMidiDeviceFactoryAndroid {
private Set<UsbDevice> mRequestedDevices;
/**
+ * True when the enumeration is in progress.
+ */
+ private boolean mIsEnumeratingDevices;
+
+ /**
* The identifier of this factory.
*/
private long mNativePointer;
@@ -59,107 +65,141 @@ class UsbMidiDeviceFactoryAndroid {
/**
* Constructs a UsbMidiDeviceAndroid.
+ * @param context
* @param nativePointer The native pointer to which the created factory is associated.
*/
- UsbMidiDeviceFactoryAndroid(long nativePointer) {
+ 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 (ACTION_USB_PERMISSION.equals(intent.getAction())) {
+ onUsbDevicePermissionRequestDone(context, intent);
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+ 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(long nativePointer) {
- return new UsbMidiDeviceFactoryAndroid(nativePointer);
+ 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 onRequestDone will be called.
+ * 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) {
- mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+ assert !mIsEnumeratingDevices;
+ mIsEnumeratingDevices = true;
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()) {
+ if (devices.isEmpty()) {
// No USB-MIDI devices are found.
+ mIsEnumeratingDevices = false;
return false;
}
+ for (UsbDevice device: devices.values()) {
+ requestDevicePermissionIfNecessary(context, device);
+ }
+ return true;
+ }
- IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
- onRequestDone(context, intent);
- }
+ /**
+ * 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 (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;
}
- };
- 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.
+ *
+ * @param context
+ * @param intent
*/
- private void onRequestDone(Context context, Intent intent) {
+ private void onUsbDevicePermissionRequestDone(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.
+ 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) {
// Now we can add the device.
- mDevices.add(new UsbMidiDeviceAndroid(mUsbManager, device));
+ midiDevice = new UsbMidiDeviceAndroid(mUsbManager, device);
+ mDevices.add(midiDevice);
}
- if (mRequestedDevices.isEmpty()) {
- // All requests are done.
- context.unregisterReceiver(mReceiver);
- if (mNativePointer != 0) {
- nativeOnUsbMidiDeviceRequestDone(mNativePointer, mDevices.toArray());
- }
+
+ 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() {
+ 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);
}
diff --git a/media/midi/midi_manager_usb.cc b/media/midi/midi_manager_usb.cc
index 5e08d1d..3b6c885 100644
--- a/media/midi/midi_manager_usb.cc
+++ b/media/midi/midi_manager_usb.cc
@@ -68,6 +68,12 @@ void MidiManagerUsb::ReceiveUsbMidiData(UsbMidiDevice* device,
time);
}
+void MidiManagerUsb::OnDeviceAttached(scoped_ptr<UsbMidiDevice> device) {
+ int device_id = devices_.size();
+ devices_.push_back(device.release());
+ AddPorts(devices_.back(), device_id);
+}
+
void MidiManagerUsb::OnReceivedData(size_t jack_index,
const uint8* data,
size_t size,
@@ -82,50 +88,56 @@ void MidiManagerUsb::OnEnumerateDevicesDone(bool result,
initialize_callback_.Run(MIDI_INITIALIZATION_ERROR);
return;
}
+ input_stream_.reset(new UsbMidiInputStream(this));
devices->swap(devices_);
- std::vector<UsbMidiJack> input_jacks;
for (size_t i = 0; i < devices_.size(); ++i) {
- UsbMidiDescriptorParser parser;
- std::vector<uint8> descriptor = devices_[i]->GetDescriptor();
- const uint8* data = descriptor.size() > 0 ? &descriptor[0] : NULL;
- std::vector<UsbMidiJack> jacks;
- bool parse_result = parser.Parse(devices_[i],
- data,
- descriptor.size(),
- &jacks);
- if (!parse_result) {
+ if (!AddPorts(devices_[i], i)) {
initialize_callback_.Run(MIDI_INITIALIZATION_ERROR);
return;
}
- for (size_t j = 0; j < jacks.size(); ++j) {
- if (jacks[j].direction() == UsbMidiJack::DIRECTION_OUT) {
- output_streams_.push_back(new UsbMidiOutputStream(jacks[j]));
- // TODO(yhirano): Set appropriate properties.
- // TODO(yhiran): Port ID should contain product ID / vendor ID.
- // Port ID must be unique in a MIDI manager. This (and the below) ID
- // setting is sufficiently unique although there is no user-friendly
- // meaning.
- MidiPortInfo port;
- port.state = MIDI_PORT_OPENED;
- port.id = base::StringPrintf("port-%ld-%ld",
- static_cast<long>(i),
- static_cast<long>(j));
- AddOutputPort(port);
- } else {
- DCHECK_EQ(jacks[j].direction(), UsbMidiJack::DIRECTION_IN);
- input_jacks.push_back(jacks[j]);
- // TODO(yhirano): Set appropriate properties.
- MidiPortInfo port;
- port.state = MIDI_PORT_OPENED;
- port.id = base::StringPrintf("port-%ld-%ld",
- static_cast<long>(i),
- static_cast<long>(j));
- AddInputPort(port);
- }
- }
}
- input_stream_.reset(new UsbMidiInputStream(input_jacks, this));
initialize_callback_.Run(MIDI_OK);
}
+bool MidiManagerUsb::AddPorts(UsbMidiDevice* device, int device_id) {
+ UsbMidiDescriptorParser parser;
+ std::vector<uint8> descriptor = device->GetDescriptor();
+ const uint8* data = descriptor.size() > 0 ? &descriptor[0] : NULL;
+ std::vector<UsbMidiJack> jacks;
+ bool parse_result = parser.Parse(device,
+ data,
+ descriptor.size(),
+ &jacks);
+ if (!parse_result)
+ return false;
+
+ for (size_t j = 0; j < jacks.size(); ++j) {
+ if (jacks[j].direction() == UsbMidiJack::DIRECTION_OUT) {
+ output_streams_.push_back(new UsbMidiOutputStream(jacks[j]));
+ // TODO(yhirano): Set appropriate properties.
+ // TODO(yhiran): Port ID should contain product ID / vendor ID.
+ // Port ID must be unique in a MIDI manager. This (and the below) ID
+ // setting is sufficiently unique although there is no user-friendly
+ // meaning.
+ MidiPortInfo port;
+ port.state = MIDI_PORT_OPENED;
+ port.id = base::StringPrintf("port-%d-%ld",
+ device_id,
+ static_cast<long>(j));
+ AddOutputPort(port);
+ } else {
+ DCHECK_EQ(jacks[j].direction(), UsbMidiJack::DIRECTION_IN);
+ input_stream_->Add(jacks[j]);
+ // TODO(yhirano): Set appropriate properties.
+ MidiPortInfo port;
+ port.state = MIDI_PORT_OPENED;
+ port.id = base::StringPrintf("port-%d-%ld",
+ device_id,
+ static_cast<long>(j));
+ AddInputPort(port);
+ }
+ }
+ return true;
+}
+
} // namespace media
diff --git a/media/midi/midi_manager_usb.h b/media/midi/midi_manager_usb.h
index d15a828..357b5da 100644
--- a/media/midi/midi_manager_usb.h
+++ b/media/midi/midi_manager_usb.h
@@ -44,6 +44,7 @@ class MEDIA_EXPORT MidiManagerUsb : public MidiManager,
const uint8* data,
size_t size,
base::TimeTicks time) override;
+ void OnDeviceAttached(scoped_ptr<UsbMidiDevice> device) override;
// UsbMidiInputStream::Delegate implementation.
void OnReceivedData(size_t jack_index,
@@ -67,6 +68,7 @@ class MEDIA_EXPORT MidiManagerUsb : public MidiManager,
private:
void OnEnumerateDevicesDone(bool result, UsbMidiDevice::Devices* devices);
+ bool AddPorts(UsbMidiDevice* device, int device_id);
scoped_ptr<UsbMidiDevice::Factory> device_factory_;
ScopedVector<UsbMidiDevice> devices_;
diff --git a/media/midi/midi_manager_usb_unittest.cc b/media/midi/midi_manager_usb_unittest.cc
index 202bead..efcf604 100644
--- a/media/midi/midi_manager_usb_unittest.cc
+++ b/media/midi/midi_manager_usb_unittest.cc
@@ -457,6 +457,55 @@ TEST_F(MidiManagerUsbTest, Receive) {
logger_.TakeLog());
}
+TEST_F(MidiManagerUsbTest, AttachDevice) {
+ uint8 descriptor[] = {
+ 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
+ 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
+ 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
+ 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
+ 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
+ 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
+ 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
+ 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
+ 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
+ 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
+ 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x25, 0x01, 0x01, 0x07,
+ };
+
+ Initialize();
+ ScopedVector<UsbMidiDevice> devices;
+ EXPECT_FALSE(IsInitializationCallbackInvoked());
+ RunCallbackUntilCallbackInvoked(true, &devices);
+ EXPECT_EQ(MIDI_OK, GetInitializationResult());
+
+ 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();
+ ASSERT_EQ(0u, manager_->output_streams().size());
+ ASSERT_EQ(0u, keys.size());
+ EXPECT_EQ("", logger_.TakeLog());
+
+ scoped_ptr<FakeUsbMidiDevice> new_device(new FakeUsbMidiDevice(&logger_));
+ new_device->SetDescriptor(ToVector(descriptor));
+ manager_->OnDeviceAttached(new_device.Pass());
+
+ ASSERT_EQ(1u, input_ports().size());
+ ASSERT_EQ(2u, output_ports().size());
+ ASSERT_TRUE(manager_->input_stream());
+ keys = manager_->input_stream()->RegisteredJackKeysForTesting();
+ 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);
+ EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_.TakeLog());
+}
+
} // namespace
} // namespace media
diff --git a/media/midi/usb_midi_device.h b/media/midi/usb_midi_device.h
index 6af92b6..4552f16 100644
--- a/media/midi/usb_midi_device.h
+++ b/media/midi/usb_midi_device.h
@@ -15,6 +15,7 @@
namespace media {
+class MidiManagerUsb;
class UsbMidiDevice;
// Delegate class for UsbMidiDevice.
@@ -29,6 +30,9 @@ class MEDIA_EXPORT UsbMidiDeviceDelegate {
const uint8* data,
size_t size,
base::TimeTicks time) = 0;
+
+ // Called when a USB-MIDI device is attached.
+ virtual void OnDeviceAttached(scoped_ptr<UsbMidiDevice> device) = 0;
};
// UsbMidiDevice represents a USB-MIDI device.
@@ -45,6 +49,7 @@ class MEDIA_EXPORT UsbMidiDevice {
public:
typedef base::Callback<void(bool result, Devices* devices)> Callback;
virtual ~Factory() {}
+
// Enumerates devices.
// Devices that have no USB-MIDI interfaces can be omitted.
// When the operation succeeds, |callback| will be called with |true| and
diff --git a/media/midi/usb_midi_device_factory_android.cc b/media/midi/usb_midi_device_factory_android.cc
index 081e6b2..840e109 100644
--- a/media/midi/usb_midi_device_factory_android.cc
+++ b/media/midi/usb_midi_device_factory_android.cc
@@ -30,7 +30,8 @@ UsbMidiDeviceFactoryAndroid::UsbMidiDeviceFactoryAndroid() : delegate_(NULL) {}
UsbMidiDeviceFactoryAndroid::~UsbMidiDeviceFactoryAndroid() {
JNIEnv* env = base::android::AttachCurrentThread();
if (!raw_factory_.is_null())
- Java_UsbMidiDeviceFactoryAndroid_close(env, raw_factory_.obj());
+ Java_UsbMidiDeviceFactoryAndroid_close(
+ env, raw_factory_.obj(), base::android::GetApplicationContext());
}
void UsbMidiDeviceFactoryAndroid::EnumerateDevices(
@@ -39,7 +40,8 @@ void UsbMidiDeviceFactoryAndroid::EnumerateDevices(
DCHECK(!delegate_);
JNIEnv* env = base::android::AttachCurrentThread();
uintptr_t pointer = reinterpret_cast<uintptr_t>(this);
- raw_factory_.Reset(Java_UsbMidiDeviceFactoryAndroid_create(env, pointer));
+ raw_factory_.Reset(Java_UsbMidiDeviceFactoryAndroid_create(
+ env, base::android::GetApplicationContext(), pointer));
delegate_ = delegate;
callback_ = callback;
@@ -70,6 +72,17 @@ void UsbMidiDeviceFactoryAndroid::OnUsbMidiDeviceRequestDone(
callback_.Run(true, &devices_to_pass);
}
+// Called from the Java world.
+void UsbMidiDeviceFactoryAndroid::OnUsbMidiDeviceAttached(
+ JNIEnv* env,
+ jobject caller,
+ jobject device) {
+ UsbMidiDeviceAndroid::ObjectRef raw_device(env, device);
+ delegate_->OnDeviceAttached(
+ scoped_ptr<UsbMidiDevice>(
+ new UsbMidiDeviceAndroid(raw_device, delegate_)));
+}
+
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 4736375..6c5ce17 100644
--- a/media/midi/usb_midi_device_factory_android.h
+++ b/media/midi/usb_midi_device_factory_android.h
@@ -31,6 +31,7 @@ class MEDIA_EXPORT UsbMidiDeviceFactoryAndroid : public UsbMidiDevice::Factory {
void OnUsbMidiDeviceRequestDone(JNIEnv* env,
jobject caller,
jobjectArray devices);
+ void OnUsbMidiDeviceAttached(JNIEnv* env, jobject caller, jobject device);
static bool RegisterUsbMidiDeviceFactory(JNIEnv* env);
diff --git a/media/midi/usb_midi_input_stream.cc b/media/midi/usb_midi_input_stream.cc
index a46596d..97e3079 100644
--- a/media/midi/usb_midi_input_stream.cc
+++ b/media/midi/usb_midi_input_stream.cc
@@ -37,20 +37,20 @@ bool UsbMidiInputStream::JackUniqueKey::operator<(
return cable_number < that.cable_number;
}
-UsbMidiInputStream::UsbMidiInputStream(const std::vector<UsbMidiJack>& jacks,
- Delegate* delegate)
- : delegate_(delegate) {
- for (size_t i = 0; i < jacks.size(); ++i) {
- jack_dictionary_.insert(
- std::make_pair(JackUniqueKey(jacks[i].device,
- jacks[i].endpoint_number(),
- jacks[i].cable_number),
- i));
- }
-}
+UsbMidiInputStream::UsbMidiInputStream(Delegate* delegate)
+ : delegate_(delegate) {}
UsbMidiInputStream::~UsbMidiInputStream() {}
+void UsbMidiInputStream::Add(const UsbMidiJack& jack) {
+ JackUniqueKey key(jack.device,
+ jack.endpoint_number(),
+ jack.cable_number);
+
+ DCHECK(jack_dictionary_.end() == jack_dictionary_.find(key));
+ jack_dictionary_.insert(std::make_pair(key, jack_dictionary_.size()));
+}
+
void UsbMidiInputStream::OnReceivedData(UsbMidiDevice* device,
int endpoint_number,
const uint8* data,
diff --git a/media/midi/usb_midi_input_stream.h b/media/midi/usb_midi_input_stream.h
index 0841751..8b97fbf 100644
--- a/media/midi/usb_midi_input_stream.h
+++ b/media/midi/usb_midi_input_stream.h
@@ -45,10 +45,11 @@ class MEDIA_EXPORT UsbMidiInputStream {
int cable_number;
};
- UsbMidiInputStream(const std::vector<UsbMidiJack>& jacks,
- Delegate* delegate);
+ explicit UsbMidiInputStream(Delegate* delegate);
~UsbMidiInputStream();
+ void Add(const UsbMidiJack& jack);
+
// This function should be called when some data arrives to a USB-MIDI
// endpoint. This function converts the data to MIDI data and call
// |delegate->OnReceivedData| with it.
diff --git a/media/midi/usb_midi_input_stream_unittest.cc b/media/midi/usb_midi_input_stream_unittest.cc
index 835d6727..0ec1568 100644
--- a/media/midi/usb_midi_input_stream_unittest.cc
+++ b/media/midi/usb_midi_input_stream_unittest.cc
@@ -53,26 +53,24 @@ class MockDelegate : public UsbMidiInputStream::Delegate {
class UsbMidiInputStreamTest : public ::testing::Test {
protected:
UsbMidiInputStreamTest() {
- std::vector<UsbMidiJack> jacks;
-
- jacks.push_back(UsbMidiJack(&device1_,
- 84, // jack_id
- 4, // cable_number
- 135)); // endpoint_address
- jacks.push_back(UsbMidiJack(&device2_,
- 85,
- 5,
- 137));
- jacks.push_back(UsbMidiJack(&device2_,
- 84,
- 4,
- 135));
- jacks.push_back(UsbMidiJack(&device1_,
- 85,
- 5,
- 135));
-
- stream_.reset(new UsbMidiInputStream(jacks, &delegate_));
+ stream_.reset(new UsbMidiInputStream(&delegate_));
+
+ stream_->Add(UsbMidiJack(&device1_,
+ 84, // jack_id
+ 4, // cable_number
+ 135)); // endpoint_address
+ stream_->Add(UsbMidiJack(&device2_,
+ 85,
+ 5,
+ 137));
+ stream_->Add(UsbMidiJack(&device2_,
+ 84,
+ 4,
+ 135));
+ stream_->Add(UsbMidiJack(&device1_,
+ 85,
+ 5,
+ 135));
}
TestUsbMidiDevice device1_;