diff options
author | yhirano <yhirano@chromium.org> | 2015-02-26 17:01:15 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-27 01:01:56 +0000 |
commit | 2fff1004b744b9eb72ecbfbd82c269b3de4172de (patch) | |
tree | d4b4c985640a2442d75934161af1ee252c168f20 /media | |
parent | 780cc4645ee81e7b29e23753b29be1db790e0d1d (diff) | |
download | chromium_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.java | 10 | ||||
-rw-r--r-- | media/base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java | 144 | ||||
-rw-r--r-- | media/midi/midi_manager_usb.cc | 86 | ||||
-rw-r--r-- | media/midi/midi_manager_usb.h | 2 | ||||
-rw-r--r-- | media/midi/midi_manager_usb_unittest.cc | 49 | ||||
-rw-r--r-- | media/midi/usb_midi_device.h | 5 | ||||
-rw-r--r-- | media/midi/usb_midi_device_factory_android.cc | 17 | ||||
-rw-r--r-- | media/midi/usb_midi_device_factory_android.h | 1 | ||||
-rw-r--r-- | media/midi/usb_midi_input_stream.cc | 22 | ||||
-rw-r--r-- | media/midi/usb_midi_input_stream.h | 5 | ||||
-rw-r--r-- | media/midi/usb_midi_input_stream_unittest.cc | 38 |
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_; |