diff options
author | reillyg <reillyg@chromium.org> | 2014-10-16 12:19:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-16 19:21:49 +0000 |
commit | 7f4f508547ac3058d7c47337313972ec1ac2fb1b (patch) | |
tree | daf6ad84ae3eb0451ba21a203fe7d3ea8bb033ab /device/hid/hid_service_linux.cc | |
parent | b92d87bee7689009c26be560634070a33508bcaf (diff) | |
download | chromium_src-7f4f508547ac3058d7c47337313972ec1ac2fb1b.zip chromium_src-7f4f508547ac3058d7c47337313972ec1ac2fb1b.tar.gz chromium_src-7f4f508547ac3058d7c47337313972ec1ac2fb1b.tar.bz2 |
Open HID connections asynchronously.
By making HidService::Connect return its result asynchronously platform
specific details such as whether device nodes must be opened on a
different thread (due to blocking) or requesting access from the Chrome
OS permission broker can be abstracted away.
BUG=422540
Review URL: https://codereview.chromium.org/660573007
Cr-Commit-Position: refs/heads/master@{#299950}
Diffstat (limited to 'device/hid/hid_service_linux.cc')
-rw-r--r-- | device/hid/hid_service_linux.cc | 129 |
1 files changed, 78 insertions, 51 deletions
diff --git a/device/hid/hid_service_linux.cc b/device/hid/hid_service_linux.cc index 0cbf5cd..e5fcb52 100644 --- a/device/hid/hid_service_linux.cc +++ b/device/hid/hid_service_linux.cc @@ -38,6 +38,40 @@ const char kHIDName[] = "HID_NAME"; const char kHIDUnique[] = "HID_UNIQ"; const char kSysfsReportDescriptorKey[] = "report_descriptor"; +#if defined(OS_CHROMEOS) +void OnRequestAccessComplete( + scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner, + const base::Callback<void(bool success)>& callback, + bool success) { + reply_task_runner->PostTask(FROM_HERE, base::Bind(callback, success)); +} + +void RequestAccess( + const std::string& device_node, + scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner, + const base::Callback<void(bool success)>& callback) { + bool success = false; + + if (base::SysInfo::IsRunningOnChromeOS()) { + chromeos::PermissionBrokerClient* client = + chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient(); + DCHECK(client) << "Could not get permission broker client."; + if (client) { + client->RequestPathAccess( + device_node, + -1, + base::Bind(OnRequestAccessComplete, reply_task_runner, callback)); + return; + } + } else { + // Not really running on Chrome OS, declare success. + success = true; + } + + reply_task_runner->PostTask(FROM_HERE, base::Bind(callback, success)); +} +#endif + } // namespace HidServiceLinux::HidServiceLinux( @@ -52,61 +86,42 @@ HidServiceLinux::HidServiceLinux( base::Bind(&HidServiceLinux::OnDeviceAdded, weak_factory_.GetWeakPtr())); } -#if defined(OS_CHROMEOS) -void HidServiceLinux::RequestAccess( - const HidDeviceId& device_id, - const base::Callback<void(bool success)>& callback) { - bool success = false; +void HidServiceLinux::Connect(const HidDeviceId& device_id, + const ConnectCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + ScopedUdevDevicePtr device = DeviceMonitorLinux::GetInstance()->GetDeviceFromPath( device_id); - - if (device) { - const char* dev_node = udev_device_get_devnode(device.get()); - - if (base::SysInfo::IsRunningOnChromeOS()) { - chromeos::PermissionBrokerClient* client = - chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient(); - DCHECK(client) << "Could not get permission broker client."; - if (client) { - ui_task_runner_->PostTask( - FROM_HERE, - base::Bind(&chromeos::PermissionBrokerClient::RequestPathAccess, - base::Unretained(client), - std::string(dev_node), - -1, - base::Bind(&HidServiceLinux::OnRequestAccessComplete, - weak_factory_.GetWeakPtr(), - callback))); - return; - } - } else { - // Not really running on Chrome OS, declare success. - success = true; - } + if (!device) { + task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); + return; } - task_runner_->PostTask(FROM_HERE, base::Bind(callback, success)); -} -#endif - -scoped_refptr<HidConnection> HidServiceLinux::Connect( - const HidDeviceId& device_id) { - HidDeviceInfo device_info; - if (!GetDeviceInfo(device_id, &device_info)) - return NULL; - ScopedUdevDevicePtr device = - DeviceMonitorLinux::GetInstance()->GetDeviceFromPath( - device_info.device_id); - - if (device) { - const char* dev_node = udev_device_get_devnode(device.get()); - if (dev_node) { - return new HidConnectionLinux(device_info, dev_node); - } + const char* device_node = udev_device_get_devnode(device.get()); + if (!device_node) { + task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); + return; } - return NULL; + base::Callback<void(bool success)> finish_connect = + base::Bind(&HidServiceLinux::FinishConnect, + weak_factory_.GetWeakPtr(), + device_id, + std::string(device_node), + callback); + +#if defined(OS_CHROMEOS) + ui_task_runner_->PostTask(FROM_HERE, + base::Bind(RequestAccess, + std::string(device_node), + task_runner_, + finish_connect)); +#else + // Use the task runner to preserve the asynchronous behavior of this call on + // non-Chrome OS platforms. + task_runner_->PostTask(FROM_HERE, base::Bind(finish_connect, true)); +#endif } HidServiceLinux::~HidServiceLinux() { @@ -195,10 +210,22 @@ void HidServiceLinux::OnDeviceRemoved(udev_device* device) { } } -void HidServiceLinux::OnRequestAccessComplete( - const base::Callback<void(bool success)>& callback, +void HidServiceLinux::FinishConnect( + const HidDeviceId& device_id, + const std::string device_node, + const base::Callback<void(scoped_refptr<HidConnection>)>& callback, bool success) { - task_runner_->PostTask(FROM_HERE, base::Bind(callback, success)); + DCHECK(thread_checker_.CalledOnValidThread()); + if (!success) { + callback.Run(nullptr); + } + + const auto& map_entry = devices().find(device_id); + if (map_entry == devices().end()) { + callback.Run(nullptr); + } + + callback.Run(new HidConnectionLinux(map_entry->second, device_node)); } } // namespace device |