| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "device/usb/usb_service_linux.h" | 5 #include "device/usb/usb_service_linux.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> |
| 10 |
| 9 #include "base/bind.h" | 11 #include "base/bind.h" |
| 10 #include "base/files/file.h" | 12 #include "base/files/file.h" |
| 11 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 12 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 13 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/logging.h" |
| 17 #include "base/memory/ptr_util.h" |
| 14 #include "base/memory/weak_ptr.h" | 18 #include "base/memory/weak_ptr.h" |
| 15 #include "base/scoped_observer.h" | 19 #include "base/scoped_observer.h" |
| 16 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
| 17 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
| 18 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/threading/thread_restrictions.h" | 24 #include "base/threading/thread_restrictions.h" |
| 21 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" |
| 22 #include "build/build_config.h" | 26 #include "build/build_config.h" |
| 23 #include "components/device_event_log/device_event_log.h" | 27 #include "components/device_event_log/device_event_log.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 } | 67 } |
| 64 | 68 |
| 65 } // namespace | 69 } // namespace |
| 66 | 70 |
| 67 class UsbServiceLinux::FileThreadHelper : public DeviceMonitorLinux::Observer { | 71 class UsbServiceLinux::FileThreadHelper : public DeviceMonitorLinux::Observer { |
| 68 public: | 72 public: |
| 69 FileThreadHelper(base::WeakPtr<UsbServiceLinux> service, | 73 FileThreadHelper(base::WeakPtr<UsbServiceLinux> service, |
| 70 scoped_refptr<base::SingleThreadTaskRunner> task_runner); | 74 scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| 71 ~FileThreadHelper() override; | 75 ~FileThreadHelper() override; |
| 72 | 76 |
| 73 static void Start(std::unique_ptr<FileThreadHelper> self); | 77 void Start(); |
| 74 | 78 |
| 75 private: | 79 private: |
| 76 // DeviceMonitorLinux::Observer: | 80 // DeviceMonitorLinux::Observer: |
| 77 void OnDeviceAdded(udev_device* udev_device) override; | 81 void OnDeviceAdded(udev_device* udev_device) override; |
| 78 void OnDeviceRemoved(udev_device* device) override; | 82 void OnDeviceRemoved(udev_device* device) override; |
| 79 void WillDestroyMonitorMessageLoop() override; | |
| 80 | 83 |
| 81 base::ThreadChecker thread_checker_; | 84 base::ThreadChecker thread_checker_; |
| 82 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_; | 85 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_; |
| 83 | 86 |
| 84 // |service_| can only be checked for validity on |task_runner_|'s thread. | 87 // |service_| can only be checked for validity on |task_runner_|'s thread. |
| 85 base::WeakPtr<UsbServiceLinux> service_; | 88 base::WeakPtr<UsbServiceLinux> service_; |
| 86 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 89 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 87 | 90 |
| 88 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); | 91 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); |
| 89 }; | 92 }; |
| 90 | 93 |
| 91 UsbServiceLinux::FileThreadHelper::FileThreadHelper( | 94 UsbServiceLinux::FileThreadHelper::FileThreadHelper( |
| 92 base::WeakPtr<UsbServiceLinux> service, | 95 base::WeakPtr<UsbServiceLinux> service, |
| 93 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 96 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| 94 : observer_(this), service_(service), task_runner_(task_runner) {} | 97 : observer_(this), service_(service), task_runner_(std::move(task_runner)) { |
| 98 thread_checker_.DetachFromThread(); |
| 99 } |
| 95 | 100 |
| 96 UsbServiceLinux::FileThreadHelper::~FileThreadHelper() { | 101 UsbServiceLinux::FileThreadHelper::~FileThreadHelper() { |
| 97 DCHECK(thread_checker_.CalledOnValidThread()); | 102 DCHECK(thread_checker_.CalledOnValidThread()); |
| 98 } | 103 } |
| 99 | 104 |
| 100 // static | 105 // static |
| 101 void UsbServiceLinux::FileThreadHelper::Start( | 106 void UsbServiceLinux::FileThreadHelper::Start() { |
| 102 std::unique_ptr<FileThreadHelper> self) { | |
| 103 base::ThreadRestrictions::AssertIOAllowed(); | 107 base::ThreadRestrictions::AssertIOAllowed(); |
| 104 self->thread_checker_.DetachFromThread(); | 108 DCHECK(thread_checker_.CalledOnValidThread()); |
| 105 | 109 |
| 106 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); | 110 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); |
| 107 self->observer_.Add(monitor); | 111 observer_.Add(monitor); |
| 108 monitor->Enumerate(base::Bind(&FileThreadHelper::OnDeviceAdded, | 112 monitor->Enumerate( |
| 109 base::Unretained(self.get()))); | 113 base::Bind(&FileThreadHelper::OnDeviceAdded, base::Unretained(this))); |
| 110 self->task_runner_->PostTask( | 114 task_runner_->PostTask(FROM_HERE, |
| 111 FROM_HERE, base::Bind(&UsbServiceLinux::HelperStarted, self->service_)); | 115 base::Bind(&UsbServiceLinux::HelperStarted, service_)); |
| 112 | |
| 113 // |self| is now owned by the current message loop. | |
| 114 ignore_result(self.release()); | |
| 115 } | 116 } |
| 116 | 117 |
| 117 void UsbServiceLinux::FileThreadHelper::OnDeviceAdded( | 118 void UsbServiceLinux::FileThreadHelper::OnDeviceAdded( |
| 118 udev_device* udev_device) { | 119 udev_device* udev_device) { |
| 119 const char* subsystem = udev_device_get_subsystem(udev_device); | 120 const char* subsystem = udev_device_get_subsystem(udev_device); |
| 120 if (!subsystem || strcmp(subsystem, "usb") != 0) | 121 if (!subsystem || strcmp(subsystem, "usb") != 0) |
| 121 return; | 122 return; |
| 122 | 123 |
| 123 const char* value = udev_device_get_devnode(udev_device); | 124 const char* value = udev_device_get_devnode(udev_device); |
| 124 if (!value) | 125 if (!value) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 void UsbServiceLinux::FileThreadHelper::OnDeviceRemoved(udev_device* device) { | 176 void UsbServiceLinux::FileThreadHelper::OnDeviceRemoved(udev_device* device) { |
| 176 DCHECK(thread_checker_.CalledOnValidThread()); | 177 DCHECK(thread_checker_.CalledOnValidThread()); |
| 177 const char* device_path = udev_device_get_devnode(device); | 178 const char* device_path = udev_device_get_devnode(device); |
| 178 if (device_path) { | 179 if (device_path) { |
| 179 task_runner_->PostTask( | 180 task_runner_->PostTask( |
| 180 FROM_HERE, base::Bind(&UsbServiceLinux::OnDeviceRemoved, service_, | 181 FROM_HERE, base::Bind(&UsbServiceLinux::OnDeviceRemoved, service_, |
| 181 std::string(device_path))); | 182 std::string(device_path))); |
| 182 } | 183 } |
| 183 } | 184 } |
| 184 | 185 |
| 185 void UsbServiceLinux::FileThreadHelper::WillDestroyMonitorMessageLoop() { | |
| 186 delete this; | |
| 187 } | |
| 188 | |
| 189 UsbServiceLinux::UsbServiceLinux( | 186 UsbServiceLinux::UsbServiceLinux( |
| 190 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 187 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_in) |
| 191 : UsbService(base::ThreadTaskRunnerHandle::Get(), blocking_task_runner), | 188 : UsbService(base::ThreadTaskRunnerHandle::Get(), |
| 189 std::move(blocking_task_runner_in)), |
| 192 weak_factory_(this) { | 190 weak_factory_(this) { |
| 193 std::unique_ptr<FileThreadHelper> helper( | 191 helper_ = base::MakeUnique<FileThreadHelper>(weak_factory_.GetWeakPtr(), |
| 194 new FileThreadHelper(weak_factory_.GetWeakPtr(), task_runner())); | 192 task_runner()); |
| 195 helper_ = helper.get(); | 193 blocking_task_runner()->PostTask( |
| 196 blocking_task_runner->PostTask( | 194 FROM_HERE, |
| 197 FROM_HERE, base::Bind(&FileThreadHelper::Start, base::Passed(&helper))); | 195 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get()))); |
| 198 } | 196 } |
| 199 | 197 |
| 200 UsbServiceLinux::~UsbServiceLinux() { | 198 UsbServiceLinux::~UsbServiceLinux() { |
| 201 blocking_task_runner()->DeleteSoon(FROM_HERE, helper_); | 199 DCHECK(!helper_); |
| 200 } |
| 201 |
| 202 void UsbServiceLinux::Shutdown() { |
| 203 const bool did_post_task = |
| 204 blocking_task_runner()->DeleteSoon(FROM_HERE, helper_.release()); |
| 205 DCHECK(did_post_task); |
| 206 UsbService::Shutdown(); |
| 202 } | 207 } |
| 203 | 208 |
| 204 void UsbServiceLinux::GetDevices(const GetDevicesCallback& callback) { | 209 void UsbServiceLinux::GetDevices(const GetDevicesCallback& callback) { |
| 205 DCHECK(CalledOnValidThread()); | 210 DCHECK(CalledOnValidThread()); |
| 206 if (enumeration_ready()) | 211 if (enumeration_ready()) |
| 207 UsbService::GetDevices(callback); | 212 UsbService::GetDevices(callback); |
| 208 else | 213 else |
| 209 enumeration_callbacks_.push_back(callback); | 214 enumeration_callbacks_.push_back(callback); |
| 210 } | 215 } |
| 211 | 216 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 result.reserve(devices().size()); | 317 result.reserve(devices().size()); |
| 313 for (const auto& map_entry : devices()) | 318 for (const auto& map_entry : devices()) |
| 314 result.push_back(map_entry.second); | 319 result.push_back(map_entry.second); |
| 315 for (const auto& callback : enumeration_callbacks_) | 320 for (const auto& callback : enumeration_callbacks_) |
| 316 callback.Run(result); | 321 callback.Run(result); |
| 317 enumeration_callbacks_.clear(); | 322 enumeration_callbacks_.clear(); |
| 318 } | 323 } |
| 319 } | 324 } |
| 320 | 325 |
| 321 } // namespace device | 326 } // namespace device |
| OLD | NEW |