Commit 774a30f2 authored by agoode's avatar agoode Committed by Commit bot

Web MIDI ALSA: Enable hardware based device matching

BUG=486471

Review URL: https://codereview.chromium.org/1145653002

Cr-Commit-Position: refs/heads/master@{#330941}
parent 558c1539
......@@ -124,6 +124,17 @@ int GetCardNumber(udev_device* dev) {
return number;
}
std::string GetVendor(udev_device* dev) {
// Try to get the vendor string. Sometimes it is encoded.
std::string vendor = device::UdevDecodeString(
device::UdevDeviceGetPropertyValue(dev, kUdevIdVendorEnc));
// Sometimes it is not encoded.
if (vendor.empty())
vendor =
UdevDeviceGetPropertyOrSysattr(dev, kUdevIdVendor, kSysattrVendorName);
return vendor;
}
void SetStringIfNonEmpty(base::DictionaryValue* value,
const std::string& path,
const std::string& in_value) {
......@@ -298,8 +309,38 @@ void MidiManagerAlsa::DispatchSendMidiData(MidiManagerClient* client,
base::Unretained(client), data.size()));
}
MidiManagerAlsa::MidiPort::Id::Id() = default;
MidiManagerAlsa::MidiPort::Id::Id(const std::string& bus,
const std::string& vendor_id,
const std::string& model_id,
const std::string& usb_interface_num,
const std::string& serial)
: bus_(bus),
vendor_id_(vendor_id),
model_id_(model_id),
usb_interface_num_(usb_interface_num),
serial_(serial) {
}
MidiManagerAlsa::MidiPort::Id::Id(const Id&) = default;
MidiManagerAlsa::MidiPort::Id::~Id() = default;
bool MidiManagerAlsa::MidiPort::Id::operator==(const Id& rhs) const {
return (bus_ == rhs.bus_) && (vendor_id_ == rhs.vendor_id_) &&
(model_id_ == rhs.model_id_) &&
(usb_interface_num_ == rhs.usb_interface_num_) &&
(serial_ == rhs.serial_);
}
bool MidiManagerAlsa::MidiPort::Id::empty() const {
return bus_.empty() && vendor_id_.empty() && model_id_.empty() &&
usb_interface_num_.empty() && serial_.empty();
}
MidiManagerAlsa::MidiPort::MidiPort(const std::string& path,
const std::string& id,
const Id& id,
int client_id,
int port_id,
int midi_device,
......@@ -339,13 +380,19 @@ scoped_ptr<base::Value> MidiManagerAlsa::MidiPort::Value() const {
}
value->SetString("type", type);
SetStringIfNonEmpty(value.get(), "path", path_);
SetStringIfNonEmpty(value.get(), "id", id_);
SetStringIfNonEmpty(value.get(), "clientName", client_name_);
SetStringIfNonEmpty(value.get(), "portName", port_name_);
value->SetInteger("clientId", client_id_);
value->SetInteger("portId", port_id_);
value->SetInteger("midiDevice", midi_device_);
// Flatten id fields.
SetStringIfNonEmpty(value.get(), "bus", id_.bus());
SetStringIfNonEmpty(value.get(), "vendorId", id_.vendor_id());
SetStringIfNonEmpty(value.get(), "modelId", id_.model_id());
SetStringIfNonEmpty(value.get(), "usbInterfaceNum", id_.usb_interface_num());
SetStringIfNonEmpty(value.get(), "serial", id_.serial());
return value.Pass();
}
......@@ -621,8 +668,7 @@ MidiManagerAlsa::AlsaSeqState::ToMidiPortState(const AlsaCardMap& alsa_cards) {
std::string manufacturer;
std::string driver;
std::string path;
std::string id;
std::string serial;
MidiPort::Id id;
std::string card_name;
std::string card_longname;
int midi_device = -1;
......@@ -633,6 +679,11 @@ MidiManagerAlsa::AlsaSeqState::ToMidiPortState(const AlsaCardMap& alsa_cards) {
card_midi_device = 0;
manufacturer = card->manufacturer();
path = card->path();
id = MidiPort::Id(card->bus(), card->vendor_id(), card->model_id(),
card->usb_interface_num(), card->serial());
card_name = card->name();
card_longname = card->longname();
midi_device = card_midi_device;
++card_midi_device;
......@@ -715,45 +766,31 @@ MidiManagerAlsa::AlsaSeqState::Client::end() const {
}
MidiManagerAlsa::AlsaCard::AlsaCard(udev_device* dev,
const std::string& alsa_name,
const std::string& alsa_longname,
const std::string& alsa_driver,
const std::string& name,
const std::string& longname,
const std::string& driver,
int midi_device_count)
: alsa_name_(alsa_name),
alsa_longname_(alsa_longname),
alsa_driver_(alsa_driver),
midi_device_count_(midi_device_count) {
// Try to get the vendor string. Sometimes it is encoded.
std::string vendor = device::UdevDecodeString(
device::UdevDeviceGetPropertyValue(dev, kUdevIdVendorEnc));
// Sometimes it is not encoded.
if (vendor.empty())
vendor =
UdevDeviceGetPropertyOrSysattr(dev, kUdevIdVendor, kSysattrVendorName);
// Also get the vendor string from the hardware database.
std::string vendor_from_database =
device::UdevDeviceGetPropertyValue(dev, kUdevIdVendorFromDatabase);
// Get the device path.
path_ = device::UdevDeviceGetPropertyValue(dev, kUdevIdPath);
// Get the bus.
bus_ = device::UdevDeviceGetPropertyValue(dev, kUdevIdBus);
// Get the "serial" number. (Often untrustable or missing.)
serial_ =
UdevDeviceGetPropertyOrSysattr(dev, kUdevIdSerialShort, kSysattrGuid);
// Get the vendor id, by either property or sysattr.
vendor_id_ =
UdevDeviceGetPropertyOrSysattr(dev, kUdevIdVendorId, kSysattrVendor);
// Get the model id, by either property or sysattr.
model_id_ =
UdevDeviceGetPropertyOrSysattr(dev, kUdevIdModelId, kSysattrModel);
// Get the usb interface number.
usb_interface_num_ =
device::UdevDeviceGetPropertyValue(dev, kUdevIdUsbInterfaceNum);
manufacturer_ = ExtractManufacturerString(
vendor, vendor_id_, vendor_from_database, alsa_name, alsa_longname);
: name_(name),
longname_(longname),
driver_(driver),
path_(device::UdevDeviceGetPropertyValue(dev, kUdevIdPath)),
bus_(device::UdevDeviceGetPropertyValue(dev, kUdevIdBus)),
vendor_id_(
UdevDeviceGetPropertyOrSysattr(dev, kUdevIdVendorId, kSysattrVendor)),
model_id_(
UdevDeviceGetPropertyOrSysattr(dev, kUdevIdModelId, kSysattrModel)),
usb_interface_num_(
device::UdevDeviceGetPropertyValue(dev, kUdevIdUsbInterfaceNum)),
serial_(UdevDeviceGetPropertyOrSysattr(dev,
kUdevIdSerialShort,
kSysattrGuid)),
midi_device_count_(midi_device_count),
manufacturer_(ExtractManufacturerString(
GetVendor(dev),
vendor_id_,
device::UdevDeviceGetPropertyValue(dev, kUdevIdVendorFromDatabase),
name,
longname)) {
}
MidiManagerAlsa::AlsaCard::~AlsaCard() = default;
......
......@@ -48,8 +48,40 @@ class MIDI_EXPORT MidiManagerAlsa final : public MidiManager {
public:
enum class Type { kInput, kOutput };
// The Id class is used to keep the multiple strings separate
// but compare them all together for equality purposes.
// The individual strings that make up the Id can theoretically contain
// arbitrary characters, so unfortunately there is no simple way to
// concatenate them into a single string.
class Id final {
public:
Id();
Id(const std::string& bus,
const std::string& vendor_id,
const std::string& model_id,
const std::string& usb_interface_num,
const std::string& serial);
Id(const Id&);
~Id();
bool operator==(const Id&) const;
bool empty() const;
std::string bus() const { return bus_; }
std::string vendor_id() const { return vendor_id_; }
std::string model_id() const { return model_id_; }
std::string usb_interface_num() const { return usb_interface_num_; }
std::string serial() const { return serial_; }
private:
std::string bus_;
std::string vendor_id_;
std::string model_id_;
std::string usb_interface_num_;
std::string serial_;
};
MidiPort(const std::string& path,
const std::string& id,
const Id& id,
int client_id,
int port_id,
int midi_device,
......@@ -84,7 +116,7 @@ class MIDI_EXPORT MidiManagerAlsa final : public MidiManager {
// accessors
std::string path() const { return path_; }
std::string id() const { return id_; }
Id id() const { return id_; }
std::string client_name() const { return client_name_; }
std::string port_name() const { return port_name_; }
std::string manufacturer() const { return manufacturer_; }
......@@ -119,7 +151,7 @@ class MIDI_EXPORT MidiManagerAlsa final : public MidiManager {
private:
// Immutable properties.
const std::string id_;
const Id id_;
const int midi_device_;
const Type type_;
......@@ -277,21 +309,22 @@ class MIDI_EXPORT MidiManagerAlsa final : public MidiManager {
class AlsaCard {
public:
AlsaCard(udev_device* dev,
const std::string& alsa_name,
const std::string& alsa_longname,
const std::string& alsa_driver,
const std::string& name,
const std::string& longname,
const std::string& driver,
int midi_device_count);
~AlsaCard();
const std::string alsa_name() const { return alsa_name_; }
const std::string alsa_longname() const { return alsa_longname_; }
const std::string manufacturer() const { return manufacturer_; }
const std::string alsa_driver() const { return alsa_driver_; }
std::string name() const { return name_; }
std::string longname() const { return longname_; }
std::string driver() const { return driver_; }
std::string path() const { return path_; }
std::string bus() const { return bus_; }
std::string vendor_id() const { return vendor_id_; }
std::string model_id() const { return model_id_; }
std::string usb_interface_num() const { return usb_interface_num_; }
std::string serial() const { return serial_; }
int midi_device_count() const { return midi_device_count_; }
// Returns hardware path.
const std::string path() const;
// Returns the id we can use to try to match hardware across different
// paths.
const std::string id() const;
std::string manufacturer() const { return manufacturer_; }
private:
FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer);
......@@ -301,20 +334,20 @@ class MIDI_EXPORT MidiManagerAlsa final : public MidiManager {
const std::string& udev_id_vendor,
const std::string& udev_id_vendor_id,
const std::string& udev_id_vendor_from_database,
const std::string& alsa_name,
const std::string& alsa_longname);
std::string alsa_name_;
std::string alsa_longname_;
std::string manufacturer_;
std::string alsa_driver_;
std::string path_;
std::string bus_;
std::string serial_;
std::string vendor_id_;
std::string model_id_;
std::string usb_interface_num_;
int midi_device_count_;
const std::string& name,
const std::string& longname);
const std::string name_;
const std::string longname_;
const std::string driver_;
const std::string path_;
const std::string bus_;
const std::string vendor_id_;
const std::string model_id_;
const std::string usb_interface_num_;
const std::string serial_;
const int midi_device_count_;
const std::string manufacturer_;
DISALLOW_COPY_AND_ASSIGN(AlsaCard);
};
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment