| OLD | NEW |
| 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 #ifndef MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ | 5 #ifndef MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ |
| 6 #define MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ | 6 #define MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ |
| 7 | 7 |
| 8 #include <alsa/asoundlib.h> | 8 #include <alsa/asoundlib.h> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 void DispatchSendMidiData(MidiManagerClient* client, | 34 void DispatchSendMidiData(MidiManagerClient* client, |
| 35 uint32 port_index, | 35 uint32 port_index, |
| 36 const std::vector<uint8>& data, | 36 const std::vector<uint8>& data, |
| 37 double timestamp) override; | 37 double timestamp) override; |
| 38 | 38 |
| 39 private: | 39 private: |
| 40 friend class MidiManagerAlsaTest; | 40 friend class MidiManagerAlsaTest; |
| 41 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer); | 41 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer); |
| 42 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ToMidiPortState); | 42 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ToMidiPortState); |
| 43 | 43 |
| 44 class AlsaCard; |
| 45 typedef std::map<int, AlsaCard*> AlsaCardMap; |
| 46 |
| 44 class MidiPort { | 47 class MidiPort { |
| 45 public: | 48 public: |
| 46 enum class Type { kInput, kOutput }; | 49 enum class Type { kInput, kOutput }; |
| 47 | 50 |
| 48 MidiPort(const std::string& path, | 51 MidiPort(const std::string& path, |
| 49 const std::string& id, | 52 const std::string& id, |
| 50 int client_id, | 53 int client_id, |
| 51 int port_id, | 54 int port_id, |
| 52 int midi_device, | 55 int midi_device, |
| 53 const std::string& client_name, | 56 const std::string& client_name, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 snd_seq_client_type_t type); | 206 snd_seq_client_type_t type); |
| 204 bool ClientStarted(int client_id); | 207 bool ClientStarted(int client_id); |
| 205 void ClientExit(int client_id); | 208 void ClientExit(int client_id); |
| 206 void PortStart(int client_id, | 209 void PortStart(int client_id, |
| 207 int port_id, | 210 int port_id, |
| 208 const std::string& port_name, | 211 const std::string& port_name, |
| 209 PortDirection direction, | 212 PortDirection direction, |
| 210 bool midi); | 213 bool midi); |
| 211 void PortExit(int client_id, int port_id); | 214 void PortExit(int client_id, int port_id); |
| 212 snd_seq_client_type_t ClientType(int client_id) const; | 215 snd_seq_client_type_t ClientType(int client_id) const; |
| 213 scoped_ptr<TemporaryMidiPortState> ToMidiPortState(); | 216 scoped_ptr<TemporaryMidiPortState> ToMidiPortState( |
| 217 const AlsaCardMap& alsa_cards); |
| 218 |
| 219 int card_client_count() { return card_client_count_; } |
| 214 | 220 |
| 215 private: | 221 private: |
| 216 class Port { | 222 class Port { |
| 217 public: | 223 public: |
| 218 Port(const std::string& name, PortDirection direction, bool midi); | 224 Port(const std::string& name, PortDirection direction, bool midi); |
| 219 ~Port(); | 225 ~Port(); |
| 220 | 226 |
| 221 std::string name() const; | 227 std::string name() const; |
| 222 PortDirection direction() const; | 228 PortDirection direction() const; |
| 223 // True if this port is a MIDI port, instead of another kind of ALSA port. | 229 // True if this port is a MIDI port, instead of another kind of ALSA port. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 252 STLValueDeleter<PortMap> ports_deleter_; | 258 STLValueDeleter<PortMap> ports_deleter_; |
| 253 | 259 |
| 254 DISALLOW_COPY_AND_ASSIGN(Client); | 260 DISALLOW_COPY_AND_ASSIGN(Client); |
| 255 }; | 261 }; |
| 256 | 262 |
| 257 typedef std::map<int, Client*> ClientMap; | 263 typedef std::map<int, Client*> ClientMap; |
| 258 | 264 |
| 259 ClientMap clients_; | 265 ClientMap clients_; |
| 260 STLValueDeleter<ClientMap> clients_deleter_; | 266 STLValueDeleter<ClientMap> clients_deleter_; |
| 261 | 267 |
| 268 // This is the current number of clients we know about that have |
| 269 // cards. When this number matches alsa_card_midi_count_, we know |
| 270 // we are in sync between ALSA and udev. Until then, we cannot generate |
| 271 // MIDIConnectionEvents to web clients. |
| 272 int card_client_count_; |
| 273 |
| 262 DISALLOW_COPY_AND_ASSIGN(AlsaSeqState); | 274 DISALLOW_COPY_AND_ASSIGN(AlsaSeqState); |
| 263 }; | 275 }; |
| 264 | 276 |
| 277 class AlsaCard { |
| 278 public: |
| 279 AlsaCard(udev_device* dev, |
| 280 const std::string& alsa_name, |
| 281 const std::string& alsa_longname, |
| 282 const std::string& alsa_driver, |
| 283 int midi_device_count); |
| 284 ~AlsaCard(); |
| 285 const std::string alsa_name() const { return alsa_name_; } |
| 286 const std::string alsa_longname() const { return alsa_longname_; } |
| 287 const std::string manufacturer() const { return manufacturer_; } |
| 288 const std::string alsa_driver() const { return alsa_driver_; } |
| 289 int midi_device_count() const { return midi_device_count_; } |
| 290 // Returns hardware path. |
| 291 const std::string path() const; |
| 292 // Returns the id we can use to try to match hardware across different |
| 293 // paths. |
| 294 const std::string id() const; |
| 295 |
| 296 private: |
| 297 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer); |
| 298 |
| 299 // Extracts the manufacturer using heuristics and a variety of sources. |
| 300 static std::string ExtractManufacturerString( |
| 301 const std::string& udev_id_vendor, |
| 302 const std::string& udev_id_vendor_id, |
| 303 const std::string& udev_id_vendor_from_database, |
| 304 const std::string& alsa_name, |
| 305 const std::string& alsa_longname); |
| 306 |
| 307 std::string alsa_name_; |
| 308 std::string alsa_longname_; |
| 309 std::string manufacturer_; |
| 310 std::string alsa_driver_; |
| 311 std::string path_; |
| 312 std::string bus_; |
| 313 std::string serial_; |
| 314 std::string vendor_id_; |
| 315 std::string model_id_; |
| 316 std::string usb_interface_num_; |
| 317 int midi_device_count_; |
| 318 |
| 319 DISALLOW_COPY_AND_ASSIGN(AlsaCard); |
| 320 }; |
| 321 |
| 265 typedef base::hash_map<int, uint32> SourceMap; | 322 typedef base::hash_map<int, uint32> SourceMap; |
| 266 typedef base::hash_map<uint32, int> OutPortMap; | 323 typedef base::hash_map<uint32, int> OutPortMap; |
| 267 | 324 |
| 268 // Extracts the manufacturer using heuristics and a variety of sources. | |
| 269 static std::string ExtractManufacturerString( | |
| 270 const std::string& udev_id_vendor, | |
| 271 const std::string& udev_id_vendor_id, | |
| 272 const std::string& udev_id_vendor_from_database, | |
| 273 const std::string& alsa_name, | |
| 274 const std::string& alsa_longname); | |
| 275 | |
| 276 // An internal callback that runs on MidiSendThread. | 325 // An internal callback that runs on MidiSendThread. |
| 277 void SendMidiData(uint32 port_index, const std::vector<uint8>& data); | 326 void SendMidiData(uint32 port_index, const std::vector<uint8>& data); |
| 278 | 327 |
| 279 void ScheduleEventLoop(); | 328 void ScheduleEventLoop(); |
| 280 void EventLoop(); | 329 void EventLoop(); |
| 281 void ProcessSingleEvent(snd_seq_event_t* event, double timestamp); | 330 void ProcessSingleEvent(snd_seq_event_t* event, double timestamp); |
| 282 void ProcessClientStartEvent(int client_id); | 331 void ProcessClientStartEvent(int client_id); |
| 283 void ProcessPortStartEvent(const snd_seq_addr_t& addr); | 332 void ProcessPortStartEvent(const snd_seq_addr_t& addr); |
| 284 void ProcessClientExitEvent(const snd_seq_addr_t& addr); | 333 void ProcessClientExitEvent(const snd_seq_addr_t& addr); |
| 285 void ProcessPortExitEvent(const snd_seq_addr_t& addr); | 334 void ProcessPortExitEvent(const snd_seq_addr_t& addr); |
| 286 void ProcessUdevEvent(udev_device* dev); | 335 void ProcessUdevEvent(udev_device* dev); |
| 336 void AddCard(udev_device* dev); |
| 337 void RemoveCard(int number); |
| 287 | 338 |
| 288 // Updates port_state_ and Web MIDI state from alsa_seq_state_. | 339 // Updates port_state_ and Web MIDI state from alsa_seq_state_. |
| 289 void UpdatePortStateAndGenerateEvents(); | 340 void UpdatePortStateAndGenerateEvents(); |
| 290 | 341 |
| 291 // Enumerates ports. Call once after subscribing to the announce port. | 342 // Enumerates ports. Call once after subscribing to the announce port. |
| 292 void EnumerateAlsaPorts(); | 343 void EnumerateAlsaPorts(); |
| 293 // Enumerates udev cards. Call once after initializing the udev monitor. | 344 // Enumerates udev cards. Call once after initializing the udev monitor. |
| 294 bool EnumerateUdevCards(); | 345 bool EnumerateUdevCards(); |
| 295 // Returns true if successful. | 346 // Returns true if successful. |
| 296 bool CreateAlsaOutputPort(uint32 port_index, int client_id, int port_id); | 347 bool CreateAlsaOutputPort(uint32 port_index, int client_id, int port_id); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 308 int out_client_id_; | 359 int out_client_id_; |
| 309 | 360 |
| 310 // One input port, many output ports. | 361 // One input port, many output ports. |
| 311 int in_port_id_; | 362 int in_port_id_; |
| 312 OutPortMap out_ports_; // guarded by out_ports_lock_ | 363 OutPortMap out_ports_; // guarded by out_ports_lock_ |
| 313 base::Lock out_ports_lock_; // guards out_ports_ | 364 base::Lock out_ports_lock_; // guards out_ports_ |
| 314 | 365 |
| 315 // Mapping from ALSA client:port to our index. | 366 // Mapping from ALSA client:port to our index. |
| 316 SourceMap source_map_; | 367 SourceMap source_map_; |
| 317 | 368 |
| 369 // Mapping from card to devices. |
| 370 AlsaCardMap alsa_cards_; |
| 371 STLValueDeleter<AlsaCardMap> alsa_cards_deleter_; |
| 372 |
| 373 // This is the current count of midi devices across all cards we know |
| 374 // about. When this number matches card_client_count_ in AlsaSeqState, |
| 375 // we are safe to generate MIDIConnectionEvents. Otherwise we need to |
| 376 // wait for our information from ALSA and udev to get back in sync. |
| 377 int alsa_card_midi_count_; |
| 378 |
| 318 // ALSA event -> MIDI coder. | 379 // ALSA event -> MIDI coder. |
| 319 snd_midi_event_t* decoder_; | 380 snd_midi_event_t* decoder_; |
| 320 | 381 |
| 321 // udev, for querying hardware devices. | 382 // udev, for querying hardware devices. |
| 322 device::ScopedUdevPtr udev_; | 383 device::ScopedUdevPtr udev_; |
| 323 device::ScopedUdevMonitorPtr udev_monitor_; | 384 device::ScopedUdevMonitorPtr udev_monitor_; |
| 324 | 385 |
| 325 base::Thread send_thread_; | 386 base::Thread send_thread_; |
| 326 base::Thread event_thread_; | 387 base::Thread event_thread_; |
| 327 | 388 |
| 328 bool event_thread_shutdown_; // guarded by shutdown_lock_ | 389 bool event_thread_shutdown_; // guarded by shutdown_lock_ |
| 329 base::Lock shutdown_lock_; // guards event_thread_shutdown_ | 390 base::Lock shutdown_lock_; // guards event_thread_shutdown_ |
| 330 | 391 |
| 331 DISALLOW_COPY_AND_ASSIGN(MidiManagerAlsa); | 392 DISALLOW_COPY_AND_ASSIGN(MidiManagerAlsa); |
| 332 }; | 393 }; |
| 333 | 394 |
| 334 } // namespace midi | 395 } // namespace midi |
| 335 } // namespace media | 396 } // namespace media |
| 336 | 397 |
| 337 #endif // MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ | 398 #endif // MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ |
| OLD | NEW |