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.
6 #include "base/message_loop/message_loop.h"
7 #include "base/run_loop.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/test/test_io_thread.h"
10 #include "device/test/usb_test_gadget.h"
11 #include "device/usb/usb_device.h"
12 #include "device/usb/usb_device_handle.h"
13 #include "testing/gtest/include/gtest/gtest.h"
19 class UsbDeviceHandleTest
: public ::testing::Test
{
21 void SetUp() override
{
22 message_loop_
.reset(new base::MessageLoopForUI
);
23 io_thread_
.reset(new base::TestIOThread(base::TestIOThread::kAutoStart
));
27 scoped_ptr
<base::TestIOThread
> io_thread_
;
30 scoped_ptr
<base::MessageLoop
> message_loop_
;
33 class TestOpenCallback
{
37 base::Bind(&TestOpenCallback::SetResult
, base::Unretained(this))) {}
39 scoped_refptr
<UsbDeviceHandle
> WaitForResult() {
41 return device_handle_
;
44 const UsbDevice::OpenCallback
& callback() const { return callback_
; }
47 void SetResult(scoped_refptr
<UsbDeviceHandle
> device_handle
) {
48 device_handle_
= device_handle
;
52 const UsbDevice::OpenCallback callback_
;
53 base::RunLoop run_loop_
;
54 scoped_refptr
<UsbDeviceHandle
> device_handle_
;
57 class TestResultCallback
{
60 : callback_(base::Bind(&TestResultCallback::SetResult
,
61 base::Unretained(this))) {}
63 bool WaitForResult() {
68 const UsbDeviceHandle::ResultCallback
& callback() const { return callback_
; }
71 void SetResult(bool success
) {
76 const UsbDeviceHandle::ResultCallback callback_
;
77 base::RunLoop run_loop_
;
81 class TestCompletionCallback
{
83 TestCompletionCallback()
84 : callback_(base::Bind(&TestCompletionCallback::SetResult
,
85 base::Unretained(this))) {}
87 void WaitForResult() { run_loop_
.Run(); }
89 const UsbDeviceHandle::TransferCallback
& callback() const {
92 UsbTransferStatus
status() const { return status_
; }
93 size_t transferred() const { return transferred_
; }
96 void SetResult(UsbTransferStatus status
,
97 scoped_refptr
<net::IOBuffer
> buffer
,
100 transferred_
= transferred
;
104 const UsbDeviceHandle::TransferCallback callback_
;
105 base::RunLoop run_loop_
;
106 UsbTransferStatus status_
;
110 TEST_F(UsbDeviceHandleTest
, InterruptTransfer
) {
111 if (!UsbTestGadget::IsTestEnabled()) {
115 scoped_ptr
<UsbTestGadget
> gadget
=
116 UsbTestGadget::Claim(io_thread_
->task_runner());
117 ASSERT_TRUE(gadget
.get());
118 ASSERT_TRUE(gadget
->SetType(UsbTestGadget::ECHO
));
120 TestOpenCallback open_device
;
121 gadget
->GetDevice()->Open(open_device
.callback());
122 scoped_refptr
<UsbDeviceHandle
> handle
= open_device
.WaitForResult();
123 ASSERT_TRUE(handle
.get());
125 TestResultCallback claim_interface
;
126 handle
->ClaimInterface(0, claim_interface
.callback());
127 ASSERT_TRUE(claim_interface
.WaitForResult());
129 scoped_refptr
<net::IOBufferWithSize
> in_buffer(new net::IOBufferWithSize(64));
130 TestCompletionCallback in_completion
;
131 handle
->InterruptTransfer(USB_DIRECTION_INBOUND
, 0x81, in_buffer
.get(),
133 5000, // 5 second timeout
134 in_completion
.callback());
136 scoped_refptr
<net::IOBufferWithSize
> out_buffer(
137 new net::IOBufferWithSize(in_buffer
->size()));
138 TestCompletionCallback out_completion
;
139 for (int i
= 0; i
< out_buffer
->size(); ++i
) {
140 out_buffer
->data()[i
] = i
;
143 handle
->InterruptTransfer(USB_DIRECTION_OUTBOUND
, 0x01, out_buffer
.get(),
145 5000, // 5 second timeout
146 out_completion
.callback());
147 out_completion
.WaitForResult();
148 ASSERT_EQ(USB_TRANSFER_COMPLETED
, out_completion
.status());
149 EXPECT_EQ(static_cast<size_t>(out_buffer
->size()),
150 out_completion
.transferred());
152 in_completion
.WaitForResult();
153 ASSERT_EQ(USB_TRANSFER_COMPLETED
, in_completion
.status());
154 EXPECT_EQ(static_cast<size_t>(in_buffer
->size()),
155 in_completion
.transferred());
156 for (size_t i
= 0; i
< in_completion
.transferred(); ++i
) {
157 EXPECT_EQ(out_buffer
->data()[i
], in_buffer
->data()[i
])
158 << "Mismatch at index " << i
<< ".";
164 TEST_F(UsbDeviceHandleTest
, BulkTransfer
) {
165 if (!UsbTestGadget::IsTestEnabled()) {
169 scoped_ptr
<UsbTestGadget
> gadget
=
170 UsbTestGadget::Claim(io_thread_
->task_runner());
171 ASSERT_TRUE(gadget
.get());
172 ASSERT_TRUE(gadget
->SetType(UsbTestGadget::ECHO
));
174 TestOpenCallback open_device
;
175 gadget
->GetDevice()->Open(open_device
.callback());
176 scoped_refptr
<UsbDeviceHandle
> handle
= open_device
.WaitForResult();
177 ASSERT_TRUE(handle
.get());
179 TestResultCallback claim_interface
;
180 handle
->ClaimInterface(1, claim_interface
.callback());
181 ASSERT_TRUE(claim_interface
.WaitForResult());
183 scoped_refptr
<net::IOBufferWithSize
> in_buffer(
184 new net::IOBufferWithSize(512));
185 TestCompletionCallback in_completion
;
186 handle
->BulkTransfer(USB_DIRECTION_INBOUND
, 0x82, in_buffer
.get(),
188 5000, // 5 second timeout
189 in_completion
.callback());
191 scoped_refptr
<net::IOBufferWithSize
> out_buffer(
192 new net::IOBufferWithSize(in_buffer
->size()));
193 TestCompletionCallback out_completion
;
194 for (int i
= 0; i
< out_buffer
->size(); ++i
) {
195 out_buffer
->data()[i
] = i
;
198 handle
->BulkTransfer(USB_DIRECTION_OUTBOUND
, 0x02, out_buffer
.get(),
200 5000, // 5 second timeout
201 out_completion
.callback());
202 out_completion
.WaitForResult();
203 ASSERT_EQ(USB_TRANSFER_COMPLETED
, out_completion
.status());
204 EXPECT_EQ(static_cast<size_t>(out_buffer
->size()),
205 out_completion
.transferred());
207 in_completion
.WaitForResult();
208 ASSERT_EQ(USB_TRANSFER_COMPLETED
, in_completion
.status());
209 EXPECT_EQ(static_cast<size_t>(in_buffer
->size()),
210 in_completion
.transferred());
211 for (size_t i
= 0; i
< in_completion
.transferred(); ++i
) {
212 EXPECT_EQ(out_buffer
->data()[i
], in_buffer
->data()[i
])
213 << "Mismatch at index " << i
<< ".";
219 TEST_F(UsbDeviceHandleTest
, SetInterfaceAlternateSetting
) {
220 if (!UsbTestGadget::IsTestEnabled()) {
224 scoped_ptr
<UsbTestGadget
> gadget
=
225 UsbTestGadget::Claim(io_thread_
->task_runner());
226 ASSERT_TRUE(gadget
.get());
227 ASSERT_TRUE(gadget
->SetType(UsbTestGadget::ECHO
));
229 TestOpenCallback open_device
;
230 gadget
->GetDevice()->Open(open_device
.callback());
231 scoped_refptr
<UsbDeviceHandle
> handle
= open_device
.WaitForResult();
232 ASSERT_TRUE(handle
.get());
234 TestResultCallback claim_interface
;
235 handle
->ClaimInterface(2, claim_interface
.callback());
236 ASSERT_TRUE(claim_interface
.WaitForResult());
238 TestResultCallback set_interface
;
239 handle
->SetInterfaceAlternateSetting(2, 1, set_interface
.callback());
240 ASSERT_TRUE(set_interface
.WaitForResult());
247 } // namespace device