| 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 |