OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <memory> | |
12 | |
13 #include "webrtc/media/devices/deviceinfo.h" | |
14 | |
15 #include "webrtc/base/common.h" // for ASSERT | |
16 #include "webrtc/media/devices/libudevsymboltable.h" | |
17 | |
18 namespace cricket { | |
19 | |
20 class ScopedLibUdev { | |
21 public: | |
22 static ScopedLibUdev* Create() { | |
23 ScopedLibUdev* ret_val = new ScopedLibUdev(); | |
24 if (!ret_val->Init()) { | |
25 delete ret_val; | |
26 return NULL; | |
27 } | |
28 return ret_val; | |
29 } | |
30 ~ScopedLibUdev() { | |
31 libudev_.Unload(); | |
32 } | |
33 | |
34 LibUDevSymbolTable* instance() { return &libudev_; } | |
35 | |
36 private: | |
37 ScopedLibUdev() {} | |
38 | |
39 bool Init() { | |
40 return libudev_.Load() && | |
41 !IsWrongLibUDevAbiVersion(libudev_.GetDllHandle()); | |
42 } | |
43 | |
44 LibUDevSymbolTable libudev_; | |
45 }; | |
46 | |
47 class ScopedUdev { | |
48 public: | |
49 explicit ScopedUdev(LibUDevSymbolTable* libudev) : libudev_(libudev) { | |
50 udev_ = libudev_->udev_new()(); | |
51 } | |
52 ~ScopedUdev() { | |
53 if (udev_) libudev_->udev_unref()(udev_); | |
54 } | |
55 | |
56 udev* instance() { return udev_; } | |
57 | |
58 private: | |
59 LibUDevSymbolTable* libudev_; | |
60 udev* udev_; | |
61 }; | |
62 | |
63 class ScopedUdevEnumerate { | |
64 public: | |
65 ScopedUdevEnumerate(LibUDevSymbolTable* libudev, udev* udev) | |
66 : libudev_(libudev) { | |
67 enumerate_ = libudev_->udev_enumerate_new()(udev); | |
68 } | |
69 ~ScopedUdevEnumerate() { | |
70 if (enumerate_) libudev_->udev_enumerate_unref()(enumerate_); | |
71 } | |
72 | |
73 udev_enumerate* instance() { return enumerate_; } | |
74 | |
75 private: | |
76 LibUDevSymbolTable* libudev_; | |
77 udev_enumerate* enumerate_; | |
78 }; | |
79 | |
80 bool GetUsbProperty(const Device& device, const char* property_name, | |
81 std::string* property) { | |
82 std::unique_ptr<ScopedLibUdev> libudev_context(ScopedLibUdev::Create()); | |
83 if (!libudev_context) { | |
84 return false; | |
85 } | |
86 ScopedUdev udev_context(libudev_context->instance()); | |
87 if (!udev_context.instance()) { | |
88 return false; | |
89 } | |
90 ScopedUdevEnumerate enumerate_context(libudev_context->instance(), | |
91 udev_context.instance()); | |
92 if (!enumerate_context.instance()) { | |
93 return false; | |
94 } | |
95 libudev_context->instance()->udev_enumerate_add_match_subsystem()( | |
96 enumerate_context.instance(), "video4linux"); | |
97 libudev_context->instance()->udev_enumerate_scan_devices()( | |
98 enumerate_context.instance()); | |
99 udev_list_entry* devices = | |
100 libudev_context->instance()->udev_enumerate_get_list_entry()( | |
101 enumerate_context.instance()); | |
102 if (!devices) { | |
103 return false; | |
104 } | |
105 udev_list_entry* dev_list_entry = NULL; | |
106 const char* property_value = NULL; | |
107 // Macro that expands to a for-loop over the devices. | |
108 for (dev_list_entry = devices; dev_list_entry != NULL; | |
109 dev_list_entry = libudev_context->instance()-> | |
110 udev_list_entry_get_next()(dev_list_entry)) { | |
111 const char* path = libudev_context->instance()->udev_list_entry_get_name()( | |
112 dev_list_entry); | |
113 if (!path) continue; | |
114 udev_device* dev = | |
115 libudev_context->instance()->udev_device_new_from_syspath()( | |
116 udev_context.instance(), path); | |
117 if (!dev) continue; | |
118 const char* device_node = | |
119 libudev_context->instance()->udev_device_get_devnode()(dev); | |
120 if (!device_node || device.id.compare(device_node) != 0) { | |
121 continue; | |
122 } | |
123 dev = libudev_context->instance()-> | |
124 udev_device_get_parent_with_subsystem_devtype()( | |
125 dev, "usb", "usb_device"); | |
126 if (!dev) continue; | |
127 property_value = libudev_context->instance()-> | |
128 udev_device_get_sysattr_value()( | |
129 dev, property_name); | |
130 break; | |
131 } | |
132 if (!property_value) { | |
133 return false; | |
134 } | |
135 property->assign(property_value); | |
136 return true; | |
137 } | |
138 | |
139 bool GetUsbId(const Device& device, std::string* usb_id) { | |
140 std::string id_vendor; | |
141 std::string id_product; | |
142 if (!GetUsbProperty(device, "idVendor", &id_vendor)) { | |
143 return false; | |
144 } | |
145 if (!GetUsbProperty(device, "idProduct", &id_product)) { | |
146 return false; | |
147 } | |
148 usb_id->clear(); | |
149 usb_id->append(id_vendor); | |
150 usb_id->append(":"); | |
151 usb_id->append(id_product); | |
152 return true; | |
153 } | |
154 | |
155 bool GetUsbVersion(const Device& device, std::string* usb_version) { | |
156 return GetUsbProperty(device, "version", usb_version); | |
157 } | |
158 | |
159 } // namespace cricket | |
OLD | NEW |