Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Unified Diff: media/midi/midi_manager_alsa.cc

Issue 968663004: Improve MidiManagerAlsa manufacturer reporting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@udev
Patch Set: Address reviewer comments Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/midi/midi_manager_alsa.h ('k') | media/midi/midi_manager_alsa_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/midi/midi_manager_alsa.cc
diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc
index 9043f1f8cc1223eff2cf268053f25240d979ffb6..6dbae8c7f8cfe411bf00e3094b386b9eae9dd6a1 100644
--- a/media/midi/midi_manager_alsa.cc
+++ b/media/midi/midi_manager_alsa.cc
@@ -15,6 +15,7 @@
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
@@ -41,6 +42,15 @@ int AddrToInt(const snd_seq_addr_t* addr) {
return (addr->client << 8) | addr->port;
}
+#if defined(USE_UDEV)
+// Copied from components/storage_monitor/udev_util_linux.cc.
+std::string GetUdevDevicePropertyValue(udev_device* udev_device,
+ const char* key) {
+ const char* value = device::udev_device_get_property_value(udev_device, key);
+ return value ? value : std::string();
+}
+#endif // defined(USE_UDEV)
+
class CardInfo {
public:
CardInfo(const std::string name, const std::string manufacturer,
@@ -60,6 +70,9 @@ MidiManagerAlsa::MidiManagerAlsa()
out_client_id_(-1),
in_port_(-1),
decoder_(NULL),
+#if defined(USE_UDEV)
+ udev_(device::udev_new()),
+#endif // defined(USE_UDEV)
send_thread_("MidiSendThread"),
event_thread_("MidiEventThread"),
event_thread_shutdown_(false) {
@@ -126,11 +139,9 @@ void MidiManagerAlsa::StartInitialization() {
return CompleteInitialization(MIDI_INITIALIZATION_ERROR);
}
- // Use a heuristic to extract the list of manufacturers for the hardware MIDI
+ // Extract the list of manufacturers for the hardware MIDI
// devices. This won't work for all devices. It is also brittle until
// hotplug is implemented. (See http://crbug.com/279097.)
- // TODO(agoode): Make manufacturer extraction simple and reliable.
- // http://crbug.com/377250.
ScopedVector<CardInfo> cards;
snd_ctl_card_info_t* card;
snd_rawmidi_info_t* midi_out;
@@ -138,8 +149,8 @@ void MidiManagerAlsa::StartInitialization() {
snd_ctl_card_info_alloca(&card);
snd_rawmidi_info_alloca(&midi_out);
snd_rawmidi_info_alloca(&midi_in);
- for (int index = -1; !snd_card_next(&index) && index >= 0; ) {
- const std::string id = base::StringPrintf("hw:CARD=%i", index);
+ for (int card_index = -1; !snd_card_next(&card_index) && card_index >= 0; ) {
+ const std::string id = base::StringPrintf("hw:CARD=%i", card_index);
snd_ctl_t* handle;
int err = snd_ctl_open(&handle, id.c_str(), 0);
if (err != 0) {
@@ -168,20 +179,33 @@ void MidiManagerAlsa::StartInitialization() {
if (!output && !input)
continue;
+ // Get Alsa properties.
snd_rawmidi_info_t* midi = midi_out ? midi_out : midi_in;
const std::string name = snd_rawmidi_info_get_name(midi);
- // We assume that card longname is in the format of
- // "<manufacturer> <name> at <bus>". Otherwise, we give up to detect
- // a manufacturer name here.
- std::string manufacturer;
- const std::string card_name = snd_ctl_card_info_get_longname(card);
- size_t at_index = card_name.rfind(" at ");
- if (std::string::npos != at_index) {
- size_t name_index = card_name.rfind(name, at_index - 1);
- if (std::string::npos != name_index)
- manufacturer = card_name.substr(0, name_index - 1);
- }
+ const std::string longname = snd_ctl_card_info_get_longname(card);
const std::string driver = snd_ctl_card_info_get_driver(card);
+
+ // Get udev properties if available.
+ std::string udev_id_vendor_enc;
+ std::string udev_id_vendor_id;
+ std::string udev_id_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(
+ udev_.get(), "sound", sysname.c_str()));
+ udev_id_vendor_enc = GetUdevDevicePropertyValue(
+ udev_device.get(), "ID_VENDOR_ENC");
+ udev_id_vendor_id = GetUdevDevicePropertyValue(
+ udev_device.get(), "ID_VENDOR_ID");
+ udev_id_vendor_from_database = GetUdevDevicePropertyValue(
+ udev_device.get(), "ID_VENDOR_FROM_DATABASE");
+#endif // defined(USE_UDEV)
+
+ const std::string manufacturer = ExtractManufacturer(
+ udev_id_vendor_enc, udev_id_vendor_id, udev_id_vendor_from_database,
+ name, longname);
+
cards.push_back(new CardInfo(name, manufacturer, driver));
}
snd_ctl_close(handle);
@@ -447,6 +471,60 @@ void MidiManagerAlsa::EventLoop() {
base::Bind(&MidiManagerAlsa::EventLoop, base::Unretained(this)));
}
+std::string MidiManagerAlsa::UnescapeUdev(const std::string& s) {
wolenetz 2015/03/04 22:18:35 nit: style: "Function declaration order should mat
Adam Goode 2015/03/04 22:57:35 Done.
+ std::string unescaped;
+ const size_t size = s.size();
+ for (size_t i = 0; i < size; ++i) {
+ char c = s[i];
+ if ((i + 3 < size) && c == '\\' && s[i + 1] == 'x') {
+ c = (HexDigitToInt(s[i + 2]) << 4) +
+ HexDigitToInt(s[i + 3]);
+ i += 3;
+ }
+ unescaped.push_back(c);
+ }
+ return unescaped;
+}
+
+std::string MidiManagerAlsa::ExtractManufacturer(
+ const std::string& udev_id_vendor_enc,
+ 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) {
+ // Let's try to determine the manufacturer. Here is the ordered preference
+ // in extraction:
+ // 1. Vendor name from the USB device iManufacturer string, stored in
+ // udev_id_vendor_enc.
+ // 2. Vendor name from the udev hwid database.
+ // 3. Heuristic from ALSA.
+
+ // Is the vendor string not just the USB vendor hex id?
+ std::string udev_id_vendor = UnescapeUdev(udev_id_vendor_enc);
+ if (udev_id_vendor != udev_id_vendor_id) {
+ return udev_id_vendor;
+ }
+
+ // Is there a vendor string in the hardware database?
+ if (!udev_id_vendor_from_database.empty()) {
+ return udev_id_vendor_from_database;
+ }
+
+ // Ok, udev gave us nothing useful. So try a heuristic.
+ // We assume that card longname is in the format of
+ // "<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) {
+ size_t name_index = alsa_longname.rfind(alsa_name, at_index - 1);
+ if (std::string::npos != name_index)
+ return alsa_longname.substr(0, name_index - 1);
+ }
+
+ // Failure.
+ return "";
+}
+
MidiManager* MidiManager::Create() {
return new MidiManagerAlsa();
}
« no previous file with comments | « media/midi/midi_manager_alsa.h ('k') | media/midi/midi_manager_alsa_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698