Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / usb / usb_apitest.cc
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.
4
5 #include "chrome/browser/extensions/extension_apitest.h"
6 #include "chrome/browser/ui/browser.h"
7 #include "content/public/browser/browser_thread.h"
8 #include "content/public/test/test_utils.h"
9 #include "device/usb/usb_service.h"
10 #include "extensions/browser/api/usb/usb_api.h"
11 #include "net/base/io_buffer.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13
14 using testing::AnyNumber;
15 using testing::_;
16 using testing::Return;
17 using testing::ReturnRef;
18 using content::BrowserThread;
19 using device::UsbConfigDescriptor;
20 using device::UsbDevice;
21 using device::UsbDeviceHandle;
22 using device::UsbEndpointDirection;
23 using device::UsbInterfaceDescriptor;
24 using device::UsbService;
25 using device::UsbTransferCallback;
26
27 namespace {
28
29 ACTION_TEMPLATE(InvokeUsbTransferCallback,
30                 HAS_1_TEMPLATE_PARAMS(int, k),
31                 AND_1_VALUE_PARAMS(p1)) {
32   net::IOBuffer* io_buffer = new net::IOBuffer(1);
33   memset(io_buffer->data(), 0, 1);  // Avoid uninitialized reads.
34   ::std::tr1::get<k>(args).Run(p1, io_buffer, 1);
35 }
36
37 // MSVC erroneously thinks that at least one of the arguments for the transfer
38 // methods differ by const or volatility and emits a warning about the old
39 // standards-noncompliant behaviour of their compiler.
40 #if defined(OS_WIN)
41 #pragma warning(push)
42 #pragma warning(disable : 4373)
43 #endif
44
45 class MockUsbDeviceHandle : public UsbDeviceHandle {
46  public:
47   MockUsbDeviceHandle() : UsbDeviceHandle() {}
48
49   MOCK_METHOD0(Close, void());
50
51   MOCK_METHOD10(ControlTransfer,
52                 void(const UsbEndpointDirection direction,
53                      const TransferRequestType request_type,
54                      const TransferRecipient recipient,
55                      const uint8 request,
56                      const uint16 value,
57                      const uint16 index,
58                      net::IOBuffer* buffer,
59                      const size_t length,
60                      const unsigned int timeout,
61                      const UsbTransferCallback& callback));
62
63   MOCK_METHOD6(BulkTransfer,
64                void(const UsbEndpointDirection direction,
65                     const uint8 endpoint,
66                     net::IOBuffer* buffer,
67                     const size_t length,
68                     const unsigned int timeout,
69                     const UsbTransferCallback& callback));
70
71   MOCK_METHOD6(InterruptTransfer,
72                void(const UsbEndpointDirection direction,
73                     const uint8 endpoint,
74                     net::IOBuffer* buffer,
75                     const size_t length,
76                     const unsigned int timeout,
77                     const UsbTransferCallback& callback));
78
79   MOCK_METHOD8(IsochronousTransfer,
80                void(const UsbEndpointDirection direction,
81                     const uint8 endpoint,
82                     net::IOBuffer* buffer,
83                     const size_t length,
84                     const unsigned int packets,
85                     const unsigned int packet_length,
86                     const unsigned int timeout,
87                     const UsbTransferCallback& callback));
88
89   MOCK_METHOD0(ResetDevice, bool());
90   MOCK_METHOD2(GetStringDescriptor, bool(uint8_t, base::string16*));
91   MOCK_METHOD1(ClaimInterface, bool(const int interface_number));
92   MOCK_METHOD1(ReleaseInterface, bool(const int interface_number));
93   MOCK_METHOD2(SetInterfaceAlternateSetting,
94                bool(const int interface_number, const int alternate_setting));
95
96   virtual scoped_refptr<UsbDevice> GetDevice() const OVERRIDE {
97     return device_;
98   }
99
100   void set_device(UsbDevice* device) { device_ = device; }
101
102  protected:
103   UsbDevice* device_;
104
105   virtual ~MockUsbDeviceHandle() {}
106 };
107
108 class MockUsbDevice : public UsbDevice {
109  public:
110   explicit MockUsbDevice(MockUsbDeviceHandle* mock_handle)
111       : UsbDevice(0, 0, 0), mock_handle_(mock_handle) {
112     mock_handle->set_device(this);
113   }
114
115   virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE {
116     return mock_handle_;
117   }
118
119   virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE {
120     EXPECT_TRUE(false) << "Should not be reached";
121     return false;
122   }
123
124 #if defined(OS_CHROMEOS)
125   virtual void RequestUsbAccess(
126       int interface_id,
127       const base::Callback<void(bool success)>& callback) OVERRIDE {
128     BrowserThread::PostTask(
129           BrowserThread::FILE, FROM_HERE, base::Bind(callback, true));
130   }
131 #endif  // OS_CHROMEOS
132
133   MOCK_METHOD0(GetConfiguration, const UsbConfigDescriptor&());
134   MOCK_METHOD1(GetManufacturer, bool(base::string16* manufacturer));
135   MOCK_METHOD1(GetProduct, bool(base::string16* product));
136   MOCK_METHOD1(GetSerialNumber, bool(base::string16* serial_number));
137
138  private:
139   MockUsbDeviceHandle* mock_handle_;
140   virtual ~MockUsbDevice() {}
141 };
142
143 class MockUsbService : public UsbService {
144  public:
145   explicit MockUsbService(scoped_refptr<UsbDevice> device) : device_(device) {}
146
147  protected:
148   virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE {
149     EXPECT_EQ(unique_id, 0U);
150     return device_;
151   }
152
153   virtual void GetDevices(
154       std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE {
155     STLClearObject(devices);
156     devices->push_back(device_);
157   }
158
159   scoped_refptr<UsbDevice> device_;
160 };
161
162 #if defined(OS_WIN)
163 #pragma warning(pop)
164 #endif
165
166 class UsbApiTest : public ExtensionApiTest {
167  public:
168   virtual void SetUpOnMainThread() OVERRIDE {
169     mock_device_handle_ = new MockUsbDeviceHandle();
170     mock_device_ = new MockUsbDevice(mock_device_handle_.get());
171     scoped_refptr<content::MessageLoopRunner> runner =
172         new content::MessageLoopRunner;
173     BrowserThread::PostTaskAndReply(BrowserThread::FILE,
174                                     FROM_HERE,
175                                     base::Bind(&UsbApiTest::SetUpService, this),
176                                     runner->QuitClosure());
177     runner->Run();
178   }
179
180   void SetUpService() {
181     UsbService::SetInstanceForTest(new MockUsbService(mock_device_));
182   }
183
184   virtual void TearDownOnMainThread() OVERRIDE {
185     scoped_refptr<content::MessageLoopRunner> runner =
186         new content::MessageLoopRunner;
187     UsbService* service = NULL;
188     BrowserThread::PostTaskAndReply(
189         BrowserThread::FILE,
190         FROM_HERE,
191         base::Bind(&UsbService::SetInstanceForTest, service),
192         runner->QuitClosure());
193     runner->Run();
194   }
195
196  protected:
197   scoped_refptr<MockUsbDeviceHandle> mock_device_handle_;
198   scoped_refptr<MockUsbDevice> mock_device_;
199 };
200
201 }  // namespace
202
203 IN_PROC_BROWSER_TEST_F(UsbApiTest, DeviceHandling) {
204   EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(4);
205   ASSERT_TRUE(RunExtensionTest("usb/device_handling"));
206 }
207
208 IN_PROC_BROWSER_TEST_F(UsbApiTest, ResetDevice) {
209   EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(2);
210   EXPECT_CALL(*mock_device_handle_.get(), ResetDevice())
211       .WillOnce(Return(true))
212       .WillOnce(Return(false));
213   EXPECT_CALL(*mock_device_handle_.get(),
214               InterruptTransfer(device::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
215       .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
216   ASSERT_TRUE(RunExtensionTest("usb/reset_device"));
217 }
218
219 IN_PROC_BROWSER_TEST_F(UsbApiTest, ListInterfaces) {
220   UsbConfigDescriptor config_descriptor;
221   EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
222   EXPECT_CALL(*mock_device_.get(), GetConfiguration())
223       .WillOnce(ReturnRef(config_descriptor));
224   ASSERT_TRUE(RunExtensionTest("usb/list_interfaces"));
225 }
226
227 IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferEvent) {
228   EXPECT_CALL(*mock_device_handle_.get(),
229               ControlTransfer(device::USB_DIRECTION_OUTBOUND,
230                               UsbDeviceHandle::STANDARD,
231                               UsbDeviceHandle::DEVICE,
232                               1,
233                               2,
234                               3,
235                               _,
236                               1,
237                               _,
238                               _))
239       .WillOnce(InvokeUsbTransferCallback<9>(device::USB_TRANSFER_COMPLETED));
240   EXPECT_CALL(*mock_device_handle_.get(),
241               BulkTransfer(device::USB_DIRECTION_OUTBOUND, 1, _, 1, _, _))
242       .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
243   EXPECT_CALL(*mock_device_handle_.get(),
244               InterruptTransfer(device::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
245       .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
246   EXPECT_CALL(
247       *mock_device_handle_.get(),
248       IsochronousTransfer(device::USB_DIRECTION_OUTBOUND, 3, _, 1, 1, 1, _, _))
249       .WillOnce(InvokeUsbTransferCallback<7>(device::USB_TRANSFER_COMPLETED));
250   EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
251   ASSERT_TRUE(RunExtensionTest("usb/transfer_event"));
252 }
253
254 IN_PROC_BROWSER_TEST_F(UsbApiTest, ZeroLengthTransfer) {
255   EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, 0, _, _))
256       .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED));
257   EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
258   ASSERT_TRUE(RunExtensionTest("usb/zero_length_transfer"));
259 }
260
261 IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferFailure) {
262   EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, _, _, _))
263       .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED))
264       .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_ERROR))
265       .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_TIMEOUT));
266   EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
267   ASSERT_TRUE(RunExtensionTest("usb/transfer_failure"));
268 }
269
270 IN_PROC_BROWSER_TEST_F(UsbApiTest, InvalidLengthTransfer) {
271   EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
272   ASSERT_TRUE(RunExtensionTest("usb/invalid_length_transfer"));
273 }