diff --git a/device/usb/usb_device_win.cc b/device/usb/usb_device_win.cc index e54d1c88d7b1dc..18e83ef8718d21 100644 --- a/device/usb/usb_device_win.cc +++ b/device/usb/usb_device_win.cc @@ -18,10 +18,12 @@ UsbDeviceWin::UsbDeviceWin( const std::string& device_path, const std::string& hub_path, int port_number, + const std::string& driver_name, scoped_refptr blocking_task_runner) : device_path_(device_path), hub_path_(hub_path), port_number_(port_number), + driver_name_(driver_name), task_runner_(base::ThreadTaskRunnerHandle::Get()), blocking_task_runner_(std::move(blocking_task_runner)) {} diff --git a/device/usb/usb_device_win.h b/device/usb/usb_device_win.h index 2c43a52f9004f3..dd17683a7579ed 100644 --- a/device/usb/usb_device_win.h +++ b/device/usb/usb_device_win.h @@ -32,12 +32,14 @@ class UsbDeviceWin : public UsbDevice { UsbDeviceWin(const std::string& device_path, const std::string& hub_path, int port_number, + const std::string& driver_name, scoped_refptr task_runner); ~UsbDeviceWin() override; const std::string& device_path() const { return device_path_; } int port_number() const { return port_number_; } + const std::string& driver_name() const { return driver_name_; } // Opens the device's parent hub in order to read the device, configuration // and string descriptors. @@ -59,6 +61,7 @@ class UsbDeviceWin : public UsbDevice { const std::string device_path_; const std::string hub_path_; const int port_number_; + const std::string driver_name_; scoped_refptr task_runner_; scoped_refptr blocking_task_runner_; diff --git a/device/usb/usb_service_unittest.cc b/device/usb/usb_service_unittest.cc index d5714ff78716df..4013fbefcd80f9 100644 --- a/device/usb/usb_service_unittest.cc +++ b/device/usb/usb_service_unittest.cc @@ -8,7 +8,9 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/test/test_io_thread.h" +#include "device/base/features.h" #include "device/test/test_device_client.h" #include "device/test/usb_test_gadget.h" #include "device/usb/usb_device.h" @@ -50,6 +52,19 @@ TEST_F(UsbServiceTest, GetDevices) { } } +#if defined(OS_WIN) +TEST_F(UsbServiceTest, GetDevicesNewBackend) { + base::test::ScopedFeatureList features; + features.InitAndEnableFeature(device::kNewUsbBackend); + UsbService* service = device_client_->GetUsbService(); + if (service) { + base::RunLoop loop; + service->GetDevices(base::Bind(&OnGetDevices, loop.QuitClosure())); + loop.Run(); + } +} +#endif // defined(OS_WIN) + TEST_F(UsbServiceTest, ClaimGadget) { if (!UsbTestGadget::IsTestEnabled()) return; diff --git a/device/usb/usb_service_win.cc b/device/usb/usb_service_win.cc index 65de4b0c6275c3..8cc9c0c9a2e169 100644 --- a/device/usb/usb_service_win.cc +++ b/device/usb/usb_service_win.cc @@ -83,8 +83,9 @@ bool GetDeviceInterfaceDetails(HDEVINFO dev_info, SP_DEVICE_INTERFACE_DATA* device_interface_data, std::string* device_path, uint32_t* port_number, - std::string* parent_instance_id) { - DWORD required_size; + std::string* parent_instance_id, + std::string* service_name) { + DWORD required_size = 0; if (SetupDiGetDeviceInterfaceDetail(dev_info, device_interface_data, nullptr, 0, &required_size, nullptr) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { @@ -127,6 +128,20 @@ bool GetDeviceInterfaceDetails(HDEVINFO dev_info, } } + if (service_name) { + if (!GetDeviceStringProperty(dev_info, &dev_info_data, + DEVPKEY_Device_Service, service_name)) { + USB_PLOG(ERROR) << "Failed to get device driver name"; + return false; + } + + // Windows pads this string with a variable number of NUL bytes for no + // discernible reason. + size_t end = service_name->find_last_not_of('\0'); + if (end != std::string::npos) + service_name->erase(end + 1); + } + return true; } @@ -150,7 +165,7 @@ bool GetHubDevicePath(const std::string& instance_id, } return GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, - device_path, nullptr, nullptr); + device_path, nullptr, nullptr, nullptr); } } // namespace @@ -182,9 +197,10 @@ class UsbServiceWin::BlockingThreadHelper { std::string device_path; uint32_t port_number; std::string parent_instance_id; + std::string service_name; if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, &device_path, &port_number, - &parent_instance_id)) { + &parent_instance_id, &service_name)) { continue; } @@ -198,8 +214,9 @@ class UsbServiceWin::BlockingThreadHelper { } service_task_runner_->PostTask( - FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_, - device_path, hub_path, port_number)); + FROM_HERE, + base::Bind(&UsbServiceWin::CreateDeviceObject, service_, device_path, + hub_path, port_number, service_name)); } if (GetLastError() != ERROR_NO_MORE_ITEMS) @@ -228,9 +245,10 @@ class UsbServiceWin::BlockingThreadHelper { uint32_t port_number; std::string parent_instance_id; + std::string service_name; if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, - nullptr, &port_number, - &parent_instance_id)) { + nullptr, &port_number, &parent_instance_id, + &service_name)) { return; } @@ -244,8 +262,9 @@ class UsbServiceWin::BlockingThreadHelper { } service_task_runner_->PostTask( - FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_, - device_path, hub_path, port_number)); + FROM_HERE, + base::Bind(&UsbServiceWin::CreateDeviceObject, service_, device_path, + hub_path, port_number, service_name)); } private: @@ -327,15 +346,16 @@ void UsbServiceWin::HelperStarted() { void UsbServiceWin::CreateDeviceObject(const std::string& device_path, const std::string& hub_path, - int port_number) { + int port_number, + const std::string& driver_name) { // Devices that appear during initial enumeration are gathered into the first // result returned by GetDevices() and prevent device add/remove notifications // from being sent. if (!enumeration_ready()) ++first_enumeration_countdown_; - scoped_refptr device( - new UsbDeviceWin(device_path, hub_path, port_number, task_runner())); + scoped_refptr device(new UsbDeviceWin( + device_path, hub_path, port_number, driver_name, blocking_task_runner())); devices_by_path_[device->device_path()] = device; device->ReadDescriptors(base::Bind(&UsbServiceWin::DeviceReady, weak_factory_.GetWeakPtr(), device)); @@ -367,7 +387,8 @@ void UsbServiceWin::DeviceReady(scoped_refptr device, << device->manufacturer_string() << "\", product=" << device->product_id() << " \"" << device->product_string() << "\", serial=\"" - << device->serial_number() << "\", guid=" << device->guid(); + << device->serial_number() << "\", driver=\"" + << device->driver_name() << "\", guid=" << device->guid(); } else { devices_by_path_.erase(it); } diff --git a/device/usb/usb_service_win.h b/device/usb/usb_service_win.h index a91557786ecfc1..58f4bb2bc8961d 100644 --- a/device/usb/usb_service_win.h +++ b/device/usb/usb_service_win.h @@ -41,7 +41,8 @@ class UsbServiceWin : public DeviceMonitorWin::Observer, public UsbService { void HelperStarted(); void CreateDeviceObject(const std::string& device_path, const std::string& hub_path, - int port_number); + int port_number, + const std::string& driver_name); void DeviceReady(scoped_refptr device, bool success);