Chromium Code Reviews| 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/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 17 matching lines...) Expand all Loading... | |
| 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::SingleThreadTaskRunner> task_runner, |
| 56 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) | 57 scoped_refptr<base::SequencedTaskRunner> file_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 file_task_runner(std::move(file_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::SingleThreadTaskRunner> task_runner; |
| 66 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner; | 67 scoped_refptr<base::SequencedTaskRunner> file_task_runner; |
|
robliao
2017/04/07 01:08:24
Rename to blocking_task_runner to harmonize with H
Reilly Grant (use Gerrit)
2017/04/07 22:10:49
Done.
| |
| 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::SingleThreadTaskRunner> 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 |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 base::Bind(&HidServiceLinux::OpenOnBlockingThread, | 251 base::Bind(&HidServiceLinux::OpenOnBlockingThread, |
| 251 base::Passed(¶ms))); | 252 base::Passed(¶ms))); |
| 252 #endif // defined(OS_CHROMEOS) | 253 #endif // defined(OS_CHROMEOS) |
| 253 } | 254 } |
| 254 | 255 |
| 255 #if defined(OS_CHROMEOS) | 256 #if defined(OS_CHROMEOS) |
| 256 | 257 |
| 257 // static | 258 // static |
| 258 void HidServiceLinux::OnPathOpenComplete(std::unique_ptr<ConnectParams> params, | 259 void HidServiceLinux::OnPathOpenComplete(std::unique_ptr<ConnectParams> params, |
| 259 base::ScopedFD fd) { | 260 base::ScopedFD fd) { |
| 260 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner = | 261 scoped_refptr<base::SequencedTaskRunner> file_task_runner = |
| 261 params->file_task_runner; | 262 params->file_task_runner; |
| 262 params->device_file = base::File(fd.release()); | 263 params->fd = std::move(fd); |
| 263 file_task_runner->PostTask(FROM_HERE, base::Bind(&HidServiceLinux::FinishOpen, | 264 file_task_runner->PostTask(FROM_HERE, base::Bind(&HidServiceLinux::FinishOpen, |
| 264 base::Passed(¶ms))); | 265 base::Passed(¶ms))); |
| 265 } | 266 } |
| 266 | 267 |
| 267 // static | 268 // static |
| 268 void HidServiceLinux::OnPathOpenError(const std::string& device_path, | 269 void HidServiceLinux::OnPathOpenError(const std::string& device_path, |
| 269 const ConnectCallback& callback, | 270 const ConnectCallback& callback, |
| 270 const std::string& error_name, | 271 const std::string& error_name, |
| 271 const std::string& error_message) { | 272 const std::string& error_message) { |
| 272 HID_LOG(EVENT) << "Permission broker failed to open '" << device_path | 273 HID_LOG(EVENT) << "Permission broker failed to open '" << device_path |
| 273 << "': " << error_name << ": " << error_message; | 274 << "': " << error_name << ": " << error_message; |
| 274 callback.Run(nullptr); | 275 callback.Run(nullptr); |
| 275 } | 276 } |
| 276 | 277 |
| 277 #else | 278 #else |
| 278 | 279 |
| 279 // static | 280 // static |
| 280 void HidServiceLinux::OpenOnBlockingThread( | 281 void HidServiceLinux::OpenOnBlockingThread( |
| 281 std::unique_ptr<ConnectParams> params) { | 282 std::unique_ptr<ConnectParams> params) { |
| 282 base::ThreadRestrictions::AssertIOAllowed(); | 283 base::ThreadRestrictions::AssertIOAllowed(); |
| 283 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; | 284 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; |
| 284 | 285 |
| 285 base::FilePath device_path(params->device_info->device_node()); | 286 base::FilePath device_path(params->device_info->device_node()); |
| 286 base::File& device_file = params->device_file; | 287 base::File device_file; |
| 287 int flags = | 288 int flags = |
| 288 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; | 289 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; |
| 289 device_file.Initialize(device_path, flags); | 290 device_file.Initialize(device_path, flags); |
| 290 if (!device_file.IsValid()) { | 291 if (!device_file.IsValid()) { |
| 291 base::File::Error file_error = device_file.error_details(); | 292 base::File::Error file_error = device_file.error_details(); |
| 292 | 293 |
| 293 if (file_error == base::File::FILE_ERROR_ACCESS_DENIED) { | 294 if (file_error == base::File::FILE_ERROR_ACCESS_DENIED) { |
| 294 HID_LOG(EVENT) | 295 HID_LOG(EVENT) |
| 295 << "Access denied opening device read-write, trying read-only."; | 296 << "Access denied opening device read-write, trying read-only."; |
| 296 flags = base::File::FLAG_OPEN | base::File::FLAG_READ; | 297 flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
| 297 device_file.Initialize(device_path, flags); | 298 device_file.Initialize(device_path, flags); |
| 298 } | 299 } |
| 299 } | 300 } |
| 300 if (!device_file.IsValid()) { | 301 if (!device_file.IsValid()) { |
| 301 HID_LOG(EVENT) << "Failed to open '" << params->device_info->device_node() | 302 HID_LOG(EVENT) << "Failed to open '" << params->device_info->device_node() |
| 302 << "': " | 303 << "': " |
| 303 << base::File::ErrorToString(device_file.error_details()); | 304 << base::File::ErrorToString(device_file.error_details()); |
| 304 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); | 305 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); |
| 305 return; | 306 return; |
| 306 } | 307 } |
| 307 | 308 params->fd.reset(device_file.TakePlatformFile()); |
| 308 FinishOpen(std::move(params)); | 309 FinishOpen(std::move(params)); |
| 309 } | 310 } |
| 310 | 311 |
| 311 #endif // defined(OS_CHROMEOS) | 312 #endif // defined(OS_CHROMEOS) |
| 312 | 313 |
| 313 // static | 314 // static |
| 314 void HidServiceLinux::FinishOpen(std::unique_ptr<ConnectParams> params) { | 315 void HidServiceLinux::FinishOpen(std::unique_ptr<ConnectParams> params) { |
| 315 base::ThreadRestrictions::AssertIOAllowed(); | 316 base::ThreadRestrictions::AssertIOAllowed(); |
| 316 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; | 317 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; |
| 317 | 318 |
| 318 if (!base::SetNonBlocking(params->device_file.GetPlatformFile())) { | 319 if (!base::SetNonBlocking(params->fd.get())) { |
| 319 HID_PLOG(ERROR) << "Failed to set the non-blocking flag on the device fd"; | 320 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)); | 321 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); |
| 321 return; | 322 return; |
| 322 } | 323 } |
| 323 | 324 |
| 324 task_runner->PostTask( | 325 task_runner->PostTask( |
| 325 FROM_HERE, | 326 FROM_HERE, |
| 326 base::Bind(&HidServiceLinux::CreateConnection, base::Passed(¶ms))); | 327 base::Bind(&HidServiceLinux::CreateConnection, base::Passed(¶ms))); |
| 327 } | 328 } |
| 328 | 329 |
| 329 // static | 330 // static |
| 330 void HidServiceLinux::CreateConnection(std::unique_ptr<ConnectParams> params) { | 331 void HidServiceLinux::CreateConnection(std::unique_ptr<ConnectParams> params) { |
| 331 DCHECK(params->device_file.IsValid()); | 332 DCHECK(params->fd.is_valid()); |
| 332 params->callback.Run(make_scoped_refptr(new HidConnectionLinux( | 333 params->callback.Run(make_scoped_refptr(new HidConnectionLinux( |
| 333 params->device_info, std::move(params->device_file), | 334 std::move(params->device_info), std::move(params->fd), |
| 334 params->file_task_runner))); | 335 std::move(params->file_task_runner)))); |
| 335 } | 336 } |
| 336 | 337 |
| 337 } // namespace device | 338 } // namespace device |
| OLD | NEW |