| 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 #include "media/midi/midi_manager_alsa.h" | 5 #include "media/midi/midi_manager_alsa.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <poll.h> | 8 #include <poll.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <stdlib.h> | 10 #include <stdlib.h> |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 base::AutoLock lock(lazy_init_member_lock_); | 174 base::AutoLock lock(lazy_init_member_lock_); |
| 175 | 175 |
| 176 initialization_thread_checker_.reset(new base::ThreadChecker()); | 176 initialization_thread_checker_.reset(new base::ThreadChecker()); |
| 177 | 177 |
| 178 // Create client handles. | 178 // Create client handles. |
| 179 snd_seq_t* tmp_seq = nullptr; | 179 snd_seq_t* tmp_seq = nullptr; |
| 180 int err = | 180 int err = |
| 181 snd_seq_open(&tmp_seq, kAlsaHw, SND_SEQ_OPEN_INPUT, SND_SEQ_NONBLOCK); | 181 snd_seq_open(&tmp_seq, kAlsaHw, SND_SEQ_OPEN_INPUT, SND_SEQ_NONBLOCK); |
| 182 if (err != 0) { | 182 if (err != 0) { |
| 183 VLOG(1) << "snd_seq_open fails: " << snd_strerror(err); | 183 VLOG(1) << "snd_seq_open fails: " << snd_strerror(err); |
| 184 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 184 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 185 } | 185 } |
| 186 ScopedSndSeqPtr in_client(tmp_seq); | 186 ScopedSndSeqPtr in_client(tmp_seq); |
| 187 tmp_seq = nullptr; | 187 tmp_seq = nullptr; |
| 188 in_client_id_ = snd_seq_client_id(in_client.get()); | 188 in_client_id_ = snd_seq_client_id(in_client.get()); |
| 189 | 189 |
| 190 err = snd_seq_open(&tmp_seq, kAlsaHw, SND_SEQ_OPEN_OUTPUT, 0); | 190 err = snd_seq_open(&tmp_seq, kAlsaHw, SND_SEQ_OPEN_OUTPUT, 0); |
| 191 if (err != 0) { | 191 if (err != 0) { |
| 192 VLOG(1) << "snd_seq_open fails: " << snd_strerror(err); | 192 VLOG(1) << "snd_seq_open fails: " << snd_strerror(err); |
| 193 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 193 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 194 } | 194 } |
| 195 ScopedSndSeqPtr out_client(tmp_seq); | 195 ScopedSndSeqPtr out_client(tmp_seq); |
| 196 tmp_seq = nullptr; | 196 tmp_seq = nullptr; |
| 197 out_client_id_ = snd_seq_client_id(out_client.get()); | 197 out_client_id_ = snd_seq_client_id(out_client.get()); |
| 198 | 198 |
| 199 // Name the clients. | 199 // Name the clients. |
| 200 err = snd_seq_set_client_name(in_client.get(), "Chrome (input)"); | 200 err = snd_seq_set_client_name(in_client.get(), "Chrome (input)"); |
| 201 if (err != 0) { | 201 if (err != 0) { |
| 202 VLOG(1) << "snd_seq_set_client_name fails: " << snd_strerror(err); | 202 VLOG(1) << "snd_seq_set_client_name fails: " << snd_strerror(err); |
| 203 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 203 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 204 } | 204 } |
| 205 err = snd_seq_set_client_name(out_client.get(), "Chrome (output)"); | 205 err = snd_seq_set_client_name(out_client.get(), "Chrome (output)"); |
| 206 if (err != 0) { | 206 if (err != 0) { |
| 207 VLOG(1) << "snd_seq_set_client_name fails: " << snd_strerror(err); | 207 VLOG(1) << "snd_seq_set_client_name fails: " << snd_strerror(err); |
| 208 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 208 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 209 } | 209 } |
| 210 | 210 |
| 211 // Create input port. | 211 // Create input port. |
| 212 in_port_id_ = snd_seq_create_simple_port( | 212 in_port_id_ = snd_seq_create_simple_port( |
| 213 in_client.get(), NULL, kCreateInputPortCaps, kCreatePortType); | 213 in_client.get(), NULL, kCreateInputPortCaps, kCreatePortType); |
| 214 if (in_port_id_ < 0) { | 214 if (in_port_id_ < 0) { |
| 215 VLOG(1) << "snd_seq_create_simple_port fails: " | 215 VLOG(1) << "snd_seq_create_simple_port fails: " |
| 216 << snd_strerror(in_port_id_); | 216 << snd_strerror(in_port_id_); |
| 217 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 217 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 218 } | 218 } |
| 219 | 219 |
| 220 // Subscribe to the announce port. | 220 // Subscribe to the announce port. |
| 221 snd_seq_port_subscribe_t* subs; | 221 snd_seq_port_subscribe_t* subs; |
| 222 snd_seq_port_subscribe_alloca(&subs); | 222 snd_seq_port_subscribe_alloca(&subs); |
| 223 snd_seq_addr_t announce_sender; | 223 snd_seq_addr_t announce_sender; |
| 224 snd_seq_addr_t announce_dest; | 224 snd_seq_addr_t announce_dest; |
| 225 announce_sender.client = SND_SEQ_CLIENT_SYSTEM; | 225 announce_sender.client = SND_SEQ_CLIENT_SYSTEM; |
| 226 announce_sender.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE; | 226 announce_sender.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE; |
| 227 announce_dest.client = in_client_id_; | 227 announce_dest.client = in_client_id_; |
| 228 announce_dest.port = in_port_id_; | 228 announce_dest.port = in_port_id_; |
| 229 snd_seq_port_subscribe_set_sender(subs, &announce_sender); | 229 snd_seq_port_subscribe_set_sender(subs, &announce_sender); |
| 230 snd_seq_port_subscribe_set_dest(subs, &announce_dest); | 230 snd_seq_port_subscribe_set_dest(subs, &announce_dest); |
| 231 err = snd_seq_subscribe_port(in_client.get(), subs); | 231 err = snd_seq_subscribe_port(in_client.get(), subs); |
| 232 if (err != 0) { | 232 if (err != 0) { |
| 233 VLOG(1) << "snd_seq_subscribe_port on the announce port fails: " | 233 VLOG(1) << "snd_seq_subscribe_port on the announce port fails: " |
| 234 << snd_strerror(err); | 234 << snd_strerror(err); |
| 235 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 235 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 236 } | 236 } |
| 237 | 237 |
| 238 // Initialize decoder. | 238 // Initialize decoder. |
| 239 snd_midi_event_t* tmp_decoder = nullptr; | 239 snd_midi_event_t* tmp_decoder = nullptr; |
| 240 snd_midi_event_new(0, &tmp_decoder); | 240 snd_midi_event_new(0, &tmp_decoder); |
| 241 ScopedSndMidiEventPtr decoder(tmp_decoder); | 241 ScopedSndMidiEventPtr decoder(tmp_decoder); |
| 242 tmp_decoder = nullptr; | 242 tmp_decoder = nullptr; |
| 243 snd_midi_event_no_status(decoder.get(), 1); | 243 snd_midi_event_no_status(decoder.get(), 1); |
| 244 | 244 |
| 245 // Initialize udev and monitor. | 245 // Initialize udev and monitor. |
| 246 device::ScopedUdevPtr udev(device::udev_new()); | 246 device::ScopedUdevPtr udev(device::udev_new()); |
| 247 device::ScopedUdevMonitorPtr udev_monitor( | 247 device::ScopedUdevMonitorPtr udev_monitor( |
| 248 device::udev_monitor_new_from_netlink(udev.get(), kUdev)); | 248 device::udev_monitor_new_from_netlink(udev.get(), kUdev)); |
| 249 if (!udev_monitor.get()) { | 249 if (!udev_monitor.get()) { |
| 250 VLOG(1) << "udev_monitor_new_from_netlink fails"; | 250 VLOG(1) << "udev_monitor_new_from_netlink fails"; |
| 251 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 251 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 252 } | 252 } |
| 253 err = device::udev_monitor_filter_add_match_subsystem_devtype( | 253 err = device::udev_monitor_filter_add_match_subsystem_devtype( |
| 254 udev_monitor.get(), kUdevSubsystemSound, nullptr); | 254 udev_monitor.get(), kUdevSubsystemSound, nullptr); |
| 255 if (err != 0) { | 255 if (err != 0) { |
| 256 VLOG(1) << "udev_monitor_add_match_subsystem fails: " | 256 VLOG(1) << "udev_monitor_add_match_subsystem fails: " |
| 257 << base::safe_strerror(-err); | 257 << base::safe_strerror(-err); |
| 258 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 258 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 259 } | 259 } |
| 260 err = device::udev_monitor_enable_receiving(udev_monitor.get()); | 260 err = device::udev_monitor_enable_receiving(udev_monitor.get()); |
| 261 if (err != 0) { | 261 if (err != 0) { |
| 262 VLOG(1) << "udev_monitor_enable_receiving fails: " | 262 VLOG(1) << "udev_monitor_enable_receiving fails: " |
| 263 << base::safe_strerror(-err); | 263 << base::safe_strerror(-err); |
| 264 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 264 return CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
| 265 } | 265 } |
| 266 | 266 |
| 267 // Success! Now, initialize members from the temporaries. Do not | 267 // Success! Now, initialize members from the temporaries. Do not |
| 268 // initialize these earlier, since they need to be destroyed by the | 268 // initialize these earlier, since they need to be destroyed by the |
| 269 // thread that calls Finalize(), not the destructor thread (and we | 269 // thread that calls Finalize(), not the destructor thread (and we |
| 270 // check this in the destructor). | 270 // check this in the destructor). |
| 271 in_client_.reset(in_client.release()); | 271 in_client_.reset(in_client.release()); |
| 272 out_client_.reset(out_client.release()); | 272 out_client_.reset(out_client.release()); |
| 273 decoder_.reset(decoder.release()); | 273 decoder_.reset(decoder.release()); |
| 274 udev_.reset(udev.release()); | 274 udev_.reset(udev.release()); |
| 275 udev_monitor_.reset(udev_monitor.release()); | 275 udev_monitor_.reset(udev_monitor.release()); |
| 276 | 276 |
| 277 // Generate hotplug events for existing ports. | 277 // Generate hotplug events for existing ports. |
| 278 // TODO(agoode): Check the return value for failure. | 278 // TODO(agoode): Check the return value for failure. |
| 279 EnumerateAlsaPorts(); | 279 EnumerateAlsaPorts(); |
| 280 | 280 |
| 281 // Generate hotplug events for existing udev devices. This must be done | 281 // Generate hotplug events for existing udev devices. This must be done |
| 282 // after udev_monitor_enable_receiving() is called. See the algorithm | 282 // after udev_monitor_enable_receiving() is called. See the algorithm |
| 283 // at http://www.signal11.us/oss/udev/. | 283 // at http://www.signal11.us/oss/udev/. |
| 284 EnumerateUdevCards(); | 284 EnumerateUdevCards(); |
| 285 | 285 |
| 286 // Start processing events. Don't do this before enumeration of both | 286 // Start processing events. Don't do this before enumeration of both |
| 287 // ALSA and udev. | 287 // ALSA and udev. |
| 288 event_thread_.Start(); | 288 event_thread_.Start(); |
| 289 event_thread_.task_runner()->PostTask( | 289 event_thread_.task_runner()->PostTask( |
| 290 FROM_HERE, | 290 FROM_HERE, |
| 291 base::Bind(&MidiManagerAlsa::ScheduleEventLoop, base::Unretained(this))); | 291 base::Bind(&MidiManagerAlsa::ScheduleEventLoop, base::Unretained(this))); |
| 292 send_thread_.Start(); | 292 send_thread_.Start(); |
| 293 | 293 |
| 294 CompleteInitialization(Result::OK); | 294 CompleteInitialization(mojom::Result::OK); |
| 295 } | 295 } |
| 296 | 296 |
| 297 void MidiManagerAlsa::Finalize() { | 297 void MidiManagerAlsa::Finalize() { |
| 298 base::AutoLock lock(lazy_init_member_lock_); | 298 base::AutoLock lock(lazy_init_member_lock_); |
| 299 DCHECK(initialization_thread_checker_->CalledOnValidThread()); | 299 DCHECK(initialization_thread_checker_->CalledOnValidThread()); |
| 300 | 300 |
| 301 // Tell the event thread it will soon be time to shut down. This gives | 301 // Tell the event thread it will soon be time to shut down. This gives |
| 302 // us assurance the thread will stop in case the SND_SEQ_EVENT_CLIENT_EXIT | 302 // us assurance the thread will stop in case the SND_SEQ_EVENT_CLIENT_EXIT |
| 303 // message is lost. | 303 // message is lost. |
| 304 { | 304 { |
| (...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 // Update our map. | 1396 // Update our map. |
| 1397 source_map_[AddrToInt(client_id, port_id)] = port_index; | 1397 source_map_[AddrToInt(client_id, port_id)] = port_index; |
| 1398 return true; | 1398 return true; |
| 1399 } | 1399 } |
| 1400 | 1400 |
| 1401 MidiManager* MidiManager::Create() { | 1401 MidiManager* MidiManager::Create() { |
| 1402 return new MidiManagerAlsa(); | 1402 return new MidiManagerAlsa(); |
| 1403 } | 1403 } |
| 1404 | 1404 |
| 1405 } // namespace midi | 1405 } // namespace midi |
| OLD | NEW |