summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authoragoode <agoode@chromium.org>2015-03-19 12:53:23 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-19 19:53:50 +0000
commiteaea4405a27a01da0de837b09b542f54a31d5d00 (patch)
tree226d6aa8a35b7b00cc95dc3a5cf974b657de6e5e /media
parent9aa5f1b733c4d4f8ed138f0788c12c9069c87322 (diff)
downloadchromium_src-eaea4405a27a01da0de837b09b542f54a31d5d00.zip
chromium_src-eaea4405a27a01da0de837b09b542f54a31d5d00.tar.gz
chromium_src-eaea4405a27a01da0de837b09b542f54a31d5d00.tar.bz2
Improve id quality, create opaque id, prep for hotplug
BUG=466721,431489 Review URL: https://codereview.chromium.org/1020783002 Cr-Commit-Position: refs/heads/master@{#321412}
Diffstat (limited to 'media')
-rw-r--r--media/DEPS1
-rw-r--r--media/midi/midi_manager_alsa.cc299
-rw-r--r--media/midi/midi_manager_alsa.h80
-rw-r--r--media/midi/midi_manager_alsa_unittest.cc63
4 files changed, 344 insertions, 99 deletions
diff --git a/media/DEPS b/media/DEPS
index 13abdcf..a8ee49d 100644
--- a/media/DEPS
+++ b/media/DEPS
@@ -1,5 +1,6 @@
# Do NOT add net/ or ui/base without a great reason, they're huge!
include_rules = [
+ "+crypto",
"+device/udev_linux",
"+gpu",
"+jni",
diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc
index 74e2f42..4b459fd 100644
--- a/media/midi/midi_manager_alsa.cc
+++ b/media/midi/midi_manager_alsa.cc
@@ -10,14 +10,18 @@
#include <string>
#include "base/bind.h"
+#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
+#include "base/values.h"
+#include "crypto/sha2.h"
#include "media/midi/midi_port_info.h"
namespace media {
@@ -38,6 +42,23 @@ const size_t kSendBufferSize = 256;
// hardcoding.
const int kMinimumClientIdForCards = 16;
+// udev key constants.
+const char kSoundClass[] = "sound";
+const char kIdVendor[] = "ID_VENDOR";
+const char kIdVendorEnc[] = "ID_VENDOR_ENC";
+const char kIdVendorFromDatabase[] = "ID_VENDOR_FROM_DATABASE";
+const char kSysattrVendorName[] = "vendor_name";
+const char kIdVendorId[] = "ID_VENDOR_ID";
+const char kSysattrVendor[] = "vendor";
+const char kIdModelId[] = "ID_MODEL_ID";
+const char kSysattrModel[] = "model";
+const char kIdBus[] = "ID_BUS";
+const char kIdPath[] = "ID_PATH";
+const char kUsbInterfaceNum[] = "ID_USB_INTERFACE_NUM";
+
+// ALSA constants.
+const char kAlsaHw[] = "hw";
+
// Constants for the capabilities we search for in inputs and outputs.
// See http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html.
const unsigned int kRequiredInputPortCaps =
@@ -49,6 +70,25 @@ int AddrToInt(const snd_seq_addr_t* addr) {
return (addr->client << 8) | addr->port;
}
+// TODO(agoode): Move this to device/udev_linux.
+#if defined(USE_UDEV)
+const std::string UdevDeviceGetPropertyOrSysattr(
+ struct udev_device* udev_device,
+ const char* property_key,
+ const char* sysattr_key) {
+ // First try the property.
+ std::string value =
+ device::UdevDeviceGetPropertyValue(udev_device, property_key);
+
+ // If no property, look for sysattrs and walk up the parent devices too.
+ while (value.empty() && udev_device) {
+ value = device::UdevDeviceGetSysattrValue(udev_device, sysattr_key);
+ udev_device = device::udev_device_get_parent(udev_device);
+ }
+ return value;
+}
+#endif // defined(USE_UDEV)
+
} // namespace
MidiManagerAlsa::MidiManagerAlsa()
@@ -94,23 +134,19 @@ MidiManagerAlsa::~MidiManagerAlsa() {
// Free the decoder.
snd_midi_event_free(decoder_);
-
- // Free the encoders.
- for (EncoderList::iterator i = encoders_.begin(); i != encoders_.end(); ++i)
- snd_midi_event_free(*i);
}
void MidiManagerAlsa::StartInitialization() {
// TODO(agoode): Move off I/O thread. See http://crbug.com/374341.
// Create client handles.
- int err = snd_seq_open(&in_client_, "hw", SND_SEQ_OPEN_INPUT, 0);
+ int err = snd_seq_open(&in_client_, kAlsaHw, SND_SEQ_OPEN_INPUT, 0);
if (err != 0) {
VLOG(1) << "snd_seq_open fails: " << snd_strerror(err);
return CompleteInitialization(MIDI_INITIALIZATION_ERROR);
}
int in_client_id = snd_seq_client_id(in_client_);
- err = snd_seq_open(&out_client_, "hw", SND_SEQ_OPEN_OUTPUT, 0);
+ err = snd_seq_open(&out_client_, kAlsaHw, SND_SEQ_OPEN_OUTPUT, 0);
if (err != 0) {
VLOG(1) << "snd_seq_open fails: " << snd_strerror(err);
return CompleteInitialization(MIDI_INITIALIZATION_ERROR);
@@ -198,64 +234,102 @@ void MidiManagerAlsa::DispatchSendMidiData(MidiManagerClient* client,
base::Unretained(client), data.size()));
}
-MidiManagerAlsa::MidiDevice::MidiDevice(const MidiManagerAlsa* outer,
- const std::string& alsa_name,
- const std::string& alsa_longname,
- const std::string& alsa_driver,
- int card_index)
- : alsa_name_(alsa_name), alsa_driver_(alsa_driver) {
+MidiManagerAlsa::AlsaRawmidi::AlsaRawmidi(const MidiManagerAlsa* outer,
+ const std::string& alsa_name,
+ const std::string& alsa_longname,
+ const std::string& alsa_driver,
+ int card_index)
+ : alsa_name_(alsa_name),
+ alsa_longname_(alsa_longname),
+ alsa_driver_(alsa_driver) {
// Get udev properties if available.
- std::string udev_id_vendor;
- std::string udev_id_vendor_id;
- std::string udev_id_vendor_from_database;
+ std::string vendor;
+ std::string vendor_from_database;
#if defined(USE_UDEV)
const std::string sysname = base::StringPrintf("card%i", card_index);
device::ScopedUdevDevicePtr udev_device(
- device::udev_device_new_from_subsystem_sysname(outer->udev_.get(),
- "sound", sysname.c_str()));
- udev_id_vendor = device::UdevDecodeString(
- device::UdevDeviceGetPropertyValue(udev_device.get(), "ID_VENDOR_ENC"));
- udev_id_vendor_id =
- device::UdevDeviceGetPropertyValue(udev_device.get(), "ID_VENDOR_ID");
- udev_id_vendor_from_database = device::UdevDeviceGetPropertyValue(
- udev_device.get(), "ID_VENDOR_FROM_DATABASE");
-
- udev_id_path_ =
- device::UdevDeviceGetPropertyValue(udev_device.get(), "ID_PATH");
- udev_id_id_ = device::UdevDeviceGetPropertyValue(udev_device.get(), "ID_ID");
+ device::udev_device_new_from_subsystem_sysname(
+ outer->udev_.get(), kSoundClass, sysname.c_str()));
+
+ // TODO(agoode): Move this to a new utility class in device/udev_linux?
+
+ // Try to get the vendor string. Sometimes it is encoded.
+ vendor = device::UdevDecodeString(
+ device::UdevDeviceGetPropertyValue(udev_device.get(), kIdVendorEnc));
+ // Sometimes it is not encoded.
+ if (vendor.empty())
+ UdevDeviceGetPropertyOrSysattr(udev_device.get(), kIdVendor,
+ kSysattrVendorName);
+ // Also get the vendor string from the hardware database.
+ vendor_from_database = device::UdevDeviceGetPropertyValue(
+ udev_device.get(), kIdVendorFromDatabase);
+
+ // Get the device path.
+ path_ = device::UdevDeviceGetPropertyValue(udev_device.get(), kIdPath);
+
+ // Get the bus.
+ bus_ = device::UdevDeviceGetPropertyValue(udev_device.get(), kIdBus);
+
+ // Get the vendor id, by either property or sysattr.
+ vendor_id_ = UdevDeviceGetPropertyOrSysattr(udev_device.get(), kIdVendorId,
+ kSysattrVendor);
+
+ // Get the model id, by either property or sysattr.
+ model_id_ = UdevDeviceGetPropertyOrSysattr(udev_device.get(), kIdModelId,
+ kSysattrModel);
+
+ // Get the usb interface number.
+ usb_interface_num_ =
+ device::UdevDeviceGetPropertyValue(udev_device.get(), kUsbInterfaceNum);
#endif // defined(USE_UDEV)
- manufacturer_ = ExtractManufacturerString(udev_id_vendor, udev_id_vendor_id,
- udev_id_vendor_from_database,
- alsa_name, alsa_longname);
+ manufacturer_ = ExtractManufacturerString(
+ vendor, vendor_id_, vendor_from_database, alsa_name, alsa_longname);
}
-MidiManagerAlsa::MidiDevice::~MidiDevice() {
+MidiManagerAlsa::AlsaRawmidi::~AlsaRawmidi() {
}
-const std::string MidiManagerAlsa::MidiDevice::alsa_name() const {
+const std::string MidiManagerAlsa::AlsaRawmidi::alsa_name() const {
return alsa_name_;
}
-const std::string MidiManagerAlsa::MidiDevice::manufacturer() const {
+const std::string MidiManagerAlsa::AlsaRawmidi::alsa_longname() const {
+ return alsa_longname_;
+}
+
+const std::string MidiManagerAlsa::AlsaRawmidi::manufacturer() const {
return manufacturer_;
}
-const std::string MidiManagerAlsa::MidiDevice::alsa_driver() const {
+const std::string MidiManagerAlsa::AlsaRawmidi::alsa_driver() const {
return alsa_driver_;
}
-const std::string MidiManagerAlsa::MidiDevice::udev_id_path() const {
- return udev_id_path_;
+const std::string MidiManagerAlsa::AlsaRawmidi::path() const {
+ return path_;
+}
+
+const std::string MidiManagerAlsa::AlsaRawmidi::bus() const {
+ return bus_;
+}
+
+const std::string MidiManagerAlsa::AlsaRawmidi::vendor_id() const {
+ return vendor_id_;
}
-const std::string MidiManagerAlsa::MidiDevice::udev_id_id() const {
- return udev_id_id_;
+const std::string MidiManagerAlsa::AlsaRawmidi::id() const {
+ std::string id = vendor_id_;
+ if (!model_id_.empty())
+ id += ":" + model_id_;
+ if (!usb_interface_num_.empty())
+ id += ":" + usb_interface_num_;
+ return id;
}
// static
-std::string MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+std::string MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
const std::string& udev_id_vendor,
const std::string& udev_id_vendor_id,
const std::string& udev_id_vendor_from_database,
@@ -263,12 +337,12 @@ std::string MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
const std::string& alsa_longname) {
// Let's try to determine the manufacturer. Here is the ordered preference
// in extraction:
- // 1. Vendor name from the USB device iManufacturer string, from
- // the udev property ID_VENDOR_ENC.
+ // 1. Vendor name from the hardware device string, from udev properties
+ // or sysattrs.
// 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE).
// 3. Heuristic from ALSA.
- // Is the vendor string not just the USB vendor hex id?
+ // Is the vendor string not just the vendor hex id?
if (udev_id_vendor != udev_id_vendor_id) {
return udev_id_vendor;
}
@@ -283,9 +357,9 @@ std::string MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
// "<manufacturer> <name> at <bus>". Otherwise, we give up to detect
// a manufacturer name here.
size_t at_index = alsa_longname.rfind(" at ");
- if (std::string::npos != at_index) {
+ if (at_index && at_index != std::string::npos) {
size_t name_index = alsa_longname.rfind(alsa_name, at_index - 1);
- if (std::string::npos != name_index)
+ if (name_index && name_index != std::string::npos)
return alsa_longname.substr(0, name_index - 1);
}
@@ -293,8 +367,77 @@ std::string MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
return "";
}
-ScopedVector<MidiManagerAlsa::MidiDevice> MidiManagerAlsa::AllMidiDevices() {
- ScopedVector<MidiDevice> devices;
+MidiManagerAlsa::AlsaPortMetadata::AlsaPortMetadata(
+ const std::string& path,
+ const std::string& bus,
+ const std::string& id,
+ const snd_seq_addr_t* address,
+ const std::string& client_name,
+ const std::string& port_name,
+ const std::string& card_name,
+ const std::string& card_longname,
+ Type type)
+ : path_(path),
+ bus_(bus),
+ id_(id),
+ client_addr_(address->client),
+ port_addr_(address->port),
+ client_name_(client_name),
+ port_name_(port_name),
+ card_name_(card_name),
+ card_longname_(card_longname),
+ type_(type) {
+}
+
+MidiManagerAlsa::AlsaPortMetadata::~AlsaPortMetadata() {
+}
+
+scoped_ptr<base::Value> MidiManagerAlsa::AlsaPortMetadata::Value() const {
+ base::DictionaryValue* value = new base::DictionaryValue();
+ value->SetString("path", path_);
+ value->SetString("bus", bus_);
+ value->SetString("id", id_);
+ value->SetInteger("clientAddr", client_addr_);
+ value->SetInteger("portAddr", port_addr_);
+ value->SetString("clientName", client_name_);
+ value->SetString("portName", port_name_);
+ value->SetString("cardName", card_name_);
+ value->SetString("cardLongname", card_longname_);
+ std::string type;
+ switch (type_) {
+ case Type::kInput:
+ type = "input";
+ break;
+
+ case Type::kOutput:
+ type = "output";
+ break;
+ }
+ value->SetString("type", type);
+
+ return scoped_ptr<base::Value>(value).Pass();
+}
+
+std::string MidiManagerAlsa::AlsaPortMetadata::JSONValue() const {
+ std::string json;
+ JSONStringValueSerializer serializer(&json);
+ serializer.Serialize(*Value().get());
+ return json;
+}
+
+// TODO(agoode): Do not use SHA256 here. Instead store a persistent
+// mapping and just use a UUID or other random string.
+// http://crbug.com/465320
+std::string MidiManagerAlsa::AlsaPortMetadata::OpaqueKey() const {
+ uint8 hash[crypto::kSHA256Length];
+ crypto::SHA256HashString(JSONValue(), &hash, sizeof(hash));
+ return base::HexEncode(&hash, sizeof(hash));
+}
+
+// TODO(agoode): Add a client->card/rawmidi mapping to the kernel to avoid
+// needing to probe in this way.
+ScopedVector<MidiManagerAlsa::AlsaRawmidi> MidiManagerAlsa::AllAlsaRawmidis() {
+ ScopedVector<AlsaRawmidi> devices;
snd_ctl_card_info_t* card;
snd_rawmidi_info_t* midi_out;
snd_rawmidi_info_t* midi_in;
@@ -315,7 +458,7 @@ ScopedVector<MidiManagerAlsa::MidiDevice> MidiManagerAlsa::AllMidiDevices() {
snd_ctl_close(handle);
continue;
}
- // Enumerate any rawmidi devices (not subdevices) and extract MidiDevice.
+ // Enumerate any rawmidi devices (not subdevices) and extract AlsaRawmidi.
for (int device = -1;
!snd_ctl_rawmidi_next_device(handle, &device) && device >= 0;) {
bool output;
@@ -333,10 +476,10 @@ ScopedVector<MidiManagerAlsa::MidiDevice> MidiManagerAlsa::AllMidiDevices() {
// Compute and save ALSA and udev properties.
snd_rawmidi_info_t* midi = midi_out ? midi_out : midi_in;
- devices.push_back(new MidiDevice(this, snd_rawmidi_info_get_name(midi),
- snd_ctl_card_info_get_longname(card),
- snd_ctl_card_info_get_driver(card),
- card_index));
+ devices.push_back(new AlsaRawmidi(this, snd_rawmidi_info_get_name(midi),
+ snd_ctl_card_info_get_longname(card),
+ snd_ctl_card_info_get_driver(card),
+ card_index));
}
snd_ctl_close(handle);
}
@@ -345,7 +488,7 @@ ScopedVector<MidiManagerAlsa::MidiDevice> MidiManagerAlsa::AllMidiDevices() {
}
void MidiManagerAlsa::EnumeratePorts() {
- ScopedVector<MidiDevice> devices = AllMidiDevices();
+ ScopedVector<AlsaRawmidi> devices = AllAlsaRawmidis();
snd_seq_port_subscribe_t* subs;
snd_seq_port_subscribe_alloca(&subs);
@@ -376,21 +519,29 @@ void MidiManagerAlsa::EnumeratePorts() {
std::string manufacturer;
std::string driver;
- std::string udev_id_path;
- std::string udev_id_id;
-
- // Join kernel clients against the list of MidiDevices.
+ std::string path;
+ std::string bus;
+ std::string vendor_id;
+ std::string id;
+ std::string card_name;
+ std::string card_longname;
+
+ // Join kernel clients against the list of AlsaRawmidis.
// In the current ALSA kernel implementation, kernel clients match the
// kernel devices in the same order, for devices with client_id over
// kMinimumClientIdForCards.
if ((snd_seq_client_info_get_type(client_info) == SND_SEQ_KERNEL_CLIENT) &&
(current_device < devices.size()) &&
(client_id >= kMinimumClientIdForCards)) {
- const MidiDevice* device = devices[current_device];
+ const AlsaRawmidi* device = devices[current_device];
manufacturer = device->manufacturer();
driver = device->alsa_driver();
- udev_id_path = device->udev_id_path();
- udev_id_id = device->udev_id_id();
+ path = device->path();
+ bus = device->bus();
+ vendor_id = device->vendor_id();
+ id = device->id();
+ card_name = device->alsa_name();
+ card_longname = device->alsa_longname();
current_device++;
}
// Enumerate ports.
@@ -399,9 +550,6 @@ void MidiManagerAlsa::EnumeratePorts() {
if (port_type & SND_SEQ_PORT_TYPE_MIDI_GENERIC) {
const snd_seq_addr_t* addr = snd_seq_port_info_get_addr(port_info);
const std::string name = snd_seq_port_info_get_name(port_info);
- const std::string id_suffix =
- base::StringPrintf("%d:%d/%s/%s", addr->client, addr->port,
- udev_id_path.c_str(), udev_id_id.c_str());
std::string version;
if (!driver.empty()) {
version = driver + " / ";
@@ -424,9 +572,12 @@ void MidiManagerAlsa::EnumeratePorts() {
VLOG(1) << "snd_seq_subscribe_port fails: " << snd_strerror(err);
} else {
source_map_[AddrToInt(sender)] = current_input++;
- AddInputPort(
- MidiPortInfo(base::StringPrintf("input/%s", id_suffix.c_str()),
- manufacturer, name, version, MIDI_PORT_OPENED));
+ const AlsaPortMetadata metadata(path, bus, id, addr, client_name,
+ name, card_name, card_longname,
+ AlsaPortMetadata::Type::kInput);
+ const std::string id = metadata.OpaqueKey();
+ AddInputPort(MidiPortInfo(id.c_str(), manufacturer, name, version,
+ MIDI_PORT_OPENED));
}
}
if ((caps & kRequiredOutputPortCaps) == kRequiredOutputPortCaps) {
@@ -456,13 +607,13 @@ void MidiManagerAlsa::EnumeratePorts() {
VLOG(1) << "snd_seq_subscribe_port fails: " << snd_strerror(err);
snd_seq_delete_simple_port(out_client_, out_port);
} else {
- snd_midi_event_t* encoder;
- snd_midi_event_new(kSendBufferSize, &encoder);
- encoders_.push_back(encoder);
out_ports_.push_back(out_port);
- AddOutputPort(
- MidiPortInfo(base::StringPrintf("output/%s", id_suffix.c_str()),
- manufacturer, name, version, MIDI_PORT_OPENED));
+ const AlsaPortMetadata metadata(path, bus, id, addr, client_name,
+ name, card_name, card_longname,
+ AlsaPortMetadata::Type::kOutput);
+ const std::string id = metadata.OpaqueKey();
+ AddOutputPort(MidiPortInfo(id.c_str(), manufacturer, name, version,
+ MIDI_PORT_OPENED));
}
}
}
@@ -474,7 +625,8 @@ void MidiManagerAlsa::SendMidiData(uint32 port_index,
const std::vector<uint8>& data) {
DCHECK(send_thread_.message_loop_proxy()->BelongsToCurrentThread());
- snd_midi_event_t* encoder = encoders_[port_index];
+ snd_midi_event_t* encoder;
+ snd_midi_event_new(kSendBufferSize, &encoder);
for (unsigned int i = 0; i < data.size(); i++) {
snd_seq_event_t event;
int result = snd_midi_event_encode_byte(encoder, data[i], &event);
@@ -486,6 +638,7 @@ void MidiManagerAlsa::SendMidiData(uint32 port_index,
snd_seq_event_output_direct(out_client_, &event);
}
}
+ snd_midi_event_free(encoder);
}
void MidiManagerAlsa::ScheduleEventLoop() {
diff --git a/media/midi/midi_manager_alsa.h b/media/midi/midi_manager_alsa.h
index 67abfc3..4ee47bf 100644
--- a/media/midi/midi_manager_alsa.h
+++ b/media/midi/midi_manager_alsa.h
@@ -14,6 +14,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
+#include "base/values.h"
#include "media/midi/midi_manager.h"
#if defined(USE_UDEV)
@@ -36,21 +37,25 @@ class MEDIA_EXPORT MidiManagerAlsa : public MidiManager {
private:
FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer);
+ FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, JSONPortMetadata);
- class MidiDevice {
+ class AlsaRawmidi {
public:
- MidiDevice(const MidiManagerAlsa* outer,
- const std::string& alsa_name,
- const std::string& alsa_longname,
- const std::string& alsa_driver,
- int card_index);
- ~MidiDevice();
+ AlsaRawmidi(const MidiManagerAlsa* outer,
+ const std::string& alsa_name,
+ const std::string& alsa_longname,
+ const std::string& alsa_driver,
+ int card_index);
+ ~AlsaRawmidi();
const std::string alsa_name() const;
+ const std::string alsa_longname() const;
const std::string manufacturer() const;
const std::string alsa_driver() const;
- const std::string udev_id_path() const;
- const std::string udev_id_id() const;
+ const std::string path() const;
+ const std::string bus() const;
+ const std::string vendor_id() const;
+ const std::string id() const;
private:
FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer);
@@ -64,16 +69,63 @@ class MEDIA_EXPORT MidiManagerAlsa : public MidiManager {
const std::string& alsa_longname);
std::string alsa_name_;
+ std::string alsa_longname_;
std::string manufacturer_;
std::string alsa_driver_;
- std::string udev_id_path_;
- std::string udev_id_id_;
+ std::string path_;
+ std::string bus_;
+ std::string vendor_id_;
+ std::string model_id_;
+ std::string usb_interface_num_;
- DISALLOW_COPY_AND_ASSIGN(MidiDevice);
+ DISALLOW_COPY_AND_ASSIGN(AlsaRawmidi);
+ };
+
+ class AlsaPortMetadata {
+ public:
+ enum class Type { kInput, kOutput };
+
+ AlsaPortMetadata(const std::string& path,
+ const std::string& bus,
+ const std::string& id,
+ const snd_seq_addr_t* address,
+ const std::string& client_name,
+ const std::string& port_name,
+ const std::string& card_name,
+ const std::string& card_longname,
+ Type type);
+ ~AlsaPortMetadata();
+
+ // Gets a Value representation of this object, suitable for serialization.
+ scoped_ptr<base::Value> Value() const;
+
+ // Gets a string version of Value in JSON format.
+ std::string JSONValue() const;
+
+ // Gets an opaque identifier for this object, suitable for using as the id
+ // field in MidiPort.id on the web. Note that this string does not store
+ // the full state.
+ std::string OpaqueKey() const;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, JSONPortMetadata);
+
+ const std::string path_;
+ const std::string bus_;
+ const std::string id_;
+ const int client_addr_;
+ const int port_addr_;
+ const std::string client_name_;
+ const std::string port_name_;
+ const std::string card_name_;
+ const std::string card_longname_;
+ const Type type_;
+
+ DISALLOW_COPY_AND_ASSIGN(AlsaPortMetadata);
};
// Returns an ordered vector of all the rawmidi devices on the system.
- ScopedVector<MidiDevice> AllMidiDevices();
+ ScopedVector<AlsaRawmidi> AllAlsaRawmidis();
// Enumerate all the ports for initial setup.
void EnumeratePorts();
@@ -101,8 +153,6 @@ class MEDIA_EXPORT MidiManagerAlsa : public MidiManager {
// ALSA event <-> MIDI coders.
snd_midi_event_t* decoder_;
- typedef std::vector<snd_midi_event_t*> EncoderList;
- EncoderList encoders_;
// udev, for querying hardware devices.
#if defined(USE_UDEV)
diff --git a/media/midi/midi_manager_alsa_unittest.cc b/media/midi/midi_manager_alsa_unittest.cc
index 47789b6..6ce4617 100644
--- a/media/midi/midi_manager_alsa_unittest.cc
+++ b/media/midi/midi_manager_alsa_unittest.cc
@@ -10,41 +10,82 @@ namespace media {
TEST(MidiManagerAlsaTest, ExtractManufacturer) {
ASSERT_EQ("My\\x20Vendor",
- MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"My\\x20Vendor", "1234", "My Vendor, Inc.", "Card",
"My Vendor Inc Card at bus"));
- ASSERT_EQ("My Vendor", MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
- "My Vendor", "1234", "My Vendor, Inc.", "Card",
- "My Vendor Inc Card at bus"));
+ ASSERT_EQ("My Vendor",
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
+ "My Vendor", "1234", "My Vendor, Inc.", "Card",
+ "My Vendor Inc Card at bus"));
ASSERT_EQ("My Vendor, Inc.",
- MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"1234", "1234", "My Vendor, Inc.", "Card",
"My Vendor Inc Card at bus"));
ASSERT_EQ("My Vendor Inc",
- MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"1234", "1234", "", "Card", "My Vendor Inc Card at bus"));
ASSERT_EQ("My Vendor Inc",
- MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"", "", "", "Card", "My Vendor Inc Card at bus"));
- ASSERT_EQ("", MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ ASSERT_EQ("", MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"1234", "1234", "", "Card", "Longname"));
ASSERT_EQ("Keystation\\x20Mini\\x2032",
- MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"Keystation\\x20Mini\\x2032", "129d",
"Evolution Electronics, Ltd", "Keystation Mini 32",
"Keystation Mini 32 Keystation Mini 32 at"
" usb-0000:00:14.0-2.4.4, full speed"));
ASSERT_EQ("Keystation Mini 32",
- MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"Keystation Mini 32", "129d", "Evolution Electronics, Ltd",
"Keystation Mini 32",
"Keystation Mini 32 Keystation Mini 32 at"
" usb-0000:00:14.0-2.4.4, full speed"));
ASSERT_EQ("Keystation Mini 32",
- MidiManagerAlsa::MidiDevice::ExtractManufacturerString(
+ MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
"", "", "", "Keystation Mini 32",
"Keystation Mini 32 Keystation Mini 32 at"
" usb-0000:00:14.0-2.4.4, full speed"));
+ ASSERT_EQ("", MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
+ "", "", "", "Serial MIDI (UART16550A)",
+ "Serial MIDI (UART16550A) [Soundcanvas] at 0x3f8, irq 4"));
+ ASSERT_EQ("", MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
+ "", "", "", "VirMIDI", "Virtual MIDI Card 1"));
+}
+
+TEST(MidiManagerAlsaTest, JSONPortMetadata) {
+ snd_seq_addr_t address;
+ address.client = 1;
+ address.port = 2;
+
+ MidiManagerAlsa::AlsaPortMetadata input(
+ "path", "bus", "id", &address, "client_name", "port_name", "card_name",
+ "card_longname", MidiManagerAlsa::AlsaPortMetadata::Type::kInput);
+
+ MidiManagerAlsa::AlsaPortMetadata output(
+ "path", "bus", "id", &address, "client_name", "port_name", "card_name",
+ "card_longname", MidiManagerAlsa::AlsaPortMetadata::Type::kOutput);
+
+ ASSERT_EQ(
+ "{\"bus\":\"bus\",\"cardLongname\":\"card_longname\",\"cardName\":\"card_"
+ "name\","
+ "\"clientAddr\":1,\"clientName\":\"client_name\",\"id\":\"id\",\"path\":"
+ "\"path\","
+ "\"portAddr\":2,\"portName\":\"port_name\",\"type\":\"input\"}",
+ input.JSONValue());
+
+ ASSERT_EQ("6D6186ACF60BB2FD26B5D2E21881CF0541FDB80FAC5BDFFA95CD55739E3BC526",
+ input.OpaqueKey());
+
+ ASSERT_EQ(
+ "{\"bus\":\"bus\",\"cardLongname\":\"card_longname\",\"cardName\":\"card_"
+ "name\","
+ "\"clientAddr\":1,\"clientName\":\"client_name\",\"id\":\"id\",\"path\":"
+ "\"path\","
+ "\"portAddr\":2,\"portName\":\"port_name\",\"type\":\"output\"}",
+ output.JSONValue());
+ ASSERT_EQ("747E553D40F8388A0C1C51261B82869D5EFA8A54860AAFB2F4F7437744982495",
+ output.OpaqueKey());
}
} // namespace media