1 // Copyright 2014 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 "base/run_loop.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "base/test/values_test_util.h"
8 #include "chrome/browser/extensions/test_extension_environment.h"
9 #include "chrome/test/base/testing_profile.h"
10 #include "device/core/device_client.h"
11 #include "device/hid/hid_device_info.h"
12 #include "device/usb/mock_usb_device.h"
13 #include "device/usb/mock_usb_service.h"
14 #include "extensions/browser/api/device_permissions_manager.h"
15 #include "extensions/browser/extension_prefs.h"
16 #include "extensions/common/extension.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace extensions
{
24 using device::HidDeviceId
;
25 using device::HidDeviceInfo
;
26 using device::HidService
;
27 using device::MockUsbDevice
;
28 using device::MockUsbService
;
29 using device::UsbDevice
;
30 using device::UsbDeviceHandle
;
31 using device::UsbService
;
34 using testing::Return
;
35 using testing::SetArgPointee
;
37 #if defined(OS_MACOSX)
38 const uint64_t kTestDeviceIds
[] = {1, 2, 3, 4};
40 const char* kTestDeviceIds
[] = {"A", "B", "C", "D"};
43 class MockDeviceClient
: device::DeviceClient
{
47 // device::DeviceClient implementation:
48 UsbService
* GetUsbService() override
{
53 HidService
* GetHidService() override
{
58 void set_usb_service(UsbService
* service
) { usb_service_
= service
; }
59 void set_hid_service(HidService
* service
) { hid_service_
= service
; }
62 UsbService
* usb_service_
= nullptr;
63 HidService
* hid_service_
= nullptr;
66 class MockHidService
: public HidService
{
69 ~MockHidService() override
{}
71 // Public wrappers around protected functions needed for tests.
72 void AddDevice(scoped_refptr
<HidDeviceInfo
> info
) {
73 HidService::AddDevice(info
);
76 void RemoveDevice(const HidDeviceId
& device_id
) {
77 HidService::RemoveDevice(device_id
);
80 void FirstEnumerationComplete() { HidService::FirstEnumerationComplete(); }
84 void(const HidDeviceId
& device_id
,
85 const ConnectCallback
& callback
));
90 class DevicePermissionsManagerTest
: public testing::Test
{
92 void SetUp() override
{
93 testing::Test::SetUp();
94 env_
.reset(new extensions::TestExtensionEnvironment());
96 env_
->MakeExtension(*base::test::ParseJson(
100 " \"scripts\": [\"background.js\"]"
103 " \"permissions\": [ \"hid\", \"usb\" ]"
106 new MockUsbDevice(0, 0, "Test Manufacturer", "Test Product", "ABCDE");
107 device1_
= new MockUsbDevice(0, 0, "Test Manufacturer", "Test Product", "");
109 new MockUsbDevice(0, 0, "Test Manufacturer", "Test Product", "12345");
110 device3_
= new MockUsbDevice(0, 0, "Test Manufacturer", "Test Product", "");
112 new HidDeviceInfo(kTestDeviceIds
[0], 0, 0, "Test HID Device", "abcde",
113 device::kHIDBusTypeUSB
, std::vector
<uint8
>());
114 hid_service_
.AddDevice(device4_
);
115 device5_
= new HidDeviceInfo(kTestDeviceIds
[1], 0, 0, "Test HID Device", "",
116 device::kHIDBusTypeUSB
, std::vector
<uint8
>());
117 hid_service_
.AddDevice(device5_
);
119 new HidDeviceInfo(kTestDeviceIds
[2], 0, 0, "Test HID Device", "67890",
120 device::kHIDBusTypeUSB
, std::vector
<uint8
>());
121 hid_service_
.AddDevice(device6_
);
122 device7_
= new HidDeviceInfo(kTestDeviceIds
[3], 0, 0, "Test HID Device", "",
123 device::kHIDBusTypeUSB
, std::vector
<uint8
>());
124 hid_service_
.AddDevice(device7_
);
125 hid_service_
.FirstEnumerationComplete();
126 mock_device_client_
.set_usb_service(&usb_service_
);
127 mock_device_client_
.set_hid_service(&hid_service_
);
130 void TearDown() override
{ env_
.reset(nullptr); }
132 scoped_ptr
<extensions::TestExtensionEnvironment
> env_
;
133 const extensions::Extension
* extension_
;
134 MockDeviceClient mock_device_client_
;
135 MockUsbService usb_service_
;
136 MockHidService hid_service_
;
137 scoped_refptr
<MockUsbDevice
> device0_
;
138 scoped_refptr
<MockUsbDevice
> device1_
;
139 scoped_refptr
<MockUsbDevice
> device2_
;
140 scoped_refptr
<MockUsbDevice
> device3_
;
141 scoped_refptr
<HidDeviceInfo
> device4_
;
142 scoped_refptr
<HidDeviceInfo
> device5_
;
143 scoped_refptr
<HidDeviceInfo
> device6_
;
144 scoped_refptr
<HidDeviceInfo
> device7_
;
147 TEST_F(DevicePermissionsManagerTest
, AllowAndClearDevices
) {
148 DevicePermissionsManager
* manager
=
149 DevicePermissionsManager::Get(env_
->profile());
150 manager
->AllowUsbDevice(extension_
->id(), device0_
);
151 manager
->AllowUsbDevice(extension_
->id(), device1_
);
152 manager
->AllowHidDevice(extension_
->id(), device4_
);
153 manager
->AllowHidDevice(extension_
->id(), device5_
);
155 DevicePermissions
* device_permissions
=
156 manager
->GetForExtension(extension_
->id());
157 scoped_refptr
<DevicePermissionEntry
> device0_entry
=
158 device_permissions
->FindUsbDeviceEntry(device0_
);
159 ASSERT_TRUE(device0_entry
.get());
160 scoped_refptr
<DevicePermissionEntry
> device1_entry
=
161 device_permissions
->FindUsbDeviceEntry(device1_
);
162 ASSERT_TRUE(device1_entry
.get());
163 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device2_
).get());
164 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device3_
).get());
165 scoped_refptr
<DevicePermissionEntry
> device4_entry
=
166 device_permissions
->FindHidDeviceEntry(device4_
);
167 ASSERT_TRUE(device4_entry
.get());
168 scoped_refptr
<DevicePermissionEntry
> device5_entry
=
169 device_permissions
->FindHidDeviceEntry(device5_
);
170 ASSERT_TRUE(device5_entry
.get());
171 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device6_
).get());
172 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device7_
).get());
173 EXPECT_EQ(4U, device_permissions
->entries().size());
175 EXPECT_EQ(base::ASCIIToUTF16(
176 "Test Product from Test Manufacturer (serial number ABCDE)"),
177 device0_entry
->GetPermissionMessageString());
178 EXPECT_EQ(base::ASCIIToUTF16("Test Product from Test Manufacturer"),
179 device1_entry
->GetPermissionMessageString());
180 EXPECT_EQ(base::ASCIIToUTF16("Test HID Device (serial number abcde)"),
181 device4_entry
->GetPermissionMessageString());
182 EXPECT_EQ(base::ASCIIToUTF16("Test HID Device"),
183 device5_entry
->GetPermissionMessageString());
185 manager
->Clear(extension_
->id());
186 // The device_permissions object is deleted by Clear.
187 device_permissions
= manager
->GetForExtension(extension_
->id());
189 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
190 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
191 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device2_
).get());
192 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device3_
).get());
193 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device4_
).get());
194 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device5_
).get());
195 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device6_
).get());
196 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device7_
).get());
197 EXPECT_EQ(0U, device_permissions
->entries().size());
199 // After clearing device it should be possible to grant permission again.
200 manager
->AllowUsbDevice(extension_
->id(), device0_
);
201 manager
->AllowUsbDevice(extension_
->id(), device1_
);
202 manager
->AllowHidDevice(extension_
->id(), device4_
);
203 manager
->AllowHidDevice(extension_
->id(), device5_
);
205 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
206 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
207 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device2_
).get());
208 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device3_
).get());
209 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device4_
).get());
210 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device5_
).get());
211 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device6_
).get());
212 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device7_
).get());
215 TEST_F(DevicePermissionsManagerTest
, DisconnectDevice
) {
216 DevicePermissionsManager
* manager
=
217 DevicePermissionsManager::Get(env_
->profile());
218 manager
->AllowUsbDevice(extension_
->id(), device0_
);
219 manager
->AllowUsbDevice(extension_
->id(), device1_
);
220 manager
->AllowHidDevice(extension_
->id(), device4_
);
221 manager
->AllowHidDevice(extension_
->id(), device5_
);
223 DevicePermissions
* device_permissions
=
224 manager
->GetForExtension(extension_
->id());
225 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
226 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
227 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device2_
).get());
228 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device3_
).get());
229 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device4_
).get());
230 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device5_
).get());
231 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device6_
).get());
232 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device7_
).get());
234 usb_service_
.RemoveDevice(device0_
);
235 usb_service_
.RemoveDevice(device1_
);
236 hid_service_
.RemoveDevice(device4_
->device_id());
237 hid_service_
.RemoveDevice(device5_
->device_id());
239 // Device 0 will be accessible when it is reconnected because it can be
240 // recognized by its serial number.
241 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
242 // Device 1 does not have a serial number and cannot be distinguished from
243 // any other device of the same model so the app must request permission again
244 // when it is reconnected.
245 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
246 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device2_
).get());
247 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device3_
).get());
248 // Device 4 is like device 0, but HID.
249 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device4_
).get());
250 // Device 5 is like device 1, but HID.
251 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device5_
).get());
252 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device6_
).get());
253 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device7_
).get());
256 TEST_F(DevicePermissionsManagerTest
, RevokeAndRegrantAccess
) {
257 DevicePermissionsManager
* manager
=
258 DevicePermissionsManager::Get(env_
->profile());
259 manager
->AllowUsbDevice(extension_
->id(), device0_
);
260 manager
->AllowUsbDevice(extension_
->id(), device1_
);
261 manager
->AllowHidDevice(extension_
->id(), device4_
);
262 manager
->AllowHidDevice(extension_
->id(), device5_
);
264 DevicePermissions
* device_permissions
=
265 manager
->GetForExtension(extension_
->id());
266 scoped_refptr
<DevicePermissionEntry
> device0_entry
=
267 device_permissions
->FindUsbDeviceEntry(device0_
);
268 ASSERT_TRUE(device0_entry
.get());
269 scoped_refptr
<DevicePermissionEntry
> device1_entry
=
270 device_permissions
->FindUsbDeviceEntry(device1_
);
271 ASSERT_TRUE(device1_entry
.get());
272 scoped_refptr
<DevicePermissionEntry
> device4_entry
=
273 device_permissions
->FindHidDeviceEntry(device4_
);
274 ASSERT_TRUE(device4_entry
.get());
275 scoped_refptr
<DevicePermissionEntry
> device5_entry
=
276 device_permissions
->FindHidDeviceEntry(device5_
);
277 ASSERT_TRUE(device5_entry
.get());
279 manager
->RemoveEntry(extension_
->id(), device0_entry
);
280 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
281 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
283 manager
->AllowUsbDevice(extension_
->id(), device0_
);
284 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
285 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
287 manager
->RemoveEntry(extension_
->id(), device1_entry
);
288 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
289 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
291 manager
->AllowUsbDevice(extension_
->id(), device1_
);
292 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device0_
).get());
293 EXPECT_TRUE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
295 manager
->RemoveEntry(extension_
->id(), device4_entry
);
296 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device4_
).get());
297 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device5_
).get());
299 manager
->AllowHidDevice(extension_
->id(), device4_
);
300 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device4_
).get());
301 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device5_
).get());
303 manager
->RemoveEntry(extension_
->id(), device5_entry
);
304 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device4_
).get());
305 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device5_
).get());
307 manager
->AllowHidDevice(extension_
->id(), device5_
);
308 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device4_
).get());
309 EXPECT_TRUE(device_permissions
->FindHidDeviceEntry(device5_
).get());
312 TEST_F(DevicePermissionsManagerTest
, UpdateLastUsed
) {
313 DevicePermissionsManager
* manager
=
314 DevicePermissionsManager::Get(env_
->profile());
315 manager
->AllowUsbDevice(extension_
->id(), device0_
);
316 manager
->AllowHidDevice(extension_
->id(), device4_
);
318 DevicePermissions
* device_permissions
=
319 manager
->GetForExtension(extension_
->id());
320 scoped_refptr
<DevicePermissionEntry
> device0_entry
=
321 device_permissions
->FindUsbDeviceEntry(device0_
);
322 EXPECT_TRUE(device0_entry
->last_used().is_null());
323 scoped_refptr
<DevicePermissionEntry
> device4_entry
=
324 device_permissions
->FindHidDeviceEntry(device4_
);
325 EXPECT_TRUE(device4_entry
->last_used().is_null());
327 manager
->UpdateLastUsed(extension_
->id(), device0_entry
);
328 EXPECT_FALSE(device0_entry
->last_used().is_null());
329 manager
->UpdateLastUsed(extension_
->id(), device4_entry
);
330 EXPECT_FALSE(device4_entry
->last_used().is_null());
333 TEST_F(DevicePermissionsManagerTest
, LoadPrefs
) {
334 scoped_ptr
<base::Value
> prefs_value
= base::test::ParseJson(
337 " \"manufacturer_string\": \"Test Manufacturer\","
338 " \"product_id\": 0,"
339 " \"product_string\": \"Test Product\","
340 " \"serial_number\": \"ABCDE\","
341 " \"type\": \"usb\","
345 " \"product_id\": 0,"
346 " \"product_string\": \"Test HID Device\","
347 " \"serial_number\": \"abcde\","
348 " \"type\": \"hid\","
352 env_
->GetExtensionPrefs()->UpdateExtensionPref(extension_
->id(), "devices",
353 prefs_value
.release());
355 DevicePermissionsManager
* manager
=
356 DevicePermissionsManager::Get(env_
->profile());
357 DevicePermissions
* device_permissions
=
358 manager
->GetForExtension(extension_
->id());
359 scoped_refptr
<DevicePermissionEntry
> device0_entry
=
360 device_permissions
->FindUsbDeviceEntry(device0_
);
361 ASSERT_TRUE(device0_entry
.get());
362 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device1_
).get());
363 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device2_
).get());
364 EXPECT_FALSE(device_permissions
->FindUsbDeviceEntry(device3_
).get());
365 scoped_refptr
<DevicePermissionEntry
> device4_entry
=
366 device_permissions
->FindHidDeviceEntry(device4_
);
367 ASSERT_TRUE(device4_entry
.get());
368 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device5_
).get());
369 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device6_
).get());
370 EXPECT_FALSE(device_permissions
->FindHidDeviceEntry(device7_
).get());
372 EXPECT_EQ(base::ASCIIToUTF16(
373 "Test Product from Test Manufacturer (serial number ABCDE)"),
374 device0_entry
->GetPermissionMessageString());
375 EXPECT_EQ(base::ASCIIToUTF16("Test HID Device (serial number abcde)"),
376 device4_entry
->GetPermissionMessageString());
379 TEST_F(DevicePermissionsManagerTest
, PermissionMessages
) {
380 base::string16 empty
;
381 base::string16
product(base::ASCIIToUTF16("Widget"));
382 base::string16
manufacturer(base::ASCIIToUTF16("ACME"));
383 base::string16
serial_number(base::ASCIIToUTF16("A"));
385 EXPECT_EQ(base::ASCIIToUTF16("Unknown product 0001 from vendor 0000"),
386 DevicePermissionsManager::GetPermissionMessage(
387 0x0000, 0x0001, empty
, empty
, empty
, false));
389 EXPECT_EQ(base::ASCIIToUTF16(
390 "Unknown product 0001 from vendor 0000 (serial number A)"),
391 DevicePermissionsManager::GetPermissionMessage(
392 0x0000, 0x0001, empty
, empty
, base::ASCIIToUTF16("A"), false));
394 EXPECT_EQ(base::ASCIIToUTF16("Unknown product 0001 from Google Inc."),
395 DevicePermissionsManager::GetPermissionMessage(
396 0x18D1, 0x0001, empty
, empty
, empty
, false));
398 EXPECT_EQ(base::ASCIIToUTF16(
399 "Unknown product 0001 from Google Inc. (serial number A)"),
400 DevicePermissionsManager::GetPermissionMessage(
401 0x18D1, 0x0001, empty
, empty
, serial_number
, false));
403 EXPECT_EQ(base::ASCIIToUTF16("Nexus One from Google Inc."),
404 DevicePermissionsManager::GetPermissionMessage(
405 0x18D1, 0x4E11, empty
, empty
, empty
, true));
407 EXPECT_EQ(base::ASCIIToUTF16("Nexus One from Google Inc. (serial number A)"),
408 DevicePermissionsManager::GetPermissionMessage(
409 0x18D1, 0x4E11, empty
, empty
, serial_number
, true));
411 EXPECT_EQ(base::ASCIIToUTF16("Nexus One"),
412 DevicePermissionsManager::GetPermissionMessage(
413 0x18D1, 0x4E11, empty
, empty
, empty
, false));
415 EXPECT_EQ(base::ASCIIToUTF16("Nexus One (serial number A)"),
416 DevicePermissionsManager::GetPermissionMessage(
417 0x18D1, 0x4E11, empty
, empty
, serial_number
, false));
419 EXPECT_EQ(base::ASCIIToUTF16("Unknown product 0001 from ACME"),
420 DevicePermissionsManager::GetPermissionMessage(
421 0x0000, 0x0001, manufacturer
, empty
, empty
, false));
424 base::ASCIIToUTF16("Unknown product 0001 from ACME (serial number A)"),
425 DevicePermissionsManager::GetPermissionMessage(
426 0x0000, 0x0001, manufacturer
, empty
, serial_number
, false));
428 EXPECT_EQ(base::ASCIIToUTF16("Widget from ACME"),
429 DevicePermissionsManager::GetPermissionMessage(
430 0x0001, 0x0000, manufacturer
, product
, empty
, true));
432 EXPECT_EQ(base::ASCIIToUTF16("Widget from ACME (serial number A)"),
433 DevicePermissionsManager::GetPermissionMessage(
434 0x0001, 0x0000, manufacturer
, product
, serial_number
, true));
436 EXPECT_EQ(base::ASCIIToUTF16("Widget"),
437 DevicePermissionsManager::GetPermissionMessage(
438 0x0001, 0x0000, manufacturer
, product
, empty
, false));
440 EXPECT_EQ(base::ASCIIToUTF16("Widget (serial number A)"),
441 DevicePermissionsManager::GetPermissionMessage(
442 0x0001, 0x0000, manufacturer
, product
, serial_number
, false));
445 } // namespace extensions