OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback.h" |
9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
10 #include "base/message_loop/message_loop.h" | 11 #include "base/run_loop.h" |
11 #include "device/hid/hid_connection.h" | 12 #include "device/hid/hid_connection.h" |
12 #include "device/hid/hid_service.h" | 13 #include "device/hid/hid_service.h" |
| 14 #include "device/test/usb_test_gadget.h" |
13 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
15 | 17 |
16 namespace device { | 18 namespace device { |
17 | 19 |
18 namespace { | 20 namespace { |
19 | 21 |
20 using net::IOBufferWithSize; | 22 using net::IOBufferWithSize; |
21 | 23 |
22 const int kUSBLUFADemoVID = 0x03eb; | 24 class TestCompletionCallback { |
23 const int kUSBLUFADemoPID = 0x204f; | 25 public: |
24 const uint64_t kReport = 0x0903a65d030f8ec9ULL; | 26 TestCompletionCallback() |
| 27 : callback_(base::Bind(&TestCompletionCallback::SetResult, |
| 28 base::Unretained(this))) {} |
25 | 29 |
26 int g_read_times = 0; | 30 void SetResult(bool success, size_t size) { |
27 void Read(scoped_refptr<HidConnection> conn); | 31 result_ = success; |
28 | 32 transferred_ = size; |
29 void OnRead(scoped_refptr<HidConnection> conn, | 33 run_loop_.Quit(); |
30 scoped_refptr<IOBufferWithSize> buffer, | |
31 bool success, | |
32 size_t bytes) { | |
33 EXPECT_TRUE(success); | |
34 if (success) { | |
35 g_read_times++; | |
36 EXPECT_EQ(8U, bytes); | |
37 if (bytes == 8) { | |
38 uint64_t* data = reinterpret_cast<uint64_t*>(buffer->data()); | |
39 EXPECT_EQ(kReport, *data); | |
40 } else { | |
41 base::MessageLoop::current()->Quit(); | |
42 } | |
43 } else { | |
44 LOG(ERROR) << "~"; | |
45 g_read_times++; | |
46 } | 34 } |
47 | 35 |
48 if (g_read_times < 3){ | 36 bool WaitForResult() { |
49 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(Read, conn)); | 37 run_loop_.Run(); |
50 } else { | 38 return result_; |
51 base::MessageLoop::current()->Quit(); | |
52 } | 39 } |
53 } | |
54 | 40 |
55 void Read(scoped_refptr<HidConnection> conn) { | 41 const HidConnection::IOCallback& callback() const { return callback_; } |
56 scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(8)); | 42 size_t transferred() const { return transferred_; } |
57 conn->Read(buffer, base::Bind(OnRead, conn, buffer)); | |
58 } | |
59 | 43 |
60 void OnWriteNormal(bool success, | 44 private: |
61 size_t bytes) { | 45 const HidConnection::IOCallback callback_; |
62 ASSERT_TRUE(success); | 46 base::RunLoop run_loop_; |
63 base::MessageLoop::current()->Quit(); | 47 bool result_; |
64 } | 48 size_t transferred_; |
65 | 49 }; |
66 void WriteNormal(scoped_refptr<HidConnection> conn) { | |
67 scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(8)); | |
68 *(int64_t*)buffer->data() = kReport; | |
69 | |
70 conn->Write(0, buffer, base::Bind(OnWriteNormal)); | |
71 } | |
72 | 50 |
73 } // namespace | 51 } // namespace |
74 | 52 |
75 class HidConnectionTest : public testing::Test { | 53 class HidConnectionTest : public testing::Test { |
76 protected: | 54 protected: |
77 virtual void SetUp() OVERRIDE { | 55 virtual void SetUp() OVERRIDE { |
| 56 if (!UsbTestGadget::IsTestEnabled()) return; |
| 57 |
78 message_loop_.reset(new base::MessageLoopForIO()); | 58 message_loop_.reset(new base::MessageLoopForIO()); |
79 service_.reset(HidService::Create(message_loop_->message_loop_proxy())); | 59 service_.reset(HidService::Create(message_loop_->message_loop_proxy())); |
80 ASSERT_TRUE(service_); | 60 ASSERT_TRUE(service_); |
81 | 61 |
| 62 test_gadget_ = UsbTestGadget::Claim(); |
| 63 ASSERT_TRUE(test_gadget_); |
| 64 ASSERT_TRUE(test_gadget_->SetType(UsbTestGadget::HID_ECHO)); |
| 65 |
| 66 device_id_ = kInvalidHidDeviceId; |
| 67 |
| 68 base::RunLoop run_loop; |
| 69 message_loop_->PostDelayedTask( |
| 70 FROM_HERE, |
| 71 base::Bind(&HidConnectionTest::FindDevice, |
| 72 base::Unretained(this), run_loop.QuitClosure(), 5), |
| 73 base::TimeDelta::FromMilliseconds(250)); |
| 74 run_loop.Run(); |
| 75 |
| 76 ASSERT_NE(device_id_, kInvalidHidDeviceId); |
| 77 } |
| 78 |
| 79 void FindDevice(const base::Closure& done, int retries) { |
82 std::vector<HidDeviceInfo> devices; | 80 std::vector<HidDeviceInfo> devices; |
83 service_->GetDevices(&devices); | 81 service_->GetDevices(&devices); |
84 device_id_ = kInvalidHidDeviceId; | 82 |
85 for (std::vector<HidDeviceInfo>::iterator it = devices.begin(); | 83 for (std::vector<HidDeviceInfo>::iterator it = devices.begin(); |
86 it != devices.end(); | 84 it != devices.end(); |
87 ++it) { | 85 ++it) { |
88 if (it->vendor_id == kUSBLUFADemoVID && | 86 if (it->serial_number == test_gadget_->GetSerial()) { |
89 it->product_id == kUSBLUFADemoPID) { | |
90 device_id_ = it->device_id; | 87 device_id_ = it->device_id; |
91 return; | 88 break; |
92 } | 89 } |
93 } | 90 } |
| 91 |
| 92 if (device_id_ == kInvalidHidDeviceId && --retries > 0) { |
| 93 message_loop_->PostDelayedTask( |
| 94 FROM_HERE, |
| 95 base::Bind(&HidConnectionTest::FindDevice, base::Unretained(this), |
| 96 done, retries), |
| 97 base::TimeDelta::FromMilliseconds(10)); |
| 98 } else { |
| 99 message_loop_->PostTask(FROM_HERE, done); |
| 100 } |
94 } | 101 } |
95 | 102 |
96 virtual void TearDown() OVERRIDE { | |
97 service_.reset(NULL); | |
98 message_loop_.reset(NULL); | |
99 } | |
100 | |
101 HidDeviceId device_id_; | |
102 scoped_ptr<base::MessageLoopForIO> message_loop_; | 103 scoped_ptr<base::MessageLoopForIO> message_loop_; |
103 scoped_ptr<HidService> service_; | 104 scoped_ptr<HidService> service_; |
| 105 scoped_ptr<UsbTestGadget> test_gadget_; |
| 106 HidDeviceId device_id_; |
104 }; | 107 }; |
105 | 108 |
106 TEST_F(HidConnectionTest, Create) { | 109 TEST_F(HidConnectionTest, ReadWrite) { |
107 scoped_refptr<HidConnection> connection = service_->Connect(device_id_); | 110 if (!UsbTestGadget::IsTestEnabled()) return; |
108 ASSERT_TRUE(connection || device_id_ == kInvalidHidDeviceId); | |
109 } | |
110 | 111 |
111 TEST_F(HidConnectionTest, Read) { | 112 scoped_refptr<HidConnection> conn = service_->Connect(device_id_); |
112 scoped_refptr<HidConnection> connection = service_->Connect(device_id_); | 113 ASSERT_TRUE(conn); |
113 if (connection) { | 114 |
114 message_loop_->PostTask(FROM_HERE, base::Bind(Read, connection)); | 115 for (int i = 0; i < 8; ++i) { |
115 message_loop_->Run(); | 116 scoped_refptr<IOBufferWithSize> write_buffer(new IOBufferWithSize(8)); |
| 117 *(int64_t*)write_buffer->data() = i; |
| 118 |
| 119 TestCompletionCallback write_callback; |
| 120 conn->Write(0, write_buffer, write_callback.callback()); |
| 121 ASSERT_TRUE(write_callback.WaitForResult()); |
| 122 ASSERT_EQ(8UL, write_callback.transferred()); |
| 123 |
| 124 scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(8)); |
| 125 TestCompletionCallback read_callback; |
| 126 conn->Read(read_buffer, read_callback.callback()); |
| 127 ASSERT_TRUE(read_callback.WaitForResult()); |
| 128 ASSERT_EQ(8UL, read_callback.transferred()); |
| 129 ASSERT_EQ(i, *(int64_t*)read_buffer->data()); |
116 } | 130 } |
117 } | 131 } |
118 | 132 |
119 TEST_F(HidConnectionTest, Write) { | |
120 scoped_refptr<HidConnection> connection = service_->Connect(device_id_); | |
121 | |
122 if (connection) { | |
123 message_loop_->PostTask(FROM_HERE, base::Bind(WriteNormal, connection)); | |
124 message_loop_->Run(); | |
125 } | |
126 } | |
127 | |
128 } // namespace device | 133 } // namespace device |
OLD | NEW |