1 // Copyright (c) 2012 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 "chrome/browser/chromeos/printer_detector/printer_detector.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
12 #include "chrome/browser/chromeos/printer_detector/printer_detector_factory.h"
13 #include "chrome/browser/chromeos/profiles/profile_helper.h"
14 #include "chrome/browser/extensions/test_extension_system.h"
15 #include "chrome/browser/notifications/notification.h"
16 #include "chrome/browser/notifications/notification_test_util.h"
17 #include "chrome/browser/notifications/notification_ui_manager.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/user_manager/fake_user_manager.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "device/core/device_client.h"
22 #include "device/usb/mock_usb_device.h"
23 #include "device/usb/mock_usb_service.h"
24 #include "device/usb/usb_descriptors.h"
25 #include "device/usb/usb_service.h"
26 #include "extensions/browser/extension_registry.h"
27 #include "extensions/common/extension_builder.h"
28 #include "extensions/common/value_builder.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 using extensions::DictionaryBuilder
;
32 using extensions::ListBuilder
;
38 const uint8 kPrinterInterfaceClass
= 7;
40 const char kTestUserId
[] = "test_user";
42 const char kPrinterAppExistsDelegateIDTemplate
[] =
43 "system.printer.printer_provider_exists/%s:%s";
45 const char kPrinterAppNotFoundDelegateIDTemplate
[] =
46 "system.printer.no_printer_provider_found/%s:%s";
48 class FakeDeviceClient
: public device::DeviceClient
{
50 FakeDeviceClient() : usb_service_(nullptr) {}
52 ~FakeDeviceClient() override
{}
54 // device::DeviceClient implementation:
55 device::UsbService
* GetUsbService() override
{
56 EXPECT_TRUE(usb_service_
);
60 void set_usb_service(device::UsbService
* service
) { usb_service_
= service
; }
63 device::UsbService
* usb_service_
;
65 DISALLOW_COPY_AND_ASSIGN(FakeDeviceClient
);
68 scoped_ptr
<KeyedService
> CreatePrinterDetector(
69 content::BrowserContext
* context
) {
70 return scoped_ptr
<KeyedService
>(
71 new chromeos::PrinterDetector(Profile::FromBrowserContext(context
)));
76 // TODO(tbarzic): Rename this test.
77 class PrinterDetectorAppSearchEnabledTest
: public testing::Test
{
79 PrinterDetectorAppSearchEnabledTest()
80 : user_manager_(new user_manager::FakeUserManager()),
81 user_manager_enabler_(user_manager_
) {}
83 ~PrinterDetectorAppSearchEnabledTest() override
= default;
85 void SetUp() override
{
86 device_client_
.set_usb_service(&usb_service_
);
87 // Make sure the profile is created after adding the switch and setting up
89 profile_
.reset(new TestingProfile());
90 chromeos::PrinterDetectorFactory::GetInstance()->SetTestingFactoryAndUse(
91 profile_
.get(), &CreatePrinterDetector
);
93 SetExtensionSystemReady(profile_
.get());
97 void SetExtensionSystemReady(TestingProfile
* profile
) {
98 extensions::TestExtensionSystem
* test_extension_system
=
99 static_cast<extensions::TestExtensionSystem
*>(
100 extensions::ExtensionSystem::Get(profile
));
101 test_extension_system
->SetReady();
102 base::RunLoop().RunUntilIdle();
106 const user_manager::User
* user
= user_manager_
->AddUser(kTestUserId
);
107 profile_
->set_profile_name(kTestUserId
);
108 chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
109 user
, profile_
.get());
110 chromeos::PrinterDetectorFactory::GetInstance()
111 ->Get(profile_
.get())
112 ->SetNotificationUIManagerForTesting(¬ification_ui_manager_
);
115 void InvokeUsbAdded(uint16 vendor_id
,
117 uint8 interface_class
) {
118 device::UsbInterfaceDescriptor interface
;
119 interface
.interface_number
= 1;
120 interface
.interface_class
= interface_class
;
121 device::UsbConfigDescriptor config
;
122 config
.interfaces
.push_back(interface
);
123 usb_service_
.AddDevice(
124 new device::MockUsbDevice(vendor_id
, product_id
, config
));
127 // Creates a test extension with the provided permissions.
128 scoped_refptr
<extensions::Extension
> CreateTestExtension(
129 ListBuilder
& permissions_builder
,
130 DictionaryBuilder
& usb_printers_builder
) {
131 return extensions::ExtensionBuilder()
132 .SetID("fake_extension_id")
135 .Set("name", "Printer provider extension")
136 .Set("manifest_version", 2)
137 .Set("version", "1.0")
138 // Needed to enable usb API.
139 .Set("app", DictionaryBuilder().Set(
141 DictionaryBuilder().Set(
142 "scripts", ListBuilder().Append("bg.js"))))
143 .Set("permissions", permissions_builder
)
144 .Set("usb_printers", usb_printers_builder
))
148 content::TestBrowserThreadBundle thread_bundle_
;
149 StubNotificationUIManager notification_ui_manager_
;
150 user_manager::FakeUserManager
* user_manager_
;
151 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
152 device::MockUsbService usb_service_
;
153 scoped_ptr
<TestingProfile
> profile_
;
154 FakeDeviceClient device_client_
;
156 DISALLOW_COPY_AND_ASSIGN(PrinterDetectorAppSearchEnabledTest
);
159 TEST_F(PrinterDetectorAppSearchEnabledTest
, ShowFindAppNotification
) {
160 InvokeUsbAdded(123, 456, kPrinterInterfaceClass
);
162 ASSERT_EQ(1u, notification_ui_manager_
.GetNotificationCount());
163 const Notification
& notification
=
164 notification_ui_manager_
.GetNotificationAt(0);
165 EXPECT_EQ("123:456", notification
.tag());
167 base::StringPrintf(kPrinterAppNotFoundDelegateIDTemplate
, "123", "456"),
168 notification
.delegate_id());
171 TEST_F(PrinterDetectorAppSearchEnabledTest
, ShowAppFoundNotification
) {
172 scoped_refptr
<extensions::Extension
> extension
= CreateTestExtension(
175 .Append("printerProvider")
176 .Append(DictionaryBuilder().Set(
177 "usbDevices", ListBuilder().Append(DictionaryBuilder()
178 .Set("vendorId", 123)
179 .Set("productId", 456))))
181 DictionaryBuilder().Set("filters", ListBuilder().Pass()).Pass());
182 ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_
.get())
183 ->AddEnabled(extension
));
185 InvokeUsbAdded(123, 456, kPrinterInterfaceClass
);
187 ASSERT_EQ(1u, notification_ui_manager_
.GetNotificationCount());
188 const Notification
& notification
=
189 notification_ui_manager_
.GetNotificationAt(0);
190 EXPECT_EQ("123:456", notification
.tag());
192 base::StringPrintf(kPrinterAppExistsDelegateIDTemplate
, "123", "456"),
193 notification
.delegate_id());
196 TEST_F(PrinterDetectorAppSearchEnabledTest
,
197 UsbHandlerExists_NotPrinterProvider
) {
198 scoped_refptr
<extensions::Extension
> extension
= CreateTestExtension(
201 .Append(DictionaryBuilder().Set(
202 "usbDevices", ListBuilder().Append(DictionaryBuilder()
203 .Set("vendorId", 123)
204 .Set("productId", 756))))
206 DictionaryBuilder().Set("filters", ListBuilder().Pass()).Pass());
207 ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_
.get())
208 ->AddEnabled(extension
));
210 InvokeUsbAdded(123, 756, kPrinterInterfaceClass
);
212 ASSERT_EQ(1u, notification_ui_manager_
.GetNotificationCount());
213 const Notification
& notification
=
214 notification_ui_manager_
.GetNotificationAt(0);
215 EXPECT_EQ("123:756", notification
.tag());
217 base::StringPrintf(kPrinterAppNotFoundDelegateIDTemplate
, "123", "756"),
218 notification
.delegate_id());
221 TEST_F(PrinterDetectorAppSearchEnabledTest
,
222 PrinterProvider_DifferentUsbProductId
) {
223 scoped_refptr
<extensions::Extension
> extension
= CreateTestExtension(
226 .Append("printerProvider")
227 .Append(DictionaryBuilder().Set(
228 "usbDevices", ListBuilder().Append(DictionaryBuilder()
229 .Set("vendorId", 123)
230 .Set("productId", 001))))
232 DictionaryBuilder().Set("filters", ListBuilder().Pass()).Pass());
233 ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_
.get())
234 ->AddEnabled(extension
));
236 InvokeUsbAdded(123, 456, kPrinterInterfaceClass
);
238 ASSERT_EQ(1u, notification_ui_manager_
.GetNotificationCount());
239 const Notification
& notification
=
240 notification_ui_manager_
.GetNotificationAt(0);
241 EXPECT_EQ("123:456", notification
.tag());
243 base::StringPrintf(kPrinterAppNotFoundDelegateIDTemplate
, "123", "456"),
244 notification
.delegate_id());
247 TEST_F(PrinterDetectorAppSearchEnabledTest
,
248 PrinterProvider_UsbPrinters_NotFound
) {
249 scoped_refptr
<extensions::Extension
> extension
=
251 ListBuilder().Append("usb").Append("printerProvider").Pass(),
252 DictionaryBuilder().Set(
253 "filters", ListBuilder().Append(DictionaryBuilder()
254 .Set("vendorId", 123)
255 .Set("productId", 001))))
257 ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_
.get())
258 ->AddEnabled(extension
));
260 InvokeUsbAdded(123, 456, kPrinterInterfaceClass
);
262 ASSERT_EQ(1u, notification_ui_manager_
.GetNotificationCount());
263 const Notification
& notification
=
264 notification_ui_manager_
.GetNotificationAt(0);
265 EXPECT_EQ("123:456", notification
.tag());
267 base::StringPrintf(kPrinterAppNotFoundDelegateIDTemplate
, "123", "456"),
268 notification
.delegate_id());
271 TEST_F(PrinterDetectorAppSearchEnabledTest
,
272 PrinterProvider_UsbPrinters_WithProductId
) {
273 scoped_refptr
<extensions::Extension
> extension
=
275 ListBuilder().Append("usb").Append("printerProvider").Pass(),
276 DictionaryBuilder().Set(
277 "filters", ListBuilder().Append(DictionaryBuilder()
278 .Set("vendorId", 123)
279 .Set("productId", 456))))
281 ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_
.get())
282 ->AddEnabled(extension
));
284 InvokeUsbAdded(123, 456, kPrinterInterfaceClass
);
286 ASSERT_EQ(1u, notification_ui_manager_
.GetNotificationCount());
287 const Notification
& notification
=
288 notification_ui_manager_
.GetNotificationAt(0);
289 EXPECT_EQ("123:456", notification
.tag());
291 base::StringPrintf(kPrinterAppExistsDelegateIDTemplate
, "123", "456"),
292 notification
.delegate_id());
295 TEST_F(PrinterDetectorAppSearchEnabledTest
,
296 PrinterProvider_UsbPrinters_WithInterfaceClass
) {
297 scoped_refptr
<extensions::Extension
> extension
=
299 ListBuilder().Append("usb").Append("printerProvider").Pass(),
300 DictionaryBuilder().Set(
302 ListBuilder().Append(
304 .Set("vendorId", 123)
305 .Set("interfaceClass", kPrinterInterfaceClass
)))).Pass();
306 ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_
.get())
307 ->AddEnabled(extension
));
309 InvokeUsbAdded(123, 456, kPrinterInterfaceClass
);
311 ASSERT_EQ(1u, notification_ui_manager_
.GetNotificationCount());
312 const Notification
& notification
=
313 notification_ui_manager_
.GetNotificationAt(0);
314 EXPECT_EQ("123:456", notification
.tag());
316 base::StringPrintf(kPrinterAppExistsDelegateIDTemplate
, "123", "456"),
317 notification
.delegate_id());
320 TEST_F(PrinterDetectorAppSearchEnabledTest
, IgnoreNonPrinters
) {
321 scoped_refptr
<extensions::Extension
> extension
=
323 ListBuilder().Append("usb").Append("printerProvider").Pass(),
324 DictionaryBuilder().Set(
326 ListBuilder().Append(
328 .Set("vendorId", 123)
329 .Set("interfaceClass", kPrinterInterfaceClass
)))).Pass();
330 ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_
.get())
331 ->AddEnabled(extension
));
333 InvokeUsbAdded(123, 456, 1);
335 ASSERT_EQ(0u, notification_ui_manager_
.GetNotificationCount());
338 } // namespace chromeos