Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: device/hid/hid_service_linux.cc

Issue 2799743006: Remove MessageLoop destruction observer from hid_connection_linux.cc (Closed)
Patch Set: Last review comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/hid/hid_service_linux.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/files/scoped_file.h"
19 #include "base/location.h" 20 #include "base/location.h"
20 #include "base/macros.h" 21 #include "base/macros.h"
21 #include "base/memory/ptr_util.h" 22 #include "base/memory/ptr_util.h"
22 #include "base/scoped_observer.h" 23 #include "base/scoped_observer.h"
23 #include "base/strings/string_number_conversions.h" 24 #include "base/strings/string_number_conversions.h"
24 #include "base/strings/string_split.h" 25 #include "base/strings/string_split.h"
25 #include "base/threading/thread_restrictions.h" 26 #include "base/threading/thread_restrictions.h"
26 #include "base/threading/thread_task_runner_handle.h" 27 #include "base/threading/thread_task_runner_handle.h"
27 #include "build/build_config.h" 28 #include "build/build_config.h"
28 #include "components/device_event_log/device_event_log.h" 29 #include "components/device_event_log/device_event_log.h"
(...skipping 16 matching lines...) Expand all
45 const char kHIDID[] = "HID_ID"; 46 const char kHIDID[] = "HID_ID";
46 const char kHIDName[] = "HID_NAME"; 47 const char kHIDName[] = "HID_NAME";
47 const char kHIDUnique[] = "HID_UNIQ"; 48 const char kHIDUnique[] = "HID_UNIQ";
48 const char kSysfsReportDescriptorKey[] = "report_descriptor"; 49 const char kSysfsReportDescriptorKey[] = "report_descriptor";
49 50
50 } // namespace 51 } // namespace
51 52
52 struct HidServiceLinux::ConnectParams { 53 struct HidServiceLinux::ConnectParams {
53 ConnectParams(scoped_refptr<HidDeviceInfoLinux> device_info, 54 ConnectParams(scoped_refptr<HidDeviceInfoLinux> device_info,
54 const ConnectCallback& callback, 55 const ConnectCallback& callback,
55 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 56 scoped_refptr<base::SequencedTaskRunner> task_runner,
56 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) 57 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
57 : device_info(device_info), 58 : device_info(std::move(device_info)),
58 callback(callback), 59 callback(callback),
59 task_runner(task_runner), 60 task_runner(std::move(task_runner)),
60 file_task_runner(file_task_runner) {} 61 blocking_task_runner(std::move(blocking_task_runner)) {}
61 ~ConnectParams() {} 62 ~ConnectParams() {}
62 63
63 scoped_refptr<HidDeviceInfoLinux> device_info; 64 scoped_refptr<HidDeviceInfoLinux> device_info;
64 ConnectCallback callback; 65 ConnectCallback callback;
65 scoped_refptr<base::SingleThreadTaskRunner> task_runner; 66 scoped_refptr<base::SequencedTaskRunner> task_runner;
66 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner; 67 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner;
67 base::File device_file; 68 base::ScopedFD fd;
68 }; 69 };
69 70
70 class HidServiceLinux::FileThreadHelper : public DeviceMonitorLinux::Observer { 71 class HidServiceLinux::FileThreadHelper : public DeviceMonitorLinux::Observer {
71 public: 72 public:
72 FileThreadHelper(base::WeakPtr<HidServiceLinux> service, 73 FileThreadHelper(base::WeakPtr<HidServiceLinux> service,
73 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 74 scoped_refptr<base::SequencedTaskRunner> task_runner)
74 : observer_(this), service_(service), task_runner_(task_runner) { 75 : observer_(this), service_(service), task_runner_(task_runner) {
75 thread_checker_.DetachFromThread(); 76 thread_checker_.DetachFromThread();
76 } 77 }
77 78
78 ~FileThreadHelper() override { 79 ~FileThreadHelper() override {
79 DCHECK(thread_checker_.CalledOnValidThread()); 80 DCHECK(thread_checker_.CalledOnValidThread());
80 } 81 }
81 82
82 void Start() { 83 void Start() {
83 base::ThreadRestrictions::AssertIOAllowed(); 84 base::ThreadRestrictions::AssertIOAllowed();
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 FROM_HERE, base::Bind(&HidServiceLinux::RemoveDevice, service_, 186 FROM_HERE, base::Bind(&HidServiceLinux::RemoveDevice, service_,
186 std::string(device_path))); 187 std::string(device_path)));
187 } 188 }
188 } 189 }
189 190
190 base::ThreadChecker thread_checker_; 191 base::ThreadChecker thread_checker_;
191 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_; 192 ScopedObserver<DeviceMonitorLinux, DeviceMonitorLinux::Observer> observer_;
192 193
193 // This weak pointer is only valid when checked on this task runner. 194 // This weak pointer is only valid when checked on this task runner.
194 base::WeakPtr<HidServiceLinux> service_; 195 base::WeakPtr<HidServiceLinux> service_;
195 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 196 scoped_refptr<base::SequencedTaskRunner> task_runner_;
196 197
197 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); 198 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper);
198 }; 199 };
199 200
200 HidServiceLinux::HidServiceLinux( 201 HidServiceLinux::HidServiceLinux(
201 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) 202 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
202 : file_task_runner_(std::move(file_task_runner)), weak_factory_(this) { 203 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
203 task_runner_ = base::ThreadTaskRunnerHandle::Get(); 204 blocking_task_runner_(std::move(blocking_task_runner)),
205 weak_factory_(this) {
204 helper_ = base::MakeUnique<FileThreadHelper>(weak_factory_.GetWeakPtr(), 206 helper_ = base::MakeUnique<FileThreadHelper>(weak_factory_.GetWeakPtr(),
205 task_runner_); 207 task_runner_);
206 file_task_runner_->PostTask( 208 blocking_task_runner_->PostTask(
207 FROM_HERE, 209 FROM_HERE,
208 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get()))); 210 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get())));
209 } 211 }
210 212
211 HidServiceLinux::~HidServiceLinux() { 213 HidServiceLinux::~HidServiceLinux() {
212 DCHECK(!helper_); 214 DCHECK(!helper_);
213 } 215 }
214 216
215 void HidServiceLinux::Shutdown() { 217 void HidServiceLinux::Shutdown() {
216 const bool did_post_task = 218 const bool did_post_task =
217 file_task_runner_->DeleteSoon(FROM_HERE, helper_.release()); 219 blocking_task_runner_->DeleteSoon(FROM_HERE, helper_.release());
218 DCHECK(did_post_task); 220 DCHECK(did_post_task);
219 HidService::Shutdown(); 221 HidService::Shutdown();
220 } 222 }
221 223
222 void HidServiceLinux::Connect(const HidDeviceId& device_id, 224 void HidServiceLinux::Connect(const HidDeviceId& device_id,
223 const ConnectCallback& callback) { 225 const ConnectCallback& callback) {
224 DCHECK(thread_checker_.CalledOnValidThread()); 226 DCHECK(thread_checker_.CalledOnValidThread());
225 227
226 const auto& map_entry = devices().find(device_id); 228 const auto& map_entry = devices().find(device_id);
227 if (map_entry == devices().end()) { 229 if (map_entry == devices().end()) {
228 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 230 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
229 return; 231 return;
230 } 232 }
231 scoped_refptr<HidDeviceInfoLinux> device_info = 233 scoped_refptr<HidDeviceInfoLinux> device_info =
232 static_cast<HidDeviceInfoLinux*>(map_entry->second.get()); 234 static_cast<HidDeviceInfoLinux*>(map_entry->second.get());
233 235
234 std::unique_ptr<ConnectParams> params(new ConnectParams( 236 std::unique_ptr<ConnectParams> params(new ConnectParams(
235 device_info, callback, task_runner_, file_task_runner_)); 237 device_info, callback, task_runner_, blocking_task_runner_));
236 238
237 #if defined(OS_CHROMEOS) 239 #if defined(OS_CHROMEOS)
238 chromeos::PermissionBrokerClient* client = 240 chromeos::PermissionBrokerClient* client =
239 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient(); 241 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
240 DCHECK(client) << "Could not get permission broker client."; 242 DCHECK(client) << "Could not get permission broker client.";
241 chromeos::PermissionBrokerClient::ErrorCallback error_callback = 243 chromeos::PermissionBrokerClient::ErrorCallback error_callback =
242 base::Bind(&HidServiceLinux::OnPathOpenError, 244 base::Bind(&HidServiceLinux::OnPathOpenError,
243 params->device_info->device_node(), params->callback); 245 params->device_info->device_node(), params->callback);
244 client->OpenPath( 246 client->OpenPath(
245 device_info->device_node(), 247 device_info->device_node(),
246 base::Bind(&HidServiceLinux::OnPathOpenComplete, base::Passed(&params)), 248 base::Bind(&HidServiceLinux::OnPathOpenComplete, base::Passed(&params)),
247 error_callback); 249 error_callback);
248 #else 250 #else
249 file_task_runner_->PostTask(FROM_HERE, 251 blocking_task_runner_->PostTask(
250 base::Bind(&HidServiceLinux::OpenOnBlockingThread, 252 FROM_HERE, base::Bind(&HidServiceLinux::OpenOnBlockingThread,
251 base::Passed(&params))); 253 base::Passed(&params)));
252 #endif // defined(OS_CHROMEOS) 254 #endif // defined(OS_CHROMEOS)
253 } 255 }
254 256
255 #if defined(OS_CHROMEOS) 257 #if defined(OS_CHROMEOS)
256 258
257 // static 259 // static
258 void HidServiceLinux::OnPathOpenComplete(std::unique_ptr<ConnectParams> params, 260 void HidServiceLinux::OnPathOpenComplete(std::unique_ptr<ConnectParams> params,
259 base::ScopedFD fd) { 261 base::ScopedFD fd) {
260 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner = 262 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner =
261 params->file_task_runner; 263 params->blocking_task_runner;
262 params->device_file = base::File(fd.release()); 264 params->fd = std::move(fd);
263 file_task_runner->PostTask(FROM_HERE, base::Bind(&HidServiceLinux::FinishOpen, 265 blocking_task_runner->PostTask(
264 base::Passed(&params))); 266 FROM_HERE,
267 base::Bind(&HidServiceLinux::FinishOpen, base::Passed(&params)));
265 } 268 }
266 269
267 // static 270 // static
268 void HidServiceLinux::OnPathOpenError(const std::string& device_path, 271 void HidServiceLinux::OnPathOpenError(const std::string& device_path,
269 const ConnectCallback& callback, 272 const ConnectCallback& callback,
270 const std::string& error_name, 273 const std::string& error_name,
271 const std::string& error_message) { 274 const std::string& error_message) {
272 HID_LOG(EVENT) << "Permission broker failed to open '" << device_path 275 HID_LOG(EVENT) << "Permission broker failed to open '" << device_path
273 << "': " << error_name << ": " << error_message; 276 << "': " << error_name << ": " << error_message;
274 callback.Run(nullptr); 277 callback.Run(nullptr);
275 } 278 }
276 279
277 #else 280 #else
278 281
279 // static 282 // static
280 void HidServiceLinux::OpenOnBlockingThread( 283 void HidServiceLinux::OpenOnBlockingThread(
281 std::unique_ptr<ConnectParams> params) { 284 std::unique_ptr<ConnectParams> params) {
282 base::ThreadRestrictions::AssertIOAllowed(); 285 base::ThreadRestrictions::AssertIOAllowed();
283 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; 286 scoped_refptr<base::SequencedTaskRunner> task_runner = params->task_runner;
284 287
285 base::FilePath device_path(params->device_info->device_node()); 288 base::FilePath device_path(params->device_info->device_node());
286 base::File& device_file = params->device_file; 289 base::File device_file;
287 int flags = 290 int flags =
288 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; 291 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE;
289 device_file.Initialize(device_path, flags); 292 device_file.Initialize(device_path, flags);
290 if (!device_file.IsValid()) { 293 if (!device_file.IsValid()) {
291 base::File::Error file_error = device_file.error_details(); 294 base::File::Error file_error = device_file.error_details();
292 295
293 if (file_error == base::File::FILE_ERROR_ACCESS_DENIED) { 296 if (file_error == base::File::FILE_ERROR_ACCESS_DENIED) {
294 HID_LOG(EVENT) 297 HID_LOG(EVENT)
295 << "Access denied opening device read-write, trying read-only."; 298 << "Access denied opening device read-write, trying read-only.";
296 flags = base::File::FLAG_OPEN | base::File::FLAG_READ; 299 flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
297 device_file.Initialize(device_path, flags); 300 device_file.Initialize(device_path, flags);
298 } 301 }
299 } 302 }
300 if (!device_file.IsValid()) { 303 if (!device_file.IsValid()) {
301 HID_LOG(EVENT) << "Failed to open '" << params->device_info->device_node() 304 HID_LOG(EVENT) << "Failed to open '" << params->device_info->device_node()
302 << "': " 305 << "': "
303 << base::File::ErrorToString(device_file.error_details()); 306 << base::File::ErrorToString(device_file.error_details());
304 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); 307 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr));
305 return; 308 return;
306 } 309 }
307 310 params->fd.reset(device_file.TakePlatformFile());
308 FinishOpen(std::move(params)); 311 FinishOpen(std::move(params));
309 } 312 }
310 313
311 #endif // defined(OS_CHROMEOS) 314 #endif // defined(OS_CHROMEOS)
312 315
313 // static 316 // static
314 void HidServiceLinux::FinishOpen(std::unique_ptr<ConnectParams> params) { 317 void HidServiceLinux::FinishOpen(std::unique_ptr<ConnectParams> params) {
315 base::ThreadRestrictions::AssertIOAllowed(); 318 base::ThreadRestrictions::AssertIOAllowed();
316 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; 319 scoped_refptr<base::SequencedTaskRunner> task_runner = params->task_runner;
317 320
318 if (!base::SetNonBlocking(params->device_file.GetPlatformFile())) { 321 if (!base::SetNonBlocking(params->fd.get())) {
319 HID_PLOG(ERROR) << "Failed to set the non-blocking flag on the device fd"; 322 HID_PLOG(ERROR) << "Failed to set the non-blocking flag on the device fd";
320 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); 323 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr));
321 return; 324 return;
322 } 325 }
323 326
324 task_runner->PostTask( 327 task_runner->PostTask(
325 FROM_HERE, 328 FROM_HERE,
326 base::Bind(&HidServiceLinux::CreateConnection, base::Passed(&params))); 329 base::Bind(&HidServiceLinux::CreateConnection, base::Passed(&params)));
327 } 330 }
328 331
329 // static 332 // static
330 void HidServiceLinux::CreateConnection(std::unique_ptr<ConnectParams> params) { 333 void HidServiceLinux::CreateConnection(std::unique_ptr<ConnectParams> params) {
331 DCHECK(params->device_file.IsValid()); 334 DCHECK(params->fd.is_valid());
332 params->callback.Run(make_scoped_refptr(new HidConnectionLinux( 335 params->callback.Run(make_scoped_refptr(new HidConnectionLinux(
333 params->device_info, std::move(params->device_file), 336 std::move(params->device_info), std::move(params->fd),
334 params->file_task_runner))); 337 std::move(params->blocking_task_runner))));
335 } 338 }
336 339
337 } // namespace device 340 } // namespace device
OLDNEW
« no previous file with comments | « device/hid/hid_service_linux.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698