summaryrefslogtreecommitdiffstats
path: root/device/hid/hid_service_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'device/hid/hid_service_linux.cc')
-rw-r--r--device/hid/hid_service_linux.cc84
1 files changed, 62 insertions, 22 deletions
diff --git a/device/hid/hid_service_linux.cc b/device/hid/hid_service_linux.cc
index 4f1d8c7..25230e7 100644
--- a/device/hid/hid_service_linux.cc
+++ b/device/hid/hid_service_linux.cc
@@ -23,6 +23,12 @@
#include "device/hid/hid_report_descriptor.h"
#include "device/udev_linux/udev.h"
+#if defined(OS_CHROMEOS)
+#include "base/sys_info.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/permission_broker_client.h"
+#endif // defined(OS_CHROMEOS)
+
namespace device {
namespace {
@@ -34,11 +40,14 @@ const char kHIDUnique[] = "HID_UNIQ";
} // namespace
-HidServiceLinux::HidServiceLinux() {
+HidServiceLinux::HidServiceLinux(
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop)
+ : ui_message_loop_(ui_message_loop),
+ weak_factory_(this) {
DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance();
monitor->AddObserver(this);
monitor->Enumerate(
- base::Bind(&HidServiceLinux::OnDeviceAdded, base::Unretained(this)));
+ base::Bind(&HidServiceLinux::OnDeviceAdded, weak_factory_.GetWeakPtr()));
}
scoped_refptr<HidConnection> HidServiceLinux::Connect(
@@ -75,8 +84,8 @@ void HidServiceLinux::OnDeviceAdded(udev_device* device) {
if (!subsystem || strcmp(subsystem, kHidrawSubsystem) != 0)
return;
- HidDeviceInfo device_info;
- device_info.device_id = device_path;
+ scoped_ptr<HidDeviceInfo> device_info(new HidDeviceInfo);
+ device_info->device_id = device_path;
uint32_t int_property = 0;
const char* str_property = NULL;
@@ -97,27 +106,64 @@ void HidServiceLinux::OnDeviceAdded(udev_device* device) {
}
if (HexStringToUInt(base::StringPiece(parts[1]), &int_property)) {
- device_info.vendor_id = int_property;
+ device_info->vendor_id = int_property;
}
if (HexStringToUInt(base::StringPiece(parts[2]), &int_property)) {
- device_info.product_id = int_property;
+ device_info->product_id = int_property;
}
str_property = udev_device_get_property_value(parent, kHIDUnique);
if (str_property != NULL)
- device_info.serial_number = str_property;
+ device_info->serial_number = str_property;
str_property = udev_device_get_property_value(parent, kHIDName);
if (str_property != NULL)
- device_info.product_name = str_property;
+ device_info->product_name = str_property;
const std::string dev_node = udev_device_get_devnode(device);
- const int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
+#if defined(OS_CHROMEOS)
+ // ChromeOS builds on non-ChromeOS machines (dev) should not attempt to
+ // use permission broker.
+ if (base::SysInfo::IsRunningOnChromeOS()) {
+ chromeos::PermissionBrokerClient* client =
+ chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
+ DCHECK(client) << "Could not get permission broker client.";
+ if (!client) {
+ return;
+ }
+ ui_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&chromeos::PermissionBrokerClient::RequestPathAccess,
+ base::Unretained(client),
+ dev_node,
+ -1,
+ base::Bind(&HidServiceLinux::OnRequestAccessComplete,
+ weak_factory_.GetWeakPtr(),
+ dev_node,
+ base::Passed(&device_info))));
+ } else {
+ OnRequestAccessComplete(dev_node, device_info.Pass(), true);
+ }
+#else
+ OnRequestAccessComplete(dev_node, device_info.Pass(), true);
+#endif // defined(OS_CHROMEOS)
+}
+
+void HidServiceLinux::OnDeviceRemoved(udev_device* device) {
+ const char* device_path = udev_device_get_syspath(device);;
+ if (device_path)
+ RemoveDevice(device_path);
+}
- base::File device_file(base::FilePath(dev_node), flags);
+void HidServiceLinux::OnRequestAccessComplete(
+ const std::string& path,
+ scoped_ptr<HidDeviceInfo> device_info,
+ bool success) {
+ const int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
+ base::File device_file(base::FilePath(path), flags);
if (!device_file.IsValid()) {
- LOG(ERROR) << "Cannot open '" << dev_node << "': "
+ LOG(ERROR) << "Cannot open '" << path << "': "
<< base::File::ErrorToString(device_file.error_details());
return;
}
@@ -143,18 +189,12 @@ void HidServiceLinux::OnDeviceAdded(udev_device* device) {
device_file.Close();
HidReportDescriptor report_descriptor(rpt_desc.value, rpt_desc.size);
- report_descriptor.GetDetails(&device_info.collections,
- &device_info.max_input_report_size,
- &device_info.max_output_report_size,
- &device_info.max_feature_report_size);
-
- AddDevice(device_info);
-}
+ report_descriptor.GetDetails(&device_info->collections,
+ &device_info->max_input_report_size,
+ &device_info->max_output_report_size,
+ &device_info->max_feature_report_size);
-void HidServiceLinux::OnDeviceRemoved(udev_device* device) {
- const char* device_path = udev_device_get_syspath(device);;
- if (device_path)
- RemoveDevice(device_path);
+ AddDevice(*device_info);
}
} // namespace device