Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / device / hid / hid_connection_unittest.cc
blob9552aa461123cebe9546c0fda80f68162d805dd6
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.
5 #include <string>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/scoped_observer.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/test_io_thread.h"
15 #include "device/hid/hid_connection.h"
16 #include "device/hid/hid_service.h"
17 #include "device/test/test_device_client.h"
18 #include "device/test/usb_test_gadget.h"
19 #include "device/usb/usb_device.h"
20 #include "net/base/io_buffer.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 namespace device {
25 namespace {
27 using net::IOBufferWithSize;
29 // Helper class that can be used to block until a HID device with a particular
30 // serial number is available. Example usage:
32 // DeviceCatcher device_catcher("ABC123");
33 // HidDeviceId device_id = device_catcher.WaitForDevice();
34 // /* Call HidService::Connect(device_id) to open the device. */
36 class DeviceCatcher : HidService::Observer {
37 public:
38 DeviceCatcher(HidService* hid_service, const base::string16& serial_number)
39 : serial_number_(base::UTF16ToUTF8(serial_number)), observer_(this) {
40 observer_.Add(hid_service);
41 hid_service->GetDevices(base::Bind(&DeviceCatcher::OnEnumerationComplete,
42 base::Unretained(this)));
45 const HidDeviceId& WaitForDevice() {
46 run_loop_.Run();
47 observer_.RemoveAll();
48 return device_id_;
51 private:
52 void OnEnumerationComplete(
53 const std::vector<scoped_refptr<HidDeviceInfo>>& devices) {
54 for (const scoped_refptr<HidDeviceInfo>& device_info : devices) {
55 if (device_info->serial_number() == serial_number_) {
56 device_id_ = device_info->device_id();
57 run_loop_.Quit();
58 break;
63 void OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) override {
64 if (device_info->serial_number() == serial_number_) {
65 device_id_ = device_info->device_id();
66 run_loop_.Quit();
70 std::string serial_number_;
71 ScopedObserver<device::HidService, device::HidService::Observer> observer_;
72 base::RunLoop run_loop_;
73 HidDeviceId device_id_;
76 class TestConnectCallback {
77 public:
78 TestConnectCallback()
79 : callback_(base::Bind(&TestConnectCallback::SetConnection,
80 base::Unretained(this))) {}
81 ~TestConnectCallback() {}
83 void SetConnection(scoped_refptr<HidConnection> connection) {
84 connection_ = connection;
85 run_loop_.Quit();
88 scoped_refptr<HidConnection> WaitForConnection() {
89 run_loop_.Run();
90 return connection_;
93 const HidService::ConnectCallback& callback() { return callback_; }
95 private:
96 HidService::ConnectCallback callback_;
97 base::RunLoop run_loop_;
98 scoped_refptr<HidConnection> connection_;
101 class TestIoCallback {
102 public:
103 TestIoCallback()
104 : read_callback_(
105 base::Bind(&TestIoCallback::SetReadResult, base::Unretained(this))),
106 write_callback_(base::Bind(&TestIoCallback::SetWriteResult,
107 base::Unretained(this))) {}
108 ~TestIoCallback() {}
110 void SetReadResult(bool success,
111 scoped_refptr<net::IOBuffer> buffer,
112 size_t size) {
113 result_ = success;
114 buffer_ = buffer;
115 size_ = size;
116 run_loop_.Quit();
119 void SetWriteResult(bool success) {
120 result_ = success;
121 run_loop_.Quit();
124 bool WaitForResult() {
125 run_loop_.Run();
126 return result_;
129 const HidConnection::ReadCallback& read_callback() { return read_callback_; }
130 const HidConnection::WriteCallback write_callback() {
131 return write_callback_;
133 scoped_refptr<net::IOBuffer> buffer() const { return buffer_; }
134 size_t size() const { return size_; }
136 private:
137 base::RunLoop run_loop_;
138 bool result_;
139 size_t size_;
140 scoped_refptr<net::IOBuffer> buffer_;
141 HidConnection::ReadCallback read_callback_;
142 HidConnection::WriteCallback write_callback_;
145 } // namespace
147 class HidConnectionTest : public testing::Test {
148 protected:
149 void SetUp() override {
150 if (!UsbTestGadget::IsTestEnabled()) return;
152 message_loop_.reset(new base::MessageLoopForUI());
153 io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
154 device_client_.reset(new TestDeviceClient(io_thread_->task_runner()));
156 service_ = DeviceClient::Get()->GetHidService();
157 ASSERT_TRUE(service_);
159 test_gadget_ = UsbTestGadget::Claim(io_thread_->task_runner());
160 ASSERT_TRUE(test_gadget_);
161 ASSERT_TRUE(test_gadget_->SetType(UsbTestGadget::HID_ECHO));
163 DeviceCatcher device_catcher(service_,
164 test_gadget_->GetDevice()->serial_number());
165 device_id_ = device_catcher.WaitForDevice();
166 ASSERT_NE(device_id_, kInvalidHidDeviceId);
169 scoped_ptr<base::MessageLoopForUI> message_loop_;
170 scoped_ptr<base::TestIOThread> io_thread_;
171 scoped_ptr<TestDeviceClient> device_client_;
172 HidService* service_;
173 scoped_ptr<UsbTestGadget> test_gadget_;
174 HidDeviceId device_id_;
177 TEST_F(HidConnectionTest, ReadWrite) {
178 if (!UsbTestGadget::IsTestEnabled()) return;
180 TestConnectCallback connect_callback;
181 service_->Connect(device_id_, connect_callback.callback());
182 scoped_refptr<HidConnection> conn = connect_callback.WaitForConnection();
183 ASSERT_TRUE(conn.get());
185 const char kBufferSize = 9;
186 for (char i = 0; i < 8; ++i) {
187 scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(kBufferSize));
188 buffer->data()[0] = 0;
189 for (unsigned char j = 1; j < kBufferSize; ++j) {
190 buffer->data()[j] = i + j - 1;
193 TestIoCallback write_callback;
194 conn->Write(buffer, buffer->size(), write_callback.write_callback());
195 ASSERT_TRUE(write_callback.WaitForResult());
197 TestIoCallback read_callback;
198 conn->Read(read_callback.read_callback());
199 ASSERT_TRUE(read_callback.WaitForResult());
200 ASSERT_EQ(9UL, read_callback.size());
201 ASSERT_EQ(0, read_callback.buffer()->data()[0]);
202 for (unsigned char j = 1; j < kBufferSize; ++j) {
203 ASSERT_EQ(i + j - 1, read_callback.buffer()->data()[j]);
207 conn->Close();
210 } // namespace device