Unregister from GCM when the only GCM app is removed
[chromium-blink-merge.git] / extensions / browser / api / usb / usb_apitest.cc
blobf436f382f57710f383ad752ba6a015c8a856f63c
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 "chrome/browser/extensions/extension_apitest.h"
6 #include "content/public/browser/browser_thread.h"
7 #include "content/public/test/test_utils.h"
8 #include "device/usb/usb_service.h"
9 #include "extensions/browser/api/device_permissions_prompt.h"
10 #include "extensions/browser/api/usb/usb_api.h"
11 #include "extensions/shell/browser/shell_extensions_api_client.h"
12 #include "extensions/shell/test/shell_apitest.h"
13 #include "extensions/test/extension_test_message_listener.h"
14 #include "net/base/io_buffer.h"
15 #include "testing/gmock/include/gmock/gmock.h"
17 using testing::_;
18 using testing::AnyNumber;
19 using testing::Invoke;
20 using testing::Return;
21 using content::BrowserThread;
22 using device::UsbConfigDescriptor;
23 using device::UsbDevice;
24 using device::UsbDeviceHandle;
25 using device::UsbEndpointDirection;
26 using device::UsbInterfaceDescriptor;
27 using device::UsbService;
28 using device::UsbTransferCallback;
30 namespace extensions {
32 namespace {
34 ACTION_TEMPLATE(InvokeUsbTransferCallback,
35 HAS_1_TEMPLATE_PARAMS(int, k),
36 AND_1_VALUE_PARAMS(p1)) {
37 net::IOBuffer* io_buffer = new net::IOBuffer(1);
38 memset(io_buffer->data(), 0, 1); // Avoid uninitialized reads.
39 ::std::tr1::get<k>(args).Run(p1, io_buffer, 1);
42 void RequestUsbAccess(int interface_id,
43 const base::Callback<void(bool success)>& callback) {
44 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
47 class TestDevicePermissionsPrompt
48 : public DevicePermissionsPrompt,
49 public DevicePermissionsPrompt::Prompt::Observer {
50 public:
51 TestDevicePermissionsPrompt(content::WebContents* web_contents)
52 : DevicePermissionsPrompt(web_contents) {}
54 void ShowDialog() override { prompt()->SetObserver(this); }
56 void OnDevicesChanged() override {
57 std::vector<scoped_refptr<UsbDevice>> devices;
58 for (size_t i = 0; i < prompt()->GetDeviceCount(); ++i) {
59 prompt()->GrantDevicePermission(i);
60 devices.push_back(prompt()->GetDevice(i));
61 if (!prompt()->multiple()) {
62 break;
65 delegate()->OnUsbDevicesChosen(devices);
69 class TestExtensionsAPIClient : public ShellExtensionsAPIClient {
70 public:
71 TestExtensionsAPIClient() : ShellExtensionsAPIClient() {}
73 scoped_ptr<DevicePermissionsPrompt> CreateDevicePermissionsPrompt(
74 content::WebContents* web_contents) const override {
75 return make_scoped_ptr(new TestDevicePermissionsPrompt(web_contents));
79 class MockUsbDeviceHandle : public UsbDeviceHandle {
80 public:
81 MockUsbDeviceHandle() : UsbDeviceHandle() {}
83 MOCK_METHOD0(Close, void());
85 MOCK_METHOD10(ControlTransfer,
86 void(UsbEndpointDirection direction,
87 TransferRequestType request_type,
88 TransferRecipient recipient,
89 uint8 request,
90 uint16 value,
91 uint16 index,
92 net::IOBuffer* buffer,
93 size_t length,
94 unsigned int timeout,
95 const UsbTransferCallback& callback));
97 MOCK_METHOD6(BulkTransfer,
98 void(UsbEndpointDirection direction,
99 uint8 endpoint,
100 net::IOBuffer* buffer,
101 size_t length,
102 unsigned int timeout,
103 const UsbTransferCallback& callback));
105 MOCK_METHOD6(InterruptTransfer,
106 void(UsbEndpointDirection direction,
107 uint8 endpoint,
108 net::IOBuffer* buffer,
109 size_t length,
110 unsigned int timeout,
111 const UsbTransferCallback& callback));
113 MOCK_METHOD8(IsochronousTransfer,
114 void(UsbEndpointDirection direction,
115 uint8 endpoint,
116 net::IOBuffer* buffer,
117 size_t length,
118 unsigned int packets,
119 unsigned int packet_length,
120 unsigned int timeout,
121 const UsbTransferCallback& callback));
123 MOCK_METHOD0(ResetDevice, bool());
124 MOCK_METHOD2(GetStringDescriptor, bool(uint8_t, base::string16*));
125 MOCK_METHOD1(SetConfiguration, bool(int));
126 MOCK_METHOD1(ClaimInterface, bool(int interface_number));
127 MOCK_METHOD1(ReleaseInterface, bool(int interface_number));
128 MOCK_METHOD2(SetInterfaceAlternateSetting,
129 bool(int interface_number, int alternate_setting));
131 virtual scoped_refptr<UsbDevice> GetDevice() const override {
132 return device_;
135 void set_device(UsbDevice* device) { device_ = device; }
137 protected:
138 UsbDevice* device_;
140 virtual ~MockUsbDeviceHandle() {}
143 class MockUsbDevice : public UsbDevice {
144 public:
145 MockUsbDevice(uint16 vendor_id, uint16 product_id, uint32 unique_id)
146 : UsbDevice(vendor_id, product_id, unique_id) {}
148 MOCK_METHOD2(RequestUsbAccess, void(int, const base::Callback<void(bool)>&));
149 MOCK_METHOD0(Open, scoped_refptr<UsbDeviceHandle>());
150 MOCK_METHOD1(Close, bool(scoped_refptr<UsbDeviceHandle>));
151 MOCK_METHOD0(GetConfiguration, const device::UsbConfigDescriptor*());
152 MOCK_METHOD1(GetManufacturer, bool(base::string16*));
153 MOCK_METHOD1(GetProduct, bool(base::string16*));
154 MOCK_METHOD1(GetSerialNumber, bool(base::string16*));
156 private:
157 virtual ~MockUsbDevice() {}
160 class MockUsbService : public UsbService {
161 public:
162 explicit MockUsbService(scoped_refptr<UsbDevice> device) : device_(device) {}
164 // Public wrapper around the protected base class method.
165 void NotifyDeviceAdded(scoped_refptr<UsbDevice> device) {
166 UsbService::NotifyDeviceAdded(device);
169 // Public wrapper around the protected base class method.
170 void NotifyDeviceRemoved(scoped_refptr<UsbDevice> device) {
171 UsbService::NotifyDeviceRemoved(device);
174 protected:
175 scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) override {
176 EXPECT_EQ(unique_id, 0U);
177 return device_;
180 void GetDevices(std::vector<scoped_refptr<UsbDevice>>* devices) override {
181 STLClearObject(devices);
182 devices->push_back(device_);
185 scoped_refptr<UsbDevice> device_;
188 class UsbApiTest : public ShellApiTest {
189 public:
190 void SetUpOnMainThread() override {
191 ShellApiTest::SetUpOnMainThread();
193 mock_device_ = new MockUsbDevice(0, 0, 0);
194 EXPECT_CALL(*mock_device_.get(), GetManufacturer(_))
195 .WillRepeatedly(Return(false));
196 EXPECT_CALL(*mock_device_.get(), GetProduct(_))
197 .WillRepeatedly(Return(false));
198 EXPECT_CALL(*mock_device_.get(), GetSerialNumber(_))
199 .WillRepeatedly(Return(false));
201 mock_device_handle_ = new MockUsbDeviceHandle();
202 mock_device_handle_->set_device(mock_device_.get());
203 EXPECT_CALL(*mock_device_.get(), RequestUsbAccess(_, _))
204 .WillRepeatedly(Invoke(RequestUsbAccess));
205 EXPECT_CALL(*mock_device_.get(), Open())
206 .WillRepeatedly(Return(mock_device_handle_));
208 base::RunLoop run_loop;
209 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
210 base::Bind(&UsbApiTest::SetUpService, this),
211 run_loop.QuitClosure());
212 run_loop.Run();
215 void SetUpService() {
216 mock_service_ = new MockUsbService(mock_device_);
217 UsbService::SetInstanceForTest(mock_service_);
220 void AddTestDevices() {
221 scoped_refptr<MockUsbDevice> device(new MockUsbDevice(0x18D1, 0x58F0, 1));
222 EXPECT_CALL(*device.get(), GetSerialNumber(_))
223 .WillRepeatedly(Return(false));
224 mock_service_->NotifyDeviceAdded(device);
226 device = new MockUsbDevice(0x18D1, 0x58F1, 2);
227 EXPECT_CALL(*device.get(), GetSerialNumber(_))
228 .WillRepeatedly(Return(false));
229 mock_service_->NotifyDeviceAdded(device);
232 protected:
233 scoped_refptr<MockUsbDeviceHandle> mock_device_handle_;
234 scoped_refptr<MockUsbDevice> mock_device_;
235 MockUsbService* mock_service_;
238 } // namespace
240 IN_PROC_BROWSER_TEST_F(UsbApiTest, DeviceHandling) {
241 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(2);
242 ASSERT_TRUE(RunAppTest("api_test/usb/device_handling"));
245 IN_PROC_BROWSER_TEST_F(UsbApiTest, ResetDevice) {
246 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(2);
247 EXPECT_CALL(*mock_device_handle_.get(), ResetDevice())
248 .WillOnce(Return(true))
249 .WillOnce(Return(false));
250 EXPECT_CALL(*mock_device_handle_.get(),
251 InterruptTransfer(device::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
252 .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
253 ASSERT_TRUE(RunAppTest("api_test/usb/reset_device"));
256 IN_PROC_BROWSER_TEST_F(UsbApiTest, SetConfiguration) {
257 UsbConfigDescriptor config_descriptor;
258 EXPECT_CALL(*mock_device_handle_.get(), SetConfiguration(1))
259 .WillOnce(Return(true));
260 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(1);
261 EXPECT_CALL(*mock_device_.get(), GetConfiguration())
262 .WillOnce(Return(nullptr))
263 .WillOnce(Return(&config_descriptor));
264 ASSERT_TRUE(RunAppTest("api_test/usb/set_configuration"));
267 IN_PROC_BROWSER_TEST_F(UsbApiTest, ListInterfaces) {
268 UsbConfigDescriptor config_descriptor;
269 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(1);
270 EXPECT_CALL(*mock_device_.get(), GetConfiguration())
271 .WillOnce(Return(&config_descriptor));
272 ASSERT_TRUE(RunAppTest("api_test/usb/list_interfaces"));
275 IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferEvent) {
276 EXPECT_CALL(*mock_device_handle_.get(),
277 ControlTransfer(device::USB_DIRECTION_OUTBOUND,
278 UsbDeviceHandle::STANDARD,
279 UsbDeviceHandle::DEVICE,
287 .WillOnce(InvokeUsbTransferCallback<9>(device::USB_TRANSFER_COMPLETED));
288 EXPECT_CALL(*mock_device_handle_.get(),
289 BulkTransfer(device::USB_DIRECTION_OUTBOUND, 1, _, 1, _, _))
290 .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
291 EXPECT_CALL(*mock_device_handle_.get(),
292 InterruptTransfer(device::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
293 .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
294 EXPECT_CALL(
295 *mock_device_handle_.get(),
296 IsochronousTransfer(device::USB_DIRECTION_OUTBOUND, 3, _, 1, 1, 1, _, _))
297 .WillOnce(InvokeUsbTransferCallback<7>(device::USB_TRANSFER_COMPLETED));
298 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
299 ASSERT_TRUE(RunAppTest("api_test/usb/transfer_event"));
302 IN_PROC_BROWSER_TEST_F(UsbApiTest, ZeroLengthTransfer) {
303 EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, 0, _, _))
304 .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
305 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
306 ASSERT_TRUE(RunAppTest("api_test/usb/zero_length_transfer"));
309 IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferFailure) {
310 EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, _, _, _))
311 .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED))
312 .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_ERROR))
313 .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_TIMEOUT));
314 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
315 ASSERT_TRUE(RunAppTest("api_test/usb/transfer_failure"));
318 IN_PROC_BROWSER_TEST_F(UsbApiTest, InvalidLengthTransfer) {
319 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
320 ASSERT_TRUE(RunAppTest("api_test/usb/invalid_length_transfer"));
323 IN_PROC_BROWSER_TEST_F(UsbApiTest, OnDeviceAdded) {
324 ExtensionTestMessageListener load_listener("loaded", false);
325 ExtensionTestMessageListener result_listener("success", false);
326 result_listener.set_failure_message("failure");
328 ASSERT_TRUE(LoadApp("api_test/usb/add_event"));
329 ASSERT_TRUE(load_listener.WaitUntilSatisfied());
331 base::RunLoop run_loop;
332 BrowserThread::PostTaskAndReply(
333 BrowserThread::FILE, FROM_HERE,
334 base::Bind(&UsbApiTest::AddTestDevices, base::Unretained(this)),
335 run_loop.QuitClosure());
336 run_loop.Run();
338 ASSERT_TRUE(result_listener.WaitUntilSatisfied());
341 IN_PROC_BROWSER_TEST_F(UsbApiTest, OnDeviceRemoved) {
342 ExtensionTestMessageListener load_listener("loaded", false);
343 ExtensionTestMessageListener result_listener("success", false);
344 result_listener.set_failure_message("failure");
346 ASSERT_TRUE(LoadApp("api_test/usb/remove_event"));
347 ASSERT_TRUE(load_listener.WaitUntilSatisfied());
349 base::RunLoop run_loop;
350 BrowserThread::PostTaskAndReply(
351 BrowserThread::FILE, FROM_HERE,
352 base::Bind(&MockUsbService::NotifyDeviceRemoved,
353 base::Unretained(mock_service_), mock_device_),
354 run_loop.QuitClosure());
355 run_loop.Run();
357 ASSERT_TRUE(result_listener.WaitUntilSatisfied());
360 IN_PROC_BROWSER_TEST_F(UsbApiTest, GetUserSelectedDevices) {
361 ExtensionTestMessageListener ready_listener("opened_device", false);
362 ExtensionTestMessageListener result_listener("success", false);
363 result_listener.set_failure_message("failure");
365 EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(1);
367 TestExtensionsAPIClient test_api_client;
368 ASSERT_TRUE(LoadApp("api_test/usb/get_user_selected_devices"));
369 ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
371 base::RunLoop run_loop;
372 BrowserThread::PostTaskAndReply(
373 BrowserThread::FILE, FROM_HERE,
374 base::Bind(&MockUsbService::NotifyDeviceRemoved,
375 base::Unretained(mock_service_), mock_device_),
376 run_loop.QuitClosure());
377 run_loop.Run();
379 ASSERT_TRUE(result_listener.WaitUntilSatisfied());
382 } // namespace extensions