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
]);
163 TEST_F(UsbDeviceHandleTest
, BulkTransfer
) {
164 if (!UsbTestGadget::IsTestEnabled()) {
168 scoped_ptr
<UsbTestGadget
> gadget
=
169 UsbTestGadget::Claim(io_thread_
->task_runner());
170 ASSERT_TRUE(gadget
.get());
171 ASSERT_TRUE(gadget
->SetType(UsbTestGadget::ECHO
));
173 TestOpenCallback open_device
;
174 gadget
->GetDevice()->Open(open_device
.callback());
175 scoped_refptr
<UsbDeviceHandle
> handle
= open_device
.WaitForResult();
176 ASSERT_TRUE(handle
.get());
178 TestResultCallback claim_interface
;
179 handle
->ClaimInterface(1, claim_interface
.callback());
180 ASSERT_TRUE(claim_interface
.WaitForResult());
182 scoped_refptr
<net::IOBufferWithSize
> in_buffer(
183 new net::IOBufferWithSize(512));
184 TestCompletionCallback in_completion
;
185 handle
->BulkTransfer(USB_DIRECTION_INBOUND
, 0x82, in_buffer
.get(),
187 5000, // 5 second timeout
188 in_completion
.callback());
190 scoped_refptr
<net::IOBufferWithSize
> out_buffer(
191 new net::IOBufferWithSize(in_buffer
->size()));
192 TestCompletionCallback out_completion
;
193 for (int i
= 0; i
< out_buffer
->size(); ++i
) {
194 out_buffer
->data()[i
] = i
;
197 handle
->BulkTransfer(USB_DIRECTION_OUTBOUND
, 0x02, out_buffer
.get(),
199 5000, // 5 second timeout
200 out_completion
.callback());
201 out_completion
.WaitForResult();
202 ASSERT_EQ(USB_TRANSFER_COMPLETED
, out_completion
.status());
203 EXPECT_EQ(static_cast<size_t>(out_buffer
->size()),
204 out_completion
.transferred());
206 in_completion
.WaitForResult();
207 ASSERT_EQ(USB_TRANSFER_COMPLETED
, in_completion
.status());
208 EXPECT_EQ(static_cast<size_t>(in_buffer
->size()),
209 in_completion
.transferred());
210 for (size_t i
= 0; i
< in_completion
.transferred(); ++i
) {
211 EXPECT_EQ(out_buffer
->data()[i
], in_buffer
->data()[i
]);
219 } // namespace device