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 "device/test/usb_test_gadget.h"
10 #include "device/usb/usb_device.h"
11 #include "device/usb/usb_device_handle.h"
12 #include "testing/gtest/include/gtest/gtest.h"
18 class UsbDeviceHandleTest
: public ::testing::Test
{
20 void SetUp() override
{
21 if (!UsbTestGadget::IsTestEnabled()) {
25 message_loop_
.reset(new base::MessageLoopForIO
);
27 gadget_
= UsbTestGadget::Claim();
28 ASSERT_TRUE(gadget_
.get());
30 ASSERT_TRUE(gadget_
->SetType(UsbTestGadget::ECHO
));
32 handle_
= gadget_
->GetDevice()->Open();
33 ASSERT_TRUE(handle_
.get());
36 void TearDown() override
{
41 message_loop_
.reset(NULL
);
45 scoped_refptr
<UsbDeviceHandle
> handle_
;
48 scoped_ptr
<UsbTestGadget
> gadget_
;
49 scoped_ptr
<base::MessageLoop
> message_loop_
;
52 class TestCompletionCallback
{
54 TestCompletionCallback()
55 : callback_(base::Bind(&TestCompletionCallback::SetResult
,
56 base::Unretained(this))) {}
58 void SetResult(UsbTransferStatus status
,
59 scoped_refptr
<net::IOBuffer
> buffer
,
62 transferred_
= transferred
;
66 void WaitForResult() { run_loop_
.Run(); }
68 const UsbTransferCallback
& callback() const { return callback_
; }
69 UsbTransferStatus
status() const { return status_
; }
70 size_t transferred() const { return transferred_
; }
73 const UsbTransferCallback callback_
;
74 base::RunLoop run_loop_
;
75 UsbTransferStatus status_
;
79 TEST_F(UsbDeviceHandleTest
, InterruptTransfer
) {
84 ASSERT_TRUE(handle_
->ClaimInterface(0));
86 scoped_refptr
<net::IOBufferWithSize
> in_buffer(new net::IOBufferWithSize(64));
87 TestCompletionCallback in_completion
;
88 handle_
->InterruptTransfer(USB_DIRECTION_INBOUND
,
92 5000, // 5 second timeout
93 in_completion
.callback());
95 scoped_refptr
<net::IOBufferWithSize
> out_buffer(
96 new net::IOBufferWithSize(in_buffer
->size()));
97 TestCompletionCallback out_completion
;
98 for (int i
= 0; i
< out_buffer
->size(); ++i
) {
99 out_buffer
->data()[i
] = i
;
102 handle_
->InterruptTransfer(USB_DIRECTION_OUTBOUND
,
106 5000, // 5 second timeout
107 out_completion
.callback());
108 out_completion
.WaitForResult();
109 ASSERT_EQ(USB_TRANSFER_COMPLETED
, out_completion
.status());
110 EXPECT_EQ(static_cast<size_t>(out_buffer
->size()),
111 out_completion
.transferred());
113 in_completion
.WaitForResult();
114 ASSERT_EQ(USB_TRANSFER_COMPLETED
, in_completion
.status());
115 EXPECT_EQ(static_cast<size_t>(in_buffer
->size()),
116 in_completion
.transferred());
117 for (size_t i
= 0; i
< in_completion
.transferred(); ++i
) {
118 EXPECT_EQ(out_buffer
->data()[i
], in_buffer
->data()[i
]);
122 TEST_F(UsbDeviceHandleTest
, BulkTransfer
) {
123 if (!handle_
.get()) {
127 ASSERT_TRUE(handle_
->ClaimInterface(1));
129 scoped_refptr
<net::IOBufferWithSize
> in_buffer(
130 new net::IOBufferWithSize(512));
131 TestCompletionCallback in_completion
;
132 handle_
->BulkTransfer(USB_DIRECTION_INBOUND
, 0x82, in_buffer
.get(),
134 5000, // 5 second timeout
135 in_completion
.callback());
137 scoped_refptr
<net::IOBufferWithSize
> out_buffer(
138 new net::IOBufferWithSize(in_buffer
->size()));
139 TestCompletionCallback out_completion
;
140 for (int i
= 0; i
< out_buffer
->size(); ++i
) {
141 out_buffer
->data()[i
] = i
;
144 handle_
->BulkTransfer(USB_DIRECTION_OUTBOUND
, 0x02, out_buffer
.get(),
146 5000, // 5 second timeout
147 out_completion
.callback());
148 out_completion
.WaitForResult();
149 ASSERT_EQ(USB_TRANSFER_COMPLETED
, out_completion
.status());
150 EXPECT_EQ(static_cast<size_t>(out_buffer
->size()),
151 out_completion
.transferred());
153 in_completion
.WaitForResult();
154 ASSERT_EQ(USB_TRANSFER_COMPLETED
, in_completion
.status());
155 EXPECT_EQ(static_cast<size_t>(in_buffer
->size()),
156 in_completion
.transferred());
157 for (size_t i
= 0; i
< in_completion
.transferred(); ++i
) {
158 EXPECT_EQ(out_buffer
->data()[i
], in_buffer
->data()[i
]);
164 } // namespace device