blob: 5fac40a55e7c82ef090fb22e2ae54a2e5834bf9d [file] [log] [blame]
reillygee658b72014-09-04 19:40:301// 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
avi176e2692015-12-22 19:26:525#include <stddef.h>
6
reillygee658b72014-09-04 19:40:307#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "base/run_loop.h"
10#include "base/strings/utf_string_conversions.h"
reillygb87cb272015-04-16 19:11:0411#include "base/test/test_io_thread.h"
reillygbadbc5412015-08-28 23:08:1012#include "device/test/test_device_client.h"
reillygee658b72014-09-04 19:40:3013#include "device/test/usb_test_gadget.h"
14#include "device/usb/usb_device.h"
15#include "device/usb/usb_device_handle.h"
reillyga9de0fa2016-01-28 01:38:0116#include "net/base/io_buffer.h"
reillygee658b72014-09-04 19:40:3017#include "testing/gtest/include/gtest/gtest.h"
18
19namespace device {
20
21namespace {
22
23class UsbDeviceHandleTest : public ::testing::Test {
24 public:
dcheng07c34a12014-10-29 18:55:1025 void SetUp() override {
reillygb87cb272015-04-16 19:11:0426 message_loop_.reset(new base::MessageLoopForUI);
27 io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
reillygbadbc5412015-08-28 23:08:1028 device_client_.reset(new TestDeviceClient(io_thread_->task_runner()));
reillygee658b72014-09-04 19:40:3029 }
30
31 protected:
reillygb87cb272015-04-16 19:11:0432 scoped_ptr<base::TestIOThread> io_thread_;
reillygee658b72014-09-04 19:40:3033
34 private:
reillygee658b72014-09-04 19:40:3035 scoped_ptr<base::MessageLoop> message_loop_;
reillygbadbc5412015-08-28 23:08:1036 scoped_ptr<TestDeviceClient> device_client_;
reillygee658b72014-09-04 19:40:3037};
38
reillygb87cb272015-04-16 19:11:0439class TestOpenCallback {
40 public:
41 TestOpenCallback()
42 : callback_(
43 base::Bind(&TestOpenCallback::SetResult, base::Unretained(this))) {}
44
45 scoped_refptr<UsbDeviceHandle> WaitForResult() {
46 run_loop_.Run();
47 return device_handle_;
48 }
49
50 const UsbDevice::OpenCallback& callback() const { return callback_; }
51
52 private:
53 void SetResult(scoped_refptr<UsbDeviceHandle> device_handle) {
54 device_handle_ = device_handle;
55 run_loop_.Quit();
56 }
57
58 const UsbDevice::OpenCallback callback_;
59 base::RunLoop run_loop_;
60 scoped_refptr<UsbDeviceHandle> device_handle_;
61};
62
63class TestResultCallback {
64 public:
65 TestResultCallback()
66 : callback_(base::Bind(&TestResultCallback::SetResult,
67 base::Unretained(this))) {}
68
69 bool WaitForResult() {
70 run_loop_.Run();
71 return success_;
72 }
73
74 const UsbDeviceHandle::ResultCallback& callback() const { return callback_; }
75
76 private:
77 void SetResult(bool success) {
78 success_ = success;
79 run_loop_.Quit();
80 }
81
82 const UsbDeviceHandle::ResultCallback callback_;
83 base::RunLoop run_loop_;
84 bool success_;
85};
86
reillygee658b72014-09-04 19:40:3087class TestCompletionCallback {
88 public:
89 TestCompletionCallback()
90 : callback_(base::Bind(&TestCompletionCallback::SetResult,
91 base::Unretained(this))) {}
92
reillygb87cb272015-04-16 19:11:0493 void WaitForResult() { run_loop_.Run(); }
94
95 const UsbDeviceHandle::TransferCallback& callback() const {
96 return callback_;
97 }
98 UsbTransferStatus status() const { return status_; }
99 size_t transferred() const { return transferred_; }
100
101 private:
reillygee658b72014-09-04 19:40:30102 void SetResult(UsbTransferStatus status,
103 scoped_refptr<net::IOBuffer> buffer,
104 size_t transferred) {
105 status_ = status;
106 transferred_ = transferred;
107 run_loop_.Quit();
108 }
109
reillygb87cb272015-04-16 19:11:04110 const UsbDeviceHandle::TransferCallback callback_;
reillygee658b72014-09-04 19:40:30111 base::RunLoop run_loop_;
112 UsbTransferStatus status_;
113 size_t transferred_;
114};
115
116TEST_F(UsbDeviceHandleTest, InterruptTransfer) {
reillygb87cb272015-04-16 19:11:04117 if (!UsbTestGadget::IsTestEnabled()) {
reillygee658b72014-09-04 19:40:30118 return;
119 }
120
reillygb87cb272015-04-16 19:11:04121 scoped_ptr<UsbTestGadget> gadget =
122 UsbTestGadget::Claim(io_thread_->task_runner());
123 ASSERT_TRUE(gadget.get());
124 ASSERT_TRUE(gadget->SetType(UsbTestGadget::ECHO));
125
126 TestOpenCallback open_device;
127 gadget->GetDevice()->Open(open_device.callback());
128 scoped_refptr<UsbDeviceHandle> handle = open_device.WaitForResult();
129 ASSERT_TRUE(handle.get());
130
131 TestResultCallback claim_interface;
132 handle->ClaimInterface(0, claim_interface.callback());
133 ASSERT_TRUE(claim_interface.WaitForResult());
reillyg67650d62014-12-13 01:18:52134
reillygee658b72014-09-04 19:40:30135 scoped_refptr<net::IOBufferWithSize> in_buffer(new net::IOBufferWithSize(64));
136 TestCompletionCallback in_completion;
juncaie03494ff2015-09-03 20:06:23137 handle->GenericTransfer(USB_DIRECTION_INBOUND, 0x81, in_buffer.get(),
138 in_buffer->size(),
139 5000, // 5 second timeout
140 in_completion.callback());
reillygee658b72014-09-04 19:40:30141
142 scoped_refptr<net::IOBufferWithSize> out_buffer(
143 new net::IOBufferWithSize(in_buffer->size()));
144 TestCompletionCallback out_completion;
145 for (int i = 0; i < out_buffer->size(); ++i) {
146 out_buffer->data()[i] = i;
147 }
148
juncaie03494ff2015-09-03 20:06:23149 handle->GenericTransfer(USB_DIRECTION_OUTBOUND, 0x01, out_buffer.get(),
150 out_buffer->size(),
151 5000, // 5 second timeout
152 out_completion.callback());
reillygee658b72014-09-04 19:40:30153 out_completion.WaitForResult();
154 ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status());
reillyg67650d62014-12-13 01:18:52155 EXPECT_EQ(static_cast<size_t>(out_buffer->size()),
reillygee658b72014-09-04 19:40:30156 out_completion.transferred());
157
158 in_completion.WaitForResult();
159 ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status());
reillyg67650d62014-12-13 01:18:52160 EXPECT_EQ(static_cast<size_t>(in_buffer->size()),
reillygee658b72014-09-04 19:40:30161 in_completion.transferred());
reillyg67650d62014-12-13 01:18:52162 for (size_t i = 0; i < in_completion.transferred(); ++i) {
reillyg631048ab2015-07-06 21:27:47163 EXPECT_EQ(out_buffer->data()[i], in_buffer->data()[i])
164 << "Mismatch at index " << i << ".";
reillygee658b72014-09-04 19:40:30165 }
reillygb87cb272015-04-16 19:11:04166
reillyg6bc4255e2016-02-04 22:45:36167 TestResultCallback release_interface;
168 handle->ReleaseInterface(0, release_interface.callback());
169 ASSERT_TRUE(release_interface.WaitForResult());
170
reillygb87cb272015-04-16 19:11:04171 handle->Close();
reillygee658b72014-09-04 19:40:30172}
173
174TEST_F(UsbDeviceHandleTest, BulkTransfer) {
reillygb87cb272015-04-16 19:11:04175 if (!UsbTestGadget::IsTestEnabled()) {
reillygee658b72014-09-04 19:40:30176 return;
177 }
178
reillygb87cb272015-04-16 19:11:04179 scoped_ptr<UsbTestGadget> gadget =
180 UsbTestGadget::Claim(io_thread_->task_runner());
181 ASSERT_TRUE(gadget.get());
182 ASSERT_TRUE(gadget->SetType(UsbTestGadget::ECHO));
183
184 TestOpenCallback open_device;
185 gadget->GetDevice()->Open(open_device.callback());
186 scoped_refptr<UsbDeviceHandle> handle = open_device.WaitForResult();
187 ASSERT_TRUE(handle.get());
188
189 TestResultCallback claim_interface;
190 handle->ClaimInterface(1, claim_interface.callback());
191 ASSERT_TRUE(claim_interface.WaitForResult());
reillyg67650d62014-12-13 01:18:52192
reillygee658b72014-09-04 19:40:30193 scoped_refptr<net::IOBufferWithSize> in_buffer(
194 new net::IOBufferWithSize(512));
195 TestCompletionCallback in_completion;
juncaie03494ff2015-09-03 20:06:23196 handle->GenericTransfer(USB_DIRECTION_INBOUND, 0x82, in_buffer.get(),
197 in_buffer->size(),
198 5000, // 5 second timeout
199 in_completion.callback());
reillygee658b72014-09-04 19:40:30200
201 scoped_refptr<net::IOBufferWithSize> out_buffer(
202 new net::IOBufferWithSize(in_buffer->size()));
203 TestCompletionCallback out_completion;
204 for (int i = 0; i < out_buffer->size(); ++i) {
205 out_buffer->data()[i] = i;
206 }
207
juncaie03494ff2015-09-03 20:06:23208 handle->GenericTransfer(USB_DIRECTION_OUTBOUND, 0x02, out_buffer.get(),
209 out_buffer->size(),
210 5000, // 5 second timeout
211 out_completion.callback());
reillygee658b72014-09-04 19:40:30212 out_completion.WaitForResult();
213 ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status());
reillyg67650d62014-12-13 01:18:52214 EXPECT_EQ(static_cast<size_t>(out_buffer->size()),
reillygee658b72014-09-04 19:40:30215 out_completion.transferred());
216
217 in_completion.WaitForResult();
218 ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status());
reillyg67650d62014-12-13 01:18:52219 EXPECT_EQ(static_cast<size_t>(in_buffer->size()),
reillygee658b72014-09-04 19:40:30220 in_completion.transferred());
reillyg67650d62014-12-13 01:18:52221 for (size_t i = 0; i < in_completion.transferred(); ++i) {
reillyg631048ab2015-07-06 21:27:47222 EXPECT_EQ(out_buffer->data()[i], in_buffer->data()[i])
223 << "Mismatch at index " << i << ".";
reillygee658b72014-09-04 19:40:30224 }
reillygb87cb272015-04-16 19:11:04225
reillyg6bc4255e2016-02-04 22:45:36226 TestResultCallback release_interface;
227 handle->ReleaseInterface(1, release_interface.callback());
228 ASSERT_TRUE(release_interface.WaitForResult());
229
reillygb87cb272015-04-16 19:11:04230 handle->Close();
reillygee658b72014-09-04 19:40:30231}
232
reillyg631048ab2015-07-06 21:27:47233TEST_F(UsbDeviceHandleTest, SetInterfaceAlternateSetting) {
234 if (!UsbTestGadget::IsTestEnabled()) {
235 return;
236 }
237
238 scoped_ptr<UsbTestGadget> gadget =
239 UsbTestGadget::Claim(io_thread_->task_runner());
240 ASSERT_TRUE(gadget.get());
241 ASSERT_TRUE(gadget->SetType(UsbTestGadget::ECHO));
242
243 TestOpenCallback open_device;
244 gadget->GetDevice()->Open(open_device.callback());
245 scoped_refptr<UsbDeviceHandle> handle = open_device.WaitForResult();
246 ASSERT_TRUE(handle.get());
247
248 TestResultCallback claim_interface;
249 handle->ClaimInterface(2, claim_interface.callback());
250 ASSERT_TRUE(claim_interface.WaitForResult());
251
252 TestResultCallback set_interface;
253 handle->SetInterfaceAlternateSetting(2, 1, set_interface.callback());
254 ASSERT_TRUE(set_interface.WaitForResult());
255
reillyg6bc4255e2016-02-04 22:45:36256 TestResultCallback release_interface;
257 handle->ReleaseInterface(2, release_interface.callback());
258 ASSERT_TRUE(release_interface.WaitForResult());
259
reillyg631048ab2015-07-06 21:27:47260 handle->Close();
261}
262
reillygee658b72014-09-04 19:40:30263} // namespace
264
265} // namespace device