1 // Copyright (c) 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.
9 #include "base/callback.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "device/hid/hid_connection.h"
13 #include "device/hid/hid_service.h"
14 #include "device/test/usb_test_gadget.h"
15 #include "net/base/io_buffer.h"
16 #include "testing/gtest/include/gtest/gtest.h"
22 using net::IOBufferWithSize;
24 class TestConnectCallback {
27 : callback_(base::Bind(&TestConnectCallback::SetConnection,
28 base::Unretained(this))) {}
29 ~TestConnectCallback() {}
31 void SetConnection(scoped_refptr<HidConnection> connection) {
32 connection_ = connection;
36 scoped_refptr<HidConnection> WaitForConnection() {
41 const HidService::ConnectCallback& callback() { return callback_; }
44 HidService::ConnectCallback callback_;
45 base::RunLoop run_loop_;
46 scoped_refptr<HidConnection> connection_;
49 class TestIoCallback {
53 base::Bind(&TestIoCallback::SetReadResult, base::Unretained(this))),
54 write_callback_(base::Bind(&TestIoCallback::SetWriteResult,
55 base::Unretained(this))) {}
58 void SetReadResult(bool success,
59 scoped_refptr<net::IOBuffer> buffer,
67 void SetWriteResult(bool success) {
72 bool WaitForResult() {
77 const HidConnection::ReadCallback& read_callback() { return read_callback_; }
78 const HidConnection::WriteCallback write_callback() {
79 return write_callback_;
81 scoped_refptr<net::IOBuffer> buffer() const { return buffer_; }
82 size_t size() const { return size_; }
85 base::RunLoop run_loop_;
88 scoped_refptr<net::IOBuffer> buffer_;
89 HidConnection::ReadCallback read_callback_;
90 HidConnection::WriteCallback write_callback_;
95 class HidConnectionTest : public testing::Test {
97 void SetUp() override {
98 if (!UsbTestGadget::IsTestEnabled()) return;
100 message_loop_.reset(new base::MessageLoopForIO());
101 service_ = HidService::GetInstance(
102 message_loop_->message_loop_proxy(),
103 message_loop_->message_loop_proxy());
104 ASSERT_TRUE(service_);
106 test_gadget_ = UsbTestGadget::Claim();
107 ASSERT_TRUE(test_gadget_);
108 ASSERT_TRUE(test_gadget_->SetType(UsbTestGadget::HID_ECHO));
110 device_id_ = kInvalidHidDeviceId;
112 base::RunLoop run_loop;
113 message_loop_->PostDelayedTask(
115 base::Bind(&HidConnectionTest::FindDevice,
116 base::Unretained(this), run_loop.QuitClosure(), 5),
117 base::TimeDelta::FromMilliseconds(250));
120 ASSERT_NE(device_id_, kInvalidHidDeviceId);
123 void FindDevice(const base::Closure& done, int retries) {
124 std::vector<HidDeviceInfo> devices;
125 service_->GetDevices(&devices);
127 for (std::vector<HidDeviceInfo>::iterator it = devices.begin();
130 if (it->serial_number == test_gadget_->GetSerialNumber()) {
131 device_id_ = it->device_id;
136 if (device_id_ == kInvalidHidDeviceId && --retries > 0) {
137 message_loop_->PostDelayedTask(
139 base::Bind(&HidConnectionTest::FindDevice, base::Unretained(this),
141 base::TimeDelta::FromMilliseconds(10));
143 message_loop_->PostTask(FROM_HERE, done);
147 scoped_ptr<base::MessageLoopForIO> message_loop_;
148 HidService* service_;
149 scoped_ptr<UsbTestGadget> test_gadget_;
150 HidDeviceId device_id_;
153 TEST_F(HidConnectionTest, ReadWrite) {
154 if (!UsbTestGadget::IsTestEnabled()) return;
156 TestConnectCallback connect_callback;
157 service_->Connect(device_id_, connect_callback.callback());
158 scoped_refptr<HidConnection> conn = connect_callback.WaitForConnection();
159 ASSERT_TRUE(conn.get());
161 const char kBufferSize = 9;
162 for (char i = 0; i < 8; ++i) {
163 scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(kBufferSize));
164 buffer->data()[0] = 0;
165 for (unsigned char j = 1; j < kBufferSize; ++j) {
166 buffer->data()[j] = i + j - 1;
169 TestIoCallback write_callback;
170 conn->Write(buffer, buffer->size(), write_callback.write_callback());
171 ASSERT_TRUE(write_callback.WaitForResult());
173 TestIoCallback read_callback;
174 conn->Read(read_callback.read_callback());
175 ASSERT_TRUE(read_callback.WaitForResult());
176 ASSERT_EQ(9UL, read_callback.size());
177 ASSERT_EQ(0, read_callback.buffer()->data()[0]);
178 for (unsigned char j = 1; j < kBufferSize; ++j) {
179 ASSERT_EQ(i + j - 1, read_callback.buffer()->data()[j]);
186 } // namespace device