| 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 |