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 <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 Loading... |
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 Loading... |
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 |
OLD | NEW |