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

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

Issue 660573007: Open HID connections asynchronously. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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') | device/hid/hid_service_mac.h » ('j') | 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 <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file.h" 10 #include "base/files/file.h"
(...skipping 20 matching lines...) Expand all
31 namespace device { 31 namespace device {
32 32
33 namespace { 33 namespace {
34 34
35 const char kHidrawSubsystem[] = "hidraw"; 35 const char kHidrawSubsystem[] = "hidraw";
36 const char kHIDID[] = "HID_ID"; 36 const char kHIDID[] = "HID_ID";
37 const char kHIDName[] = "HID_NAME"; 37 const char kHIDName[] = "HID_NAME";
38 const char kHIDUnique[] = "HID_UNIQ"; 38 const char kHIDUnique[] = "HID_UNIQ";
39 const char kSysfsReportDescriptorKey[] = "report_descriptor"; 39 const char kSysfsReportDescriptorKey[] = "report_descriptor";
40 40
41 #if defined(OS_CHROMEOS)
42 void OnRequestAccessComplete(
43 scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
44 const base::Callback<void(bool success)>& callback,
45 bool success) {
46 reply_task_runner->PostTask(FROM_HERE, base::Bind(callback, success));
47 }
48
49 void RequestAccess(
50 const std::string& device_node,
51 scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
52 const base::Callback<void(bool success)>& callback) {
53 bool success = false;
54
55 if (base::SysInfo::IsRunningOnChromeOS()) {
56 chromeos::PermissionBrokerClient* client =
57 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
58 DCHECK(client) << "Could not get permission broker client.";
59 if (client) {
60 client->RequestPathAccess(
61 device_node,
62 -1,
63 base::Bind(OnRequestAccessComplete, reply_task_runner, callback));
64 return;
65 }
66 } else {
67 // Not really running on Chrome OS, declare success.
68 success = true;
69 }
70
71 reply_task_runner->PostTask(FROM_HERE, base::Bind(callback, success));
72 }
73 #endif
74
41 } // namespace 75 } // namespace
42 76
43 HidServiceLinux::HidServiceLinux( 77 HidServiceLinux::HidServiceLinux(
44 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) 78 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
45 : ui_task_runner_(ui_task_runner), 79 : ui_task_runner_(ui_task_runner),
46 weak_factory_(this) { 80 weak_factory_(this) {
47 base::ThreadRestrictions::AssertIOAllowed(); 81 base::ThreadRestrictions::AssertIOAllowed();
48 task_runner_ = base::ThreadTaskRunnerHandle::Get(); 82 task_runner_ = base::ThreadTaskRunnerHandle::Get();
49 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); 83 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance();
50 monitor->AddObserver(this); 84 monitor->AddObserver(this);
51 monitor->Enumerate( 85 monitor->Enumerate(
52 base::Bind(&HidServiceLinux::OnDeviceAdded, weak_factory_.GetWeakPtr())); 86 base::Bind(&HidServiceLinux::OnDeviceAdded, weak_factory_.GetWeakPtr()));
53 } 87 }
54 88
55 #if defined(OS_CHROMEOS) 89 void HidServiceLinux::Connect(const HidDeviceId& device_id,
56 void HidServiceLinux::RequestAccess( 90 const ConnectCallback& callback) {
57 const HidDeviceId& device_id, 91 DCHECK(thread_checker_.CalledOnValidThread());
58 const base::Callback<void(bool success)>& callback) { 92
59 bool success = false;
60 ScopedUdevDevicePtr device = 93 ScopedUdevDevicePtr device =
61 DeviceMonitorLinux::GetInstance()->GetDeviceFromPath( 94 DeviceMonitorLinux::GetInstance()->GetDeviceFromPath(
62 device_id); 95 device_id);
63 96 if (!device) {
64 if (device) { 97 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
65 const char* dev_node = udev_device_get_devnode(device.get()); 98 return;
66
67 if (base::SysInfo::IsRunningOnChromeOS()) {
68 chromeos::PermissionBrokerClient* client =
69 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
70 DCHECK(client) << "Could not get permission broker client.";
71 if (client) {
72 ui_task_runner_->PostTask(
73 FROM_HERE,
74 base::Bind(&chromeos::PermissionBrokerClient::RequestPathAccess,
75 base::Unretained(client),
76 std::string(dev_node),
77 -1,
78 base::Bind(&HidServiceLinux::OnRequestAccessComplete,
79 weak_factory_.GetWeakPtr(),
80 callback)));
81 return;
82 }
83 } else {
84 // Not really running on Chrome OS, declare success.
85 success = true;
86 }
87 }
88 task_runner_->PostTask(FROM_HERE, base::Bind(callback, success));
89 }
90 #endif
91
92 scoped_refptr<HidConnection> HidServiceLinux::Connect(
93 const HidDeviceId& device_id) {
94 HidDeviceInfo device_info;
95 if (!GetDeviceInfo(device_id, &device_info))
96 return NULL;
97
98 ScopedUdevDevicePtr device =
99 DeviceMonitorLinux::GetInstance()->GetDeviceFromPath(
100 device_info.device_id);
101
102 if (device) {
103 const char* dev_node = udev_device_get_devnode(device.get());
104 if (dev_node) {
105 return new HidConnectionLinux(device_info, dev_node);
106 }
107 } 99 }
108 100
109 return NULL; 101 const char* device_node = udev_device_get_devnode(device.get());
102 if (!device_node) {
103 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
104 return;
105 }
106
107 base::Callback<void(bool success)> finish_connect =
108 base::Bind(&HidServiceLinux::FinishConnect,
109 weak_factory_.GetWeakPtr(),
110 device_id,
111 std::string(device_node),
112 callback);
113
114 #if defined(OS_CHROMEOS)
115 ui_task_runner_->PostTask(FROM_HERE,
116 base::Bind(RequestAccess,
117 std::string(device_node),
118 task_runner_,
119 finish_connect));
120 #else
121 // Use the task runner to preserve the asynchronous behavior of this call on
122 // non-Chrome OS platforms.
123 task_runner_->PostTask(FROM_HERE, base::Bind(finish_connect, true));
124 #endif
110 } 125 }
111 126
112 HidServiceLinux::~HidServiceLinux() { 127 HidServiceLinux::~HidServiceLinux() {
113 if (DeviceMonitorLinux::HasInstance()) 128 if (DeviceMonitorLinux::HasInstance())
114 DeviceMonitorLinux::GetInstance()->RemoveObserver(this); 129 DeviceMonitorLinux::GetInstance()->RemoveObserver(this);
115 } 130 }
116 131
117 void HidServiceLinux::OnDeviceAdded(udev_device* device) { 132 void HidServiceLinux::OnDeviceAdded(udev_device* device) {
118 if (!device) 133 if (!device)
119 return; 134 return;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 AddDevice(device_info); 203 AddDevice(device_info);
189 } 204 }
190 205
191 void HidServiceLinux::OnDeviceRemoved(udev_device* device) { 206 void HidServiceLinux::OnDeviceRemoved(udev_device* device) {
192 const char* device_path = udev_device_get_syspath(device);; 207 const char* device_path = udev_device_get_syspath(device);;
193 if (device_path) { 208 if (device_path) {
194 RemoveDevice(device_path); 209 RemoveDevice(device_path);
195 } 210 }
196 } 211 }
197 212
198 void HidServiceLinux::OnRequestAccessComplete( 213 void HidServiceLinux::FinishConnect(
199 const base::Callback<void(bool success)>& callback, 214 const HidDeviceId& device_id,
215 const std::string device_node,
216 const base::Callback<void(scoped_refptr<HidConnection>)>& callback,
200 bool success) { 217 bool success) {
201 task_runner_->PostTask(FROM_HERE, base::Bind(callback, success)); 218 DCHECK(thread_checker_.CalledOnValidThread());
219 if (!success) {
220 callback.Run(nullptr);
221 }
222
223 const auto& map_entry = devices().find(device_id);
224 if (map_entry == devices().end()) {
225 callback.Run(nullptr);
226 }
227
228 callback.Run(new HidConnectionLinux(map_entry->second, device_node));
202 } 229 }
203 230
204 } // namespace device 231 } // namespace device
OLDNEW
« no previous file with comments | « device/hid/hid_service_linux.h ('k') | device/hid/hid_service_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698