1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
9 #include "base/macros.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "device/core/device_client.h"
15 #include "device/devices_app/usb/device_impl.h"
16 #include "device/devices_app/usb/device_manager_impl.h"
17 #include "device/devices_app/usb/public/cpp/device_manager_delegate.h"
18 #include "device/usb/mock_usb_device.h"
19 #include "device/usb/mock_usb_device_handle.h"
20 #include "device/usb/mock_usb_service.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
24 using ::testing::Invoke
;
32 class TestDeviceManagerDelegate
: public DeviceManagerDelegate
{
34 TestDeviceManagerDelegate() {}
35 ~TestDeviceManagerDelegate() override
{}
38 // DeviceManagerDelegate implementation:
39 bool IsDeviceAllowed(const DeviceInfo
& device_info
) override
{ return true; }
42 class TestDeviceClient
: public DeviceClient
{
45 ~TestDeviceClient() override
{}
47 MockUsbService
& mock_usb_service() { return mock_usb_service_
; }
50 // DeviceClient implementation:
51 UsbService
* GetUsbService() override
{ return &mock_usb_service_
; }
53 MockUsbService mock_usb_service_
;
56 class USBDeviceManagerImplTest
: public testing::Test
{
58 USBDeviceManagerImplTest()
59 : message_loop_(new base::MessageLoop
),
60 device_client_(new TestDeviceClient
) {}
61 ~USBDeviceManagerImplTest() override
{}
64 MockUsbService
& mock_usb_service() {
65 return device_client_
->mock_usb_service();
68 DeviceManagerPtr
ConnectToDeviceManager() {
69 DeviceManagerPtr device_manager
;
70 new DeviceManagerImpl(
71 mojo::GetProxy(&device_manager
),
72 scoped_ptr
<DeviceManagerDelegate
>(new TestDeviceManagerDelegate
),
73 base::ThreadTaskRunnerHandle::Get());
74 return device_manager
.Pass();
78 scoped_ptr
<base::MessageLoop
> message_loop_
;
79 scoped_ptr
<TestDeviceClient
> device_client_
;
82 class MockOpenCallback
{
84 explicit MockOpenCallback(UsbDevice
* device
) : device_(device
) {}
86 void Open(const UsbDevice::OpenCallback
& callback
) {
87 device_handle_
= new MockUsbDeviceHandle(device_
);
88 callback
.Run(device_handle_
);
91 scoped_refptr
<MockUsbDeviceHandle
> mock_handle() { return device_handle_
; }
95 scoped_refptr
<MockUsbDeviceHandle
> device_handle_
;
98 void ExpectDevicesAndThen(const std::set
<std::string
>& expected_guids
,
99 const base::Closure
& continuation
,
100 mojo::Array
<DeviceInfoPtr
> results
) {
101 EXPECT_EQ(expected_guids
.size(), results
.size());
102 std::set
<std::string
> actual_guids
;
103 for (size_t i
= 0; i
< results
.size(); ++i
)
104 actual_guids
.insert(results
[i
]->guid
);
105 EXPECT_EQ(expected_guids
, actual_guids
);
109 void ExpectDeviceInfoAndThen(const std::string
& expected_guid
,
110 const base::Closure
& continuation
,
111 DeviceInfoPtr device_info
) {
112 EXPECT_EQ(expected_guid
, device_info
->guid
);
116 void ExpectOpenDeviceError(OpenDeviceError expected_error
,
117 OpenDeviceError actual_error
) {
118 EXPECT_EQ(expected_error
, actual_error
);
121 void FailOnGetDeviceInfoResponse(DeviceInfoPtr device_info
) {
127 // Test basic GetDevices functionality to ensure that all mock devices are
128 // returned by the service.
129 TEST_F(USBDeviceManagerImplTest
, GetDevices
) {
130 scoped_refptr
<MockUsbDevice
> device0
=
131 new MockUsbDevice(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");
132 scoped_refptr
<MockUsbDevice
> device1
=
133 new MockUsbDevice(0x1234, 0x5679, "ACME", "Frobinator+", "GHIJKL");
134 scoped_refptr
<MockUsbDevice
> device2
=
135 new MockUsbDevice(0x1234, 0x567a, "ACME", "Frobinator Mk II", "MNOPQR");
137 mock_usb_service().AddDevice(device0
);
138 mock_usb_service().AddDevice(device1
);
139 mock_usb_service().AddDevice(device2
);
141 DeviceManagerPtr device_manager
= ConnectToDeviceManager();
143 EnumerationOptionsPtr options
= EnumerationOptions::New();
144 options
->filters
= mojo::Array
<DeviceFilterPtr
>::New(1);
145 options
->filters
[0] = DeviceFilter::New();
146 options
->filters
[0]->has_vendor_id
= true;
147 options
->filters
[0]->vendor_id
= 0x1234;
149 std::set
<std::string
> guids
;
150 guids
.insert(device0
->guid());
151 guids
.insert(device1
->guid());
152 guids
.insert(device2
->guid());
154 // One call to GetActiveConfiguration for each device during enumeration.
155 EXPECT_CALL(*device0
.get(), GetActiveConfiguration());
156 EXPECT_CALL(*device1
.get(), GetActiveConfiguration());
157 EXPECT_CALL(*device2
.get(), GetActiveConfiguration());
160 device_manager
->GetDevices(
162 base::Bind(&ExpectDevicesAndThen
, guids
, loop
.QuitClosure()));
166 // Test requesting a single Device by GUID.
167 TEST_F(USBDeviceManagerImplTest
, OpenDevice
) {
168 scoped_refptr
<MockUsbDevice
> mock_device
=
169 new MockUsbDevice(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");
171 mock_usb_service().AddDevice(mock_device
);
173 DeviceManagerPtr device_manager
= ConnectToDeviceManager();
175 // Should be called on the mock as a result of OpenDevice() below.
176 EXPECT_CALL(*mock_device
.get(), Open(_
));
178 MockOpenCallback
open_callback(mock_device
.get());
179 ON_CALL(*mock_device
.get(), Open(_
))
180 .WillByDefault(Invoke(&open_callback
, &MockOpenCallback::Open
));
185 device_manager
->OpenDevice(
186 mock_device
->guid(), mojo::GetProxy(&device
),
187 base::Bind(&ExpectOpenDeviceError
, OPEN_DEVICE_ERROR_OK
));
188 device
->GetDeviceInfo(base::Bind(&ExpectDeviceInfoAndThen
,
189 mock_device
->guid(), loop
.QuitClosure()));
193 // The device should eventually be closed when its MessagePipe is closed.
194 DCHECK(open_callback
.mock_handle());
195 EXPECT_CALL(*open_callback
.mock_handle().get(), Close());
197 DevicePtr bad_device
;
198 device_manager
->OpenDevice(
199 "not a real guid", mojo::GetProxy(&bad_device
),
200 base::Bind(&ExpectOpenDeviceError
, OPEN_DEVICE_ERROR_NOT_FOUND
));
204 bad_device
.set_connection_error_handler(loop
.QuitClosure());
205 bad_device
->GetDeviceInfo(base::Bind(&FailOnGetDeviceInfoResponse
));
211 } // namespace device