OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // libudev is used for monitoring device changes. | |
6 | |
7 #include "media/capture/device_monitor_udev.h" | |
8 | |
9 #include <stddef.h> | |
10 | |
11 #include <string> | |
12 | |
13 #include "base/macros.h" | |
14 #include "base/system_monitor/system_monitor.h" | |
15 #include "device/udev_linux/udev.h" | |
16 #include "device/udev_linux/udev_linux.h" | |
17 | |
18 namespace { | |
19 | |
20 struct SubsystemMap { | |
21 base::SystemMonitor::DeviceType device_type; | |
22 const char* subsystem; | |
23 const char* devtype; | |
24 }; | |
25 | |
26 const char kAudioSubsystem[] = "sound"; | |
27 const char kVideoSubsystem[] = "video4linux"; | |
28 | |
29 // Add more subsystems here for monitoring. | |
30 const SubsystemMap kSubsystemMap[] = { | |
31 {base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE, kAudioSubsystem, NULL}, | |
32 {base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE, kVideoSubsystem, NULL}, | |
33 }; | |
34 | |
35 } // namespace | |
36 | |
37 namespace media { | |
38 | |
39 DeviceMonitorLinux::DeviceMonitorLinux( | |
40 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) | |
41 : io_task_runner_(io_task_runner) { | |
42 io_task_runner_->PostTask( | |
43 FROM_HERE, | |
44 base::Bind(&DeviceMonitorLinux::Initialize, base::Unretained(this))); | |
45 } | |
46 | |
47 DeviceMonitorLinux::~DeviceMonitorLinux() {} | |
48 | |
49 void DeviceMonitorLinux::Initialize() { | |
50 DCHECK(io_task_runner_->BelongsToCurrentThread()); | |
51 | |
52 // We want to be notified of IO message loop destruction to delete |udev_|. | |
53 base::MessageLoop::current()->AddDestructionObserver(this); | |
54 | |
55 std::vector<device::UdevLinux::UdevMonitorFilter> filters; | |
56 for (const SubsystemMap& entry : kSubsystemMap) { | |
57 filters.push_back( | |
58 device::UdevLinux::UdevMonitorFilter(entry.subsystem, entry.devtype)); | |
59 } | |
60 udev_.reset(new device::UdevLinux( | |
61 filters, base::Bind(&DeviceMonitorLinux::OnDevicesChanged, | |
62 base::Unretained(this)))); | |
63 } | |
64 | |
65 void DeviceMonitorLinux::WillDestroyCurrentMessageLoop() { | |
66 DCHECK(io_task_runner_->BelongsToCurrentThread()); | |
67 udev_.reset(); | |
68 } | |
69 | |
70 void DeviceMonitorLinux::OnDevicesChanged(udev_device* device) { | |
71 DCHECK(io_task_runner_->BelongsToCurrentThread()); | |
72 DCHECK(device); | |
73 | |
74 base::SystemMonitor::DeviceType device_type = | |
75 base::SystemMonitor::DEVTYPE_UNKNOWN; | |
76 const std::string subsystem(device::udev_device_get_subsystem(device)); | |
77 for (const SubsystemMap& entry : kSubsystemMap) { | |
78 if (subsystem == entry.subsystem) { | |
79 device_type = entry.device_type; | |
80 break; | |
81 } | |
82 } | |
83 DCHECK_NE(device_type, base::SystemMonitor::DEVTYPE_UNKNOWN); | |
84 | |
85 base::SystemMonitor::Get()->ProcessDevicesChanged(device_type); | |
86 } | |
87 | |
88 } // namespace media | |
OLD | NEW |