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.
5 #include "components/webusb/webusb_detector.h"
7 #include "base/macros.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "components/webusb/webusb_browser_client.h"
11 #include "device/core/device_client.h"
12 #include "device/usb/mock_usb_device.h"
13 #include "device/usb/mock_usb_service.h"
14 #include "device/usb/usb_device.h"
15 #include "device/usb/usb_service.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
22 // usb device product name
23 const char* kProductName_1
= "Google Product A";
24 const char* kProductName_2
= "Google Product B";
25 const char* kProductName_3
= "Google Product C";
27 // usb device landing page
28 const char* kLandingPage_1
= "https://www.google.com/A";
29 const char* kLandingPage_2
= "https://www.google.com/B";
30 const char* kLandingPage_3
= "https://www.google.com/C";
38 class TestDeviceClient
: public device::DeviceClient
{
40 TestDeviceClient() : device::DeviceClient() {}
41 ~TestDeviceClient() override
{}
43 device::MockUsbService
& mock_usb_service() { return usb_service_
; }
46 device::UsbService
* GetUsbService() override
{ return &usb_service_
; }
48 device::MockUsbService usb_service_
;
51 class MockWebUsbBrowserClient
: public webusb::WebUsbBrowserClient
{
53 MockWebUsbBrowserClient() {}
55 ~MockWebUsbBrowserClient() override
{}
57 // webusb::WebUsbBrowserClient implementation
58 MOCK_METHOD3(OnDeviceAdded
,
59 void(const base::string16
& product_name
,
60 const GURL
& landing_page
,
61 const std::string
& notification_id
));
63 // webusb::WebUsbBrowserClient implementation
64 MOCK_METHOD1(OnDeviceRemoved
, void(const std::string
& notification_id
));
67 DISALLOW_COPY_AND_ASSIGN(MockWebUsbBrowserClient
);
72 class WebUsbDetectorTest
: public testing::Test
{
74 WebUsbDetectorTest() {}
76 ~WebUsbDetectorTest() override
= default;
79 TestDeviceClient device_client_
;
80 MockWebUsbBrowserClient mock_webusb_browser_client_
;
82 DISALLOW_COPY_AND_ASSIGN(WebUsbDetectorTest
);
85 TEST_F(WebUsbDetectorTest
, UsbDeviceAdded
) {
86 base::string16 product_name
= base::UTF8ToUTF16(kProductName_1
);
87 GURL
landing_page(kLandingPage_1
);
88 scoped_refptr
<device::MockUsbDevice
> device(new device::MockUsbDevice(
89 0, 1, "Google", kProductName_1
, "002", landing_page
));
90 std::string guid
= device
->guid();
92 EXPECT_CALL(mock_webusb_browser_client_
,
93 OnDeviceAdded(product_name
, landing_page
, guid
))
95 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(testing::_
))
98 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
100 device_client_
.mock_usb_service().AddDevice(device
);
103 TEST_F(WebUsbDetectorTest
, UsbDeviceAddedAndRemoved
) {
104 base::string16 product_name
= base::UTF8ToUTF16(kProductName_1
);
105 GURL
landing_page(kLandingPage_1
);
106 scoped_refptr
<device::MockUsbDevice
> device(new device::MockUsbDevice(
107 0, 1, "Google", kProductName_1
, "002", landing_page
));
108 std::string guid
= device
->guid();
111 testing::InSequence s
;
112 EXPECT_CALL(mock_webusb_browser_client_
,
113 OnDeviceAdded(product_name
, landing_page
, guid
))
115 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid
)).Times(1);
118 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
120 device_client_
.mock_usb_service().AddDevice(device
);
121 device_client_
.mock_usb_service().RemoveDevice(device
);
124 TEST_F(WebUsbDetectorTest
, UsbDeviceWithoutProductNameAddedAndRemoved
) {
125 std::string product_name
= "";
126 GURL
landing_page(kLandingPage_1
);
127 scoped_refptr
<device::MockUsbDevice
> device(new device::MockUsbDevice(
128 0, 1, "Google", product_name
, "002", landing_page
));
129 std::string guid
= device
->guid();
131 EXPECT_CALL(mock_webusb_browser_client_
,
132 OnDeviceAdded(testing::_
, testing::_
, testing::_
))
134 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid
)).Times(1);
136 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
138 device_client_
.mock_usb_service().AddDevice(device
);
139 device_client_
.mock_usb_service().RemoveDevice(device
);
142 TEST_F(WebUsbDetectorTest
, UsbDeviceWithoutLandingPageAddedAndRemoved
) {
143 GURL
landing_page("");
144 scoped_refptr
<device::MockUsbDevice
> device(new device::MockUsbDevice(
145 0, 1, "Google", kProductName_1
, "002", landing_page
));
146 std::string guid
= device
->guid();
148 EXPECT_CALL(mock_webusb_browser_client_
,
149 OnDeviceAdded(testing::_
, testing::_
, testing::_
))
151 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid
)).Times(1);
153 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
155 device_client_
.mock_usb_service().AddDevice(device
);
156 device_client_
.mock_usb_service().RemoveDevice(device
);
159 TEST_F(WebUsbDetectorTest
, WebUsbBrowserClientIsNullptr
) {
160 GURL
landing_page(kLandingPage_1
);
161 scoped_refptr
<device::MockUsbDevice
> device(new device::MockUsbDevice(
162 0, 1, "Google", kProductName_1
, "002", landing_page
));
164 EXPECT_CALL(mock_webusb_browser_client_
,
165 OnDeviceAdded(testing::_
, testing::_
, testing::_
))
167 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(testing::_
))
170 webusb::WebUsbDetector
webusb_detector(nullptr);
172 device_client_
.mock_usb_service().AddDevice(device
);
173 device_client_
.mock_usb_service().RemoveDevice(device
);
176 TEST_F(WebUsbDetectorTest
, NoUsbService
) {
177 GURL
landing_page(kLandingPage_1
);
178 scoped_refptr
<device::MockUsbDevice
> device(new device::MockUsbDevice(
179 0, 1, "Google", kProductName_1
, "002", landing_page
));
181 EXPECT_CALL(mock_webusb_browser_client_
,
182 OnDeviceAdded(testing::_
, testing::_
, testing::_
))
184 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(testing::_
))
187 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
190 TEST_F(WebUsbDetectorTest
, UsbDeviceWasThereBeforeAndThenRemoved
) {
191 GURL
landing_page(kLandingPage_1
);
192 scoped_refptr
<device::MockUsbDevice
> device(new device::MockUsbDevice(
193 0, 1, "Google", kProductName_1
, "002", landing_page
));
194 std::string guid
= device
->guid();
196 EXPECT_CALL(mock_webusb_browser_client_
,
197 OnDeviceAdded(testing::_
, testing::_
, testing::_
))
199 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid
)).Times(1);
201 // usb device was added before webusb_detector was created
202 device_client_
.mock_usb_service().AddDevice(device
);
204 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
206 device_client_
.mock_usb_service().RemoveDevice(device
);
211 ThreeUsbDevicesWereThereBeforeAndThenRemovedBeforeWebUsbDetectorWasCreated
) {
212 base::string16 product_name_1
= base::UTF8ToUTF16(kProductName_1
);
213 GURL
landing_page_1(kLandingPage_1
);
214 scoped_refptr
<device::MockUsbDevice
> device_1(new device::MockUsbDevice(
215 0, 1, "Google", kProductName_1
, "002", landing_page_1
));
216 std::string guid_1
= device_1
->guid();
218 base::string16 product_name_2
= base::UTF8ToUTF16(kProductName_2
);
219 GURL
landing_page_2(kLandingPage_2
);
220 scoped_refptr
<device::MockUsbDevice
> device_2(new device::MockUsbDevice(
221 3, 4, "Google", kProductName_2
, "005", landing_page_2
));
222 std::string guid_2
= device_2
->guid();
224 base::string16 product_name_3
= base::UTF8ToUTF16(kProductName_3
);
225 GURL
landing_page_3(kLandingPage_3
);
226 scoped_refptr
<device::MockUsbDevice
> device_3(new device::MockUsbDevice(
227 6, 7, "Google", kProductName_3
, "008", landing_page_3
));
228 std::string guid_3
= device_3
->guid();
230 EXPECT_CALL(mock_webusb_browser_client_
,
231 OnDeviceAdded(product_name_1
, landing_page_1
, guid_1
))
233 EXPECT_CALL(mock_webusb_browser_client_
,
234 OnDeviceAdded(product_name_2
, landing_page_2
, guid_2
))
236 EXPECT_CALL(mock_webusb_browser_client_
,
237 OnDeviceAdded(product_name_3
, landing_page_3
, guid_3
))
240 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_1
)).Times(0);
241 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_2
)).Times(0);
242 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_3
)).Times(0);
244 // three usb devices were added and removed before webusb_detector was
246 device_client_
.mock_usb_service().AddDevice(device_1
);
247 device_client_
.mock_usb_service().AddDevice(device_2
);
248 device_client_
.mock_usb_service().AddDevice(device_3
);
250 device_client_
.mock_usb_service().RemoveDevice(device_1
);
251 device_client_
.mock_usb_service().RemoveDevice(device_2
);
252 device_client_
.mock_usb_service().RemoveDevice(device_3
);
254 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
259 ThreeUsbDevicesWereThereBeforeAndThenRemovedAfterWebUsbDetectorWasCreated
) {
260 base::string16 product_name_1
= base::UTF8ToUTF16(kProductName_1
);
261 GURL
landing_page_1(kLandingPage_1
);
262 scoped_refptr
<device::MockUsbDevice
> device_1(new device::MockUsbDevice(
263 0, 1, "Google", kProductName_1
, "002", landing_page_1
));
264 std::string guid_1
= device_1
->guid();
266 base::string16 product_name_2
= base::UTF8ToUTF16(kProductName_2
);
267 GURL
landing_page_2(kLandingPage_2
);
268 scoped_refptr
<device::MockUsbDevice
> device_2(new device::MockUsbDevice(
269 3, 4, "Google", kProductName_2
, "005", landing_page_2
));
270 std::string guid_2
= device_2
->guid();
272 base::string16 product_name_3
= base::UTF8ToUTF16(kProductName_3
);
273 GURL
landing_page_3(kLandingPage_3
);
274 scoped_refptr
<device::MockUsbDevice
> device_3(new device::MockUsbDevice(
275 6, 7, "Google", kProductName_3
, "008", landing_page_3
));
276 std::string guid_3
= device_3
->guid();
278 EXPECT_CALL(mock_webusb_browser_client_
,
279 OnDeviceAdded(product_name_1
, landing_page_1
, guid_1
))
281 EXPECT_CALL(mock_webusb_browser_client_
,
282 OnDeviceAdded(product_name_2
, landing_page_2
, guid_2
))
284 EXPECT_CALL(mock_webusb_browser_client_
,
285 OnDeviceAdded(product_name_3
, landing_page_3
, guid_3
))
289 testing::InSequence s
;
291 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_1
)).Times(1);
292 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_2
)).Times(1);
293 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_3
)).Times(1);
296 // three usb devices were added before webusb_detector was created
297 device_client_
.mock_usb_service().AddDevice(device_1
);
298 device_client_
.mock_usb_service().AddDevice(device_2
);
299 device_client_
.mock_usb_service().AddDevice(device_3
);
301 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
303 device_client_
.mock_usb_service().RemoveDevice(device_1
);
304 device_client_
.mock_usb_service().RemoveDevice(device_2
);
305 device_client_
.mock_usb_service().RemoveDevice(device_3
);
308 TEST_F(WebUsbDetectorTest
,
309 TwoUsbDevicesWereThereBeforeAndThenRemovedAndNewUsbDeviceAdded
) {
310 base::string16 product_name_1
= base::UTF8ToUTF16(kProductName_1
);
311 GURL
landing_page_1(kLandingPage_1
);
312 scoped_refptr
<device::MockUsbDevice
> device_1(new device::MockUsbDevice(
313 0, 1, "Google", kProductName_1
, "002", landing_page_1
));
314 std::string guid_1
= device_1
->guid();
316 base::string16 product_name_2
= base::UTF8ToUTF16(kProductName_2
);
317 GURL
landing_page_2(kLandingPage_2
);
318 scoped_refptr
<device::MockUsbDevice
> device_2(new device::MockUsbDevice(
319 3, 4, "Google", kProductName_2
, "005", landing_page_2
));
320 std::string guid_2
= device_2
->guid();
322 base::string16 product_name_3
= base::UTF8ToUTF16(kProductName_3
);
323 GURL
landing_page_3(kLandingPage_3
);
324 scoped_refptr
<device::MockUsbDevice
> device_3(new device::MockUsbDevice(
325 6, 7, "Google", kProductName_3
, "008", landing_page_3
));
326 std::string guid_3
= device_3
->guid();
328 EXPECT_CALL(mock_webusb_browser_client_
,
329 OnDeviceAdded(product_name_1
, landing_page_1
, guid_1
))
331 EXPECT_CALL(mock_webusb_browser_client_
,
332 OnDeviceAdded(product_name_3
, landing_page_3
, guid_3
))
336 testing::InSequence s
;
338 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_1
)).Times(1);
339 EXPECT_CALL(mock_webusb_browser_client_
,
340 OnDeviceAdded(product_name_2
, landing_page_2
, guid_2
))
342 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_3
)).Times(1);
343 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_2
)).Times(1);
346 // two usb devices were added before webusb_detector was created
347 device_client_
.mock_usb_service().AddDevice(device_1
);
348 device_client_
.mock_usb_service().AddDevice(device_3
);
350 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
352 device_client_
.mock_usb_service().RemoveDevice(device_1
);
353 device_client_
.mock_usb_service().AddDevice(device_2
);
354 device_client_
.mock_usb_service().RemoveDevice(device_3
);
355 device_client_
.mock_usb_service().RemoveDevice(device_2
);
358 TEST_F(WebUsbDetectorTest
, ThreeUsbDevicesAddedAndRemoved
) {
359 base::string16 product_name_1
= base::UTF8ToUTF16(kProductName_1
);
360 GURL
landing_page_1(kLandingPage_1
);
361 scoped_refptr
<device::MockUsbDevice
> device_1(new device::MockUsbDevice(
362 0, 1, "Google", kProductName_1
, "002", landing_page_1
));
363 std::string guid_1
= device_1
->guid();
365 base::string16 product_name_2
= base::UTF8ToUTF16(kProductName_2
);
366 GURL
landing_page_2(kLandingPage_2
);
367 scoped_refptr
<device::MockUsbDevice
> device_2(new device::MockUsbDevice(
368 3, 4, "Google", kProductName_2
, "005", landing_page_2
));
369 std::string guid_2
= device_2
->guid();
371 base::string16 product_name_3
= base::UTF8ToUTF16(kProductName_3
);
372 GURL
landing_page_3(kLandingPage_3
);
373 scoped_refptr
<device::MockUsbDevice
> device_3(new device::MockUsbDevice(
374 6, 7, "Google", kProductName_3
, "008", landing_page_3
));
375 std::string guid_3
= device_3
->guid();
378 testing::InSequence s
;
380 EXPECT_CALL(mock_webusb_browser_client_
,
381 OnDeviceAdded(product_name_1
, landing_page_1
, guid_1
))
383 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_1
)).Times(1);
385 EXPECT_CALL(mock_webusb_browser_client_
,
386 OnDeviceAdded(product_name_2
, landing_page_2
, guid_2
))
388 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_2
)).Times(1);
390 EXPECT_CALL(mock_webusb_browser_client_
,
391 OnDeviceAdded(product_name_3
, landing_page_3
, guid_3
))
393 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_3
)).Times(1);
396 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
398 device_client_
.mock_usb_service().AddDevice(device_1
);
399 device_client_
.mock_usb_service().RemoveDevice(device_1
);
400 device_client_
.mock_usb_service().AddDevice(device_2
);
401 device_client_
.mock_usb_service().RemoveDevice(device_2
);
402 device_client_
.mock_usb_service().AddDevice(device_3
);
403 device_client_
.mock_usb_service().RemoveDevice(device_3
);
406 TEST_F(WebUsbDetectorTest
, ThreeUsbDeviceAddedAndRemovedDifferentOrder
) {
407 base::string16 product_name_1
= base::UTF8ToUTF16(kProductName_1
);
408 GURL
landing_page_1(kLandingPage_1
);
409 scoped_refptr
<device::MockUsbDevice
> device_1(new device::MockUsbDevice(
410 0, 1, "Google", kProductName_1
, "002", landing_page_1
));
411 std::string guid_1
= device_1
->guid();
413 base::string16 product_name_2
= base::UTF8ToUTF16(kProductName_2
);
414 GURL
landing_page_2(kLandingPage_2
);
415 scoped_refptr
<device::MockUsbDevice
> device_2(new device::MockUsbDevice(
416 3, 4, "Google", kProductName_2
, "005", landing_page_2
));
417 std::string guid_2
= device_2
->guid();
419 base::string16 product_name_3
= base::UTF8ToUTF16(kProductName_3
);
420 GURL
landing_page_3(kLandingPage_3
);
421 scoped_refptr
<device::MockUsbDevice
> device_3(new device::MockUsbDevice(
422 6, 7, "Google", kProductName_3
, "008", landing_page_3
));
423 std::string guid_3
= device_3
->guid();
426 testing::InSequence s
;
428 EXPECT_CALL(mock_webusb_browser_client_
,
429 OnDeviceAdded(product_name_1
, landing_page_1
, guid_1
))
432 EXPECT_CALL(mock_webusb_browser_client_
,
433 OnDeviceAdded(product_name_2
, landing_page_2
, guid_2
))
436 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_2
)).Times(1);
438 EXPECT_CALL(mock_webusb_browser_client_
,
439 OnDeviceAdded(product_name_3
, landing_page_3
, guid_3
))
442 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_1
)).Times(1);
444 EXPECT_CALL(mock_webusb_browser_client_
, OnDeviceRemoved(guid_3
)).Times(1);
447 webusb::WebUsbDetector
webusb_detector(&mock_webusb_browser_client_
);
449 device_client_
.mock_usb_service().AddDevice(device_1
);
450 device_client_
.mock_usb_service().AddDevice(device_2
);
451 device_client_
.mock_usb_service().RemoveDevice(device_2
);
452 device_client_
.mock_usb_service().AddDevice(device_3
);
453 device_client_
.mock_usb_service().RemoveDevice(device_1
);
454 device_client_
.mock_usb_service().RemoveDevice(device_3
);
457 } // namespace webusb