OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/hid/hid_service_linux.h" | 5 #include "device/hid/hid_service_linux.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <limits> | 10 #include <limits> |
11 #include <memory> | 11 #include <memory> |
12 #include <string> | 12 #include <string> |
13 #include <utility> | 13 #include <utility> |
14 | 14 |
15 #include "base/bind.h" | 15 #include "base/bind.h" |
16 #include "base/files/file.h" | 16 #include "base/files/file.h" |
17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
18 #include "base/files/file_util.h" | 18 #include "base/files/file_util.h" |
19 #include "base/location.h" | 19 #include "base/location.h" |
20 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "base/memory/ptr_util.h" |
21 #include "base/scoped_observer.h" | 22 #include "base/scoped_observer.h" |
22 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
23 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
24 #include "base/threading/thread_restrictions.h" | 25 #include "base/threading/thread_restrictions.h" |
25 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
26 #include "build/build_config.h" | 27 #include "build/build_config.h" |
27 #include "components/device_event_log/device_event_log.h" | 28 #include "components/device_event_log/device_event_log.h" |
28 #include "device/base/device_monitor_linux.h" | 29 #include "device/base/device_monitor_linux.h" |
29 #include "device/hid/hid_connection_linux.h" | 30 #include "device/hid/hid_connection_linux.h" |
30 #include "device/hid/hid_device_info_linux.h" | 31 #include "device/hid/hid_device_info_linux.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 ConnectCallback callback; | 64 ConnectCallback callback; |
64 scoped_refptr<base::SingleThreadTaskRunner> task_runner; | 65 scoped_refptr<base::SingleThreadTaskRunner> task_runner; |
65 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner; | 66 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner; |
66 base::File device_file; | 67 base::File device_file; |
67 }; | 68 }; |
68 | 69 |
69 class HidServiceLinux::FileThreadHelper : public DeviceMonitorLinux::Observer { | 70 class HidServiceLinux::FileThreadHelper : public DeviceMonitorLinux::Observer { |
70 public: | 71 public: |
71 FileThreadHelper(base::WeakPtr<HidServiceLinux> service, | 72 FileThreadHelper(base::WeakPtr<HidServiceLinux> service, |
72 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 73 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
73 : observer_(this), service_(service), task_runner_(task_runner) {} | 74 : observer_(this), service_(service), task_runner_(task_runner) { |
| 75 thread_checker_.DetachFromThread(); |
| 76 } |
74 | 77 |
75 ~FileThreadHelper() override { | 78 ~FileThreadHelper() override { |
76 DCHECK(thread_checker_.CalledOnValidThread()); | 79 DCHECK(thread_checker_.CalledOnValidThread()); |
77 } | 80 } |
78 | 81 |
79 static void Start(std::unique_ptr<FileThreadHelper> self) { | 82 void Start() { |
80 base::ThreadRestrictions::AssertIOAllowed(); | 83 base::ThreadRestrictions::AssertIOAllowed(); |
81 self->thread_checker_.DetachFromThread(); | 84 DCHECK(thread_checker_.CalledOnValidThread()); |
82 | 85 |
83 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); | 86 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); |
84 self->observer_.Add(monitor); | 87 observer_.Add(monitor); |
85 monitor->Enumerate(base::Bind(&FileThreadHelper::OnDeviceAdded, | 88 monitor->Enumerate( |
86 base::Unretained(self.get()))); | 89 base::Bind(&FileThreadHelper::OnDeviceAdded, base::Unretained(this))); |
87 self->task_runner_->PostTask( | 90 task_runner_->PostTask( |
88 FROM_HERE, | 91 FROM_HERE, |
89 base::Bind(&HidServiceLinux::FirstEnumerationComplete, self->service_)); | 92 base::Bind(&HidServiceLinux::FirstEnumerationComplete, service_)); |
90 | |
91 // |self| is now owned by the current message loop. | |
92 ignore_result(self.release()); | |
93 } | 93 } |
94 | 94 |
95 private: | 95 private: |
96 // DeviceMonitorLinux::Observer: | 96 // DeviceMonitorLinux::Observer: |
97 void OnDeviceAdded(udev_device* device) override { | 97 void OnDeviceAdded(udev_device* device) override { |
98 DCHECK(thread_checker_.CalledOnValidThread()); | 98 DCHECK(thread_checker_.CalledOnValidThread()); |
99 const char* device_path = udev_device_get_syspath(device); | 99 const char* device_path = udev_device_get_syspath(device); |
100 if (!device_path) { | 100 if (!device_path) { |
101 return; | 101 return; |
102 } | 102 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 void OnDeviceRemoved(udev_device* device) override { | 180 void OnDeviceRemoved(udev_device* device) override { |
181 DCHECK(thread_checker_.CalledOnValidThread()); | 181 DCHECK(thread_checker_.CalledOnValidThread()); |
182 const char* device_path = udev_device_get_syspath(device); | 182 const char* device_path = udev_device_get_syspath(device); |
183 if (device_path) { | 183 if (device_path) { |
184 task_runner_->PostTask( | 184 task_runner_->PostTask( |
185 FROM_HERE, base::Bind(&HidServiceLinux::RemoveDevice, service_, | 185 FROM_HERE, base::Bind(&HidServiceLinux::RemoveDevice, service_, |
186 std::string(device_path))); | 186 std::string(device_path))); |
187 } | 187 } |
188 } | 188 } |
189 | 189 |
190 void WillDestroyMonitorMessageLoop() override { | |
191 DCHECK(thread_checker_.CalledOnValidThread()); | |
192 delete this; | |
193 } | |
194 | |
195 base::ThreadChecker thread_checker_; | 190 base::ThreadChecker thread_checker_; |
196 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_; | 191 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_; |
197 | 192 |
198 // This weak pointer is only valid when checked on this task runner. | 193 // This weak pointer is only valid when checked on this task runner. |
199 base::WeakPtr<HidServiceLinux> service_; | 194 base::WeakPtr<HidServiceLinux> service_; |
200 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 195 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
201 | 196 |
202 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); | 197 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); |
203 }; | 198 }; |
204 | 199 |
205 HidServiceLinux::HidServiceLinux( | 200 HidServiceLinux::HidServiceLinux( |
206 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) | 201 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) |
207 : file_task_runner_(file_task_runner), weak_factory_(this) { | 202 : file_task_runner_(std::move(file_task_runner)), weak_factory_(this) { |
208 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 203 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
209 std::unique_ptr<FileThreadHelper> helper( | 204 helper_ = base::MakeUnique<FileThreadHelper>(weak_factory_.GetWeakPtr(), |
210 new FileThreadHelper(weak_factory_.GetWeakPtr(), task_runner_)); | 205 task_runner_); |
211 helper_ = helper.get(); | |
212 file_task_runner_->PostTask( | 206 file_task_runner_->PostTask( |
213 FROM_HERE, base::Bind(&FileThreadHelper::Start, base::Passed(&helper))); | 207 FROM_HERE, |
| 208 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get()))); |
214 } | 209 } |
215 | 210 |
216 HidServiceLinux::~HidServiceLinux() { | 211 HidServiceLinux::~HidServiceLinux() { |
217 file_task_runner_->DeleteSoon(FROM_HERE, helper_); | 212 DCHECK(!helper_); |
| 213 } |
| 214 |
| 215 void HidServiceLinux::Shutdown() { |
| 216 const bool did_post_task = |
| 217 file_task_runner_->DeleteSoon(FROM_HERE, helper_.release()); |
| 218 DCHECK(did_post_task); |
| 219 HidService::Shutdown(); |
218 } | 220 } |
219 | 221 |
220 void HidServiceLinux::Connect(const HidDeviceId& device_id, | 222 void HidServiceLinux::Connect(const HidDeviceId& device_id, |
221 const ConnectCallback& callback) { | 223 const ConnectCallback& callback) { |
222 DCHECK(thread_checker_.CalledOnValidThread()); | 224 DCHECK(thread_checker_.CalledOnValidThread()); |
223 | 225 |
224 const auto& map_entry = devices().find(device_id); | 226 const auto& map_entry = devices().find(device_id); |
225 if (map_entry == devices().end()) { | 227 if (map_entry == devices().end()) { |
226 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 228 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); |
227 return; | 229 return; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 328 |
327 // static | 329 // static |
328 void HidServiceLinux::CreateConnection(std::unique_ptr<ConnectParams> params) { | 330 void HidServiceLinux::CreateConnection(std::unique_ptr<ConnectParams> params) { |
329 DCHECK(params->device_file.IsValid()); | 331 DCHECK(params->device_file.IsValid()); |
330 params->callback.Run(make_scoped_refptr(new HidConnectionLinux( | 332 params->callback.Run(make_scoped_refptr(new HidConnectionLinux( |
331 params->device_info, std::move(params->device_file), | 333 params->device_info, std::move(params->device_file), |
332 params->file_task_runner))); | 334 params->file_task_runner))); |
333 } | 335 } |
334 | 336 |
335 } // namespace device | 337 } // namespace device |
OLD | NEW |