summaryrefslogtreecommitdiffstats
path: root/device/hid/hid_service_linux.cc
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2014-10-16 12:19:14 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-16 19:21:49 +0000
commit7f4f508547ac3058d7c47337313972ec1ac2fb1b (patch)
treedaf6ad84ae3eb0451ba21a203fe7d3ea8bb033ab /device/hid/hid_service_linux.cc
parentb92d87bee7689009c26be560634070a33508bcaf (diff)
downloadchromium_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.cc129
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