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