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

Side by Side Diff: media/midi/midi_manager_alsa.cc

Issue 989913002: Move UdevDecodeString from media/midi to device/udev_linux (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@seq3
Patch Set: Fix unit tests Created 5 years, 9 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/midi/midi_manager_alsa.h" 5 #include "media/midi/midi_manager_alsa.h"
6 6
7 #include <alsa/asoundlib.h> 7 #include <alsa/asoundlib.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_vector.h" 15 #include "base/memory/scoped_vector.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/posix/eintr_wrapper.h" 17 #include "base/posix/eintr_wrapper.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
20 #include "base/threading/thread.h" 19 #include "base/threading/thread.h"
21 #include "base/time/time.h" 20 #include "base/time/time.h"
22 #include "media/midi/midi_port_info.h" 21 #include "media/midi/midi_port_info.h"
23 22
24 namespace media { 23 namespace media {
25 24
26 namespace { 25 namespace {
27 26
28 // Per-output buffer. This can be smaller, but then large sysex messages 27 // Per-output buffer. This can be smaller, but then large sysex messages
29 // will be (harmlessly) split across multiple seq events. This should 28 // will be (harmlessly) split across multiple seq events. This should
30 // not have any real practical effect, except perhaps to slightly reorder 29 // not have any real practical effect, except perhaps to slightly reorder
31 // realtime messages with respect to sysex. 30 // realtime messages with respect to sysex.
32 const size_t kSendBufferSize = 256; 31 const size_t kSendBufferSize = 256;
33 32
34 // Constants for the capabilities we search for in inputs and outputs. 33 // Constants for the capabilities we search for in inputs and outputs.
35 // See http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html. 34 // See http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html.
36 const unsigned int kRequiredInputPortCaps = 35 const unsigned int kRequiredInputPortCaps =
37 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; 36 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
38 const unsigned int kRequiredOutputPortCaps = 37 const unsigned int kRequiredOutputPortCaps =
39 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; 38 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;
40 39
41 int AddrToInt(const snd_seq_addr_t* addr) { 40 int AddrToInt(const snd_seq_addr_t* addr) {
42 return (addr->client << 8) | addr->port; 41 return (addr->client << 8) | addr->port;
43 } 42 }
44 43
45 #if defined(USE_UDEV)
46 // Copied from components/storage_monitor/udev_util_linux.cc.
47 // TODO(agoode): Move this into a common place. Maybe device/udev_linux?
48 std::string GetUdevDevicePropertyValue(udev_device* udev_device,
49 const char* key) {
50 const char* value = device::udev_device_get_property_value(udev_device, key);
51 return value ? value : std::string();
52 }
53 #endif // defined(USE_UDEV)
54
55 } // namespace 44 } // namespace
56 45
57 MidiManagerAlsa::MidiManagerAlsa() 46 MidiManagerAlsa::MidiManagerAlsa()
58 : in_client_(NULL), 47 : in_client_(NULL),
59 out_client_(NULL), 48 out_client_(NULL),
60 out_client_id_(-1), 49 out_client_id_(-1),
61 in_port_(-1), 50 in_port_(-1),
62 decoder_(NULL), 51 decoder_(NULL),
63 #if defined(USE_UDEV) 52 #if defined(USE_UDEV)
64 udev_(device::udev_new()), 53 udev_(device::udev_new()),
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 for (EncoderList::iterator i = encoders_.begin(); i != encoders_.end(); ++i) 317 for (EncoderList::iterator i = encoders_.begin(); i != encoders_.end(); ++i)
329 snd_midi_event_free(*i); 318 snd_midi_event_free(*i);
330 } 319 }
331 320
332 MidiManagerAlsa::CardInfo::CardInfo( 321 MidiManagerAlsa::CardInfo::CardInfo(
333 const MidiManagerAlsa* outer, 322 const MidiManagerAlsa* outer,
334 const std::string& alsa_name, const std::string& alsa_longname, 323 const std::string& alsa_name, const std::string& alsa_longname,
335 const std::string& alsa_driver, int card_index) 324 const std::string& alsa_driver, int card_index)
336 : alsa_name_(alsa_name), alsa_driver_(alsa_driver) { 325 : alsa_name_(alsa_name), alsa_driver_(alsa_driver) {
337 // Get udev properties if available. 326 // Get udev properties if available.
338 std::string udev_id_vendor_enc; 327 std::string udev_id_vendor;
339 std::string udev_id_vendor_id; 328 std::string udev_id_vendor_id;
340 std::string udev_id_vendor_from_database; 329 std::string udev_id_vendor_from_database;
341 330
342 #if defined(USE_UDEV) 331 #if defined(USE_UDEV)
343 const std::string sysname = base::StringPrintf("card%i", card_index); 332 const std::string sysname = base::StringPrintf("card%i", card_index);
344 device::ScopedUdevDevicePtr udev_device( 333 device::ScopedUdevDevicePtr udev_device(
345 device::udev_device_new_from_subsystem_sysname( 334 device::udev_device_new_from_subsystem_sysname(
346 outer->udev_.get(), "sound", sysname.c_str())); 335 outer->udev_.get(), "sound", sysname.c_str()));
347 udev_id_vendor_enc = GetUdevDevicePropertyValue( 336 udev_id_vendor = device::UdevDecodeString(device::UdevDeviceGetPropertyValue(
348 udev_device.get(), "ID_VENDOR_ENC"); 337 udev_device.get(), "ID_VENDOR_ENC"));
349 udev_id_vendor_id = GetUdevDevicePropertyValue( 338 udev_id_vendor_id = device::UdevDeviceGetPropertyValue(
350 udev_device.get(), "ID_VENDOR_ID"); 339 udev_device.get(), "ID_VENDOR_ID");
351 udev_id_vendor_from_database = GetUdevDevicePropertyValue( 340 udev_id_vendor_from_database = device::UdevDeviceGetPropertyValue(
352 udev_device.get(), "ID_VENDOR_FROM_DATABASE"); 341 udev_device.get(), "ID_VENDOR_FROM_DATABASE");
353 342
354 udev_id_path_ = GetUdevDevicePropertyValue( 343 udev_id_path_ = device::UdevDeviceGetPropertyValue(
355 udev_device.get(), "ID_PATH"); 344 udev_device.get(), "ID_PATH");
356 udev_id_id_ = GetUdevDevicePropertyValue( 345 udev_id_id_ = device::UdevDeviceGetPropertyValue(
357 udev_device.get(), "ID_ID"); 346 udev_device.get(), "ID_ID");
358 #endif // defined(USE_UDEV) 347 #endif // defined(USE_UDEV)
359 348
360 manufacturer_ = ExtractManufacturerString( 349 manufacturer_ = ExtractManufacturerString(
361 udev_id_vendor_enc, udev_id_vendor_id, udev_id_vendor_from_database, 350 udev_id_vendor, udev_id_vendor_id, udev_id_vendor_from_database,
362 alsa_name, alsa_longname); 351 alsa_name, alsa_longname);
363 } 352 }
364 353
365 MidiManagerAlsa::CardInfo::~CardInfo() { 354 MidiManagerAlsa::CardInfo::~CardInfo() {
366 } 355 }
367 356
368 const std::string MidiManagerAlsa::CardInfo::alsa_name() const { 357 const std::string MidiManagerAlsa::CardInfo::alsa_name() const {
369 return alsa_name_; 358 return alsa_name_;
370 } 359 }
371 360
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 } 481 }
493 482
494 // Do again. 483 // Do again.
495 event_thread_.message_loop()->PostTask( 484 event_thread_.message_loop()->PostTask(
496 FROM_HERE, 485 FROM_HERE,
497 base::Bind(&MidiManagerAlsa::EventLoop, base::Unretained(this))); 486 base::Bind(&MidiManagerAlsa::EventLoop, base::Unretained(this)));
498 } 487 }
499 488
500 // static 489 // static
501 std::string MidiManagerAlsa::CardInfo::ExtractManufacturerString( 490 std::string MidiManagerAlsa::CardInfo::ExtractManufacturerString(
502 const std::string& udev_id_vendor_enc, 491 const std::string& udev_id_vendor,
503 const std::string& udev_id_vendor_id, 492 const std::string& udev_id_vendor_id,
504 const std::string& udev_id_vendor_from_database, 493 const std::string& udev_id_vendor_from_database,
505 const std::string& alsa_name, 494 const std::string& alsa_name,
506 const std::string& alsa_longname) { 495 const std::string& alsa_longname) {
507 // Let's try to determine the manufacturer. Here is the ordered preference 496 // Let's try to determine the manufacturer. Here is the ordered preference
508 // in extraction: 497 // in extraction:
509 // 1. Vendor name from the USB device iManufacturer string, stored in 498 // 1. Vendor name from the USB device iManufacturer string, from
510 // udev_id_vendor_enc. 499 // the udev property ID_VENDOR_ENC.
511 // 2. Vendor name from the udev hwid database. 500 // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE).
512 // 3. Heuristic from ALSA. 501 // 3. Heuristic from ALSA.
513 502
514 // Is the vendor string not just the USB vendor hex id? 503 // Is the vendor string not just the USB vendor hex id?
515 std::string udev_id_vendor = UnescapeUdev(udev_id_vendor_enc);
516 if (udev_id_vendor != udev_id_vendor_id) { 504 if (udev_id_vendor != udev_id_vendor_id) {
517 return udev_id_vendor; 505 return udev_id_vendor;
518 } 506 }
519 507
520 // Is there a vendor string in the hardware database? 508 // Is there a vendor string in the hardware database?
521 if (!udev_id_vendor_from_database.empty()) { 509 if (!udev_id_vendor_from_database.empty()) {
522 return udev_id_vendor_from_database; 510 return udev_id_vendor_from_database;
523 } 511 }
524 512
525 // Ok, udev gave us nothing useful, or was unavailable. So try a heuristic. 513 // Ok, udev gave us nothing useful, or was unavailable. So try a heuristic.
526 // We assume that card longname is in the format of 514 // We assume that card longname is in the format of
527 // "<manufacturer> <name> at <bus>". Otherwise, we give up to detect 515 // "<manufacturer> <name> at <bus>". Otherwise, we give up to detect
528 // a manufacturer name here. 516 // a manufacturer name here.
529 size_t at_index = alsa_longname.rfind(" at "); 517 size_t at_index = alsa_longname.rfind(" at ");
530 if (std::string::npos != at_index) { 518 if (std::string::npos != at_index) {
531 size_t name_index = alsa_longname.rfind(alsa_name, at_index - 1); 519 size_t name_index = alsa_longname.rfind(alsa_name, at_index - 1);
532 if (std::string::npos != name_index) 520 if (std::string::npos != name_index)
533 return alsa_longname.substr(0, name_index - 1); 521 return alsa_longname.substr(0, name_index - 1);
534 } 522 }
535 523
536 // Failure. 524 // Failure.
537 return ""; 525 return "";
538 } 526 }
539 527
540 // static
541 std::string MidiManagerAlsa::CardInfo::UnescapeUdev(const std::string& s) {
542 std::string unescaped;
543 const size_t size = s.size();
544 for (size_t i = 0; i < size; ++i) {
545 char c = s[i];
546 if ((i + 3 < size) && c == '\\' && s[i + 1] == 'x') {
547 c = (HexDigitToInt(s[i + 2]) << 4) +
548 HexDigitToInt(s[i + 3]);
549 i += 3;
550 }
551 unescaped.push_back(c);
552 }
553 return unescaped;
554 }
555
556 MidiManager* MidiManager::Create() { 528 MidiManager* MidiManager::Create() {
557 return new MidiManagerAlsa(); 529 return new MidiManagerAlsa();
558 } 530 }
559 531
560 } // namespace media 532 } // namespace media
OLDNEW
« 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