Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / device / devices_app / usb / device_impl_unittest.cc
blob5868a17b55de5ea6434a3b5c24eb8882c915ecce
1 // Copyright 2015 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 <map>
6 #include <queue>
7 #include <set>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/macros.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/stl_util.h"
15 #include "device/devices_app/usb/device_impl.h"
16 #include "device/usb/mock_usb_device.h"
17 #include "device/usb/mock_usb_device_handle.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
21 using ::testing::Invoke;
22 using ::testing::_;
24 namespace device {
25 namespace usb {
27 namespace {
29 class ConfigBuilder {
30 public:
31 ConfigBuilder(uint8_t value) { config_.configuration_value = value; }
33 ConfigBuilder& AddInterface(uint8_t interface_number,
34 uint8_t alternate_setting,
35 uint8_t class_code,
36 uint8_t subclass_code,
37 uint8_t protocol_code) {
38 UsbInterfaceDescriptor interface;
39 interface.interface_number = interface_number;
40 interface.alternate_setting = alternate_setting;
41 interface.interface_class = class_code;
42 interface.interface_subclass = subclass_code;
43 interface.interface_protocol = protocol_code;
44 config_.interfaces.push_back(interface);
45 return *this;
48 const UsbConfigDescriptor& config() const { return config_; }
50 private:
51 UsbConfigDescriptor config_;
54 void ExpectOpenAndThen(OpenDeviceError expected,
55 const base::Closure& continuation,
56 OpenDeviceError error) {
57 EXPECT_EQ(expected, error);
58 continuation.Run();
61 void ExpectDeviceInfoAndThen(const std::string& guid,
62 uint16_t vendor_id,
63 uint16_t product_id,
64 const std::string& manufacturer_name,
65 const std::string& product_name,
66 const std::string& serial_number,
67 const base::Closure& continuation,
68 DeviceInfoPtr device_info) {
69 EXPECT_EQ(guid, device_info->guid);
70 EXPECT_EQ(vendor_id, device_info->vendor_id);
71 EXPECT_EQ(product_id, device_info->product_id);
72 EXPECT_EQ(manufacturer_name, device_info->manufacturer_name);
73 EXPECT_EQ(product_name, device_info->product_name);
74 EXPECT_EQ(serial_number, device_info->serial_number);
75 continuation.Run();
78 void ExpectResultAndThen(bool expected_result,
79 const base::Closure& continuation,
80 bool actual_result) {
81 EXPECT_EQ(expected_result, actual_result);
82 continuation.Run();
85 void ExpectTransferInAndThen(TransferStatus expected_status,
86 const std::vector<uint8_t>& expected_bytes,
87 const base::Closure& continuation,
88 TransferStatus actual_status,
89 mojo::Array<uint8_t> actual_bytes) {
90 EXPECT_EQ(expected_status, actual_status);
91 ASSERT_EQ(expected_bytes.size(), actual_bytes.size());
92 for (size_t i = 0; i < actual_bytes.size(); ++i) {
93 EXPECT_EQ(expected_bytes[i], actual_bytes[i])
94 << "Contents differ at index: " << i;
96 continuation.Run();
99 void ExpectPacketsAndThen(
100 TransferStatus expected_status,
101 const std::vector<std::vector<uint8_t>>& expected_packets,
102 const base::Closure& continuation,
103 TransferStatus actual_status,
104 mojo::Array<mojo::Array<uint8_t>> actual_packets) {
105 EXPECT_EQ(expected_status, actual_status);
106 ASSERT_EQ(expected_packets.size(), actual_packets.size());
107 for (size_t i = 0; i < expected_packets.size(); ++i) {
108 EXPECT_EQ(expected_packets[i].size(), actual_packets[i].size())
109 << "Packet sizes differ at index: " << i;
110 for (size_t j = 0; j < expected_packets[i].size(); ++j) {
111 EXPECT_EQ(expected_packets[i][j], actual_packets[i][j])
112 << "Contents of packet " << i << " differ at index " << j;
115 continuation.Run();
118 void ExpectTransferStatusAndThen(TransferStatus expected_status,
119 const base::Closure& continuation,
120 TransferStatus actual_status) {
121 EXPECT_EQ(expected_status, actual_status);
122 continuation.Run();
125 class USBDeviceImplTest : public testing::Test {
126 public:
127 USBDeviceImplTest()
128 : message_loop_(new base::MessageLoop),
129 is_device_open_(false),
130 allow_reset_(false),
131 current_config_(0) {}
133 ~USBDeviceImplTest() override {}
135 protected:
136 MockUsbDevice& mock_device() { return *mock_device_.get(); }
137 bool is_device_open() const { return is_device_open_; }
138 MockUsbDeviceHandle& mock_handle() { return *mock_handle_.get(); }
140 void set_allow_reset(bool allow_reset) { allow_reset_ = allow_reset; }
142 // Creates a mock device and binds a Device proxy to a Device service impl
143 // wrapping the mock device.
144 DevicePtr GetMockDeviceProxy(uint16_t vendor_id,
145 uint16_t product_id,
146 const std::string& manufacturer,
147 const std::string& product,
148 const std::string& serial) {
149 mock_device_ =
150 new MockUsbDevice(vendor_id, product_id, manufacturer, product, serial);
151 mock_handle_ = new MockUsbDeviceHandle(mock_device_.get());
153 DevicePtr proxy;
154 new DeviceImpl(mock_device_, mojo::GetProxy(&proxy));
156 // Set up mock handle calls to respond based on mock device configs
157 // established by the test.
158 ON_CALL(mock_device(), Open(_))
159 .WillByDefault(Invoke(this, &USBDeviceImplTest::OpenMockHandle));
160 ON_CALL(mock_handle(), Close())
161 .WillByDefault(Invoke(this, &USBDeviceImplTest::CloseMockHandle));
162 ON_CALL(mock_handle(), SetConfiguration(_, _))
163 .WillByDefault(Invoke(this, &USBDeviceImplTest::SetConfiguration));
164 ON_CALL(mock_handle(), ClaimInterface(_, _))
165 .WillByDefault(Invoke(this, &USBDeviceImplTest::ClaimInterface));
166 ON_CALL(mock_handle(), ReleaseInterface(_))
167 .WillByDefault(Invoke(this, &USBDeviceImplTest::ReleaseInterface));
168 ON_CALL(mock_handle(), SetInterfaceAlternateSetting(_, _, _))
169 .WillByDefault(
170 Invoke(this, &USBDeviceImplTest::SetInterfaceAlternateSetting));
171 ON_CALL(mock_handle(), ResetDevice(_))
172 .WillByDefault(Invoke(this, &USBDeviceImplTest::ResetDevice));
173 ON_CALL(mock_handle(), ControlTransfer(_, _, _, _, _, _, _, _, _, _))
174 .WillByDefault(Invoke(this, &USBDeviceImplTest::ControlTransfer));
175 ON_CALL(mock_handle(), GenericTransfer(_, _, _, _, _, _))
176 .WillByDefault(Invoke(this, &USBDeviceImplTest::GenericTransfer));
177 ON_CALL(mock_handle(), IsochronousTransfer(_, _, _, _, _, _, _, _))
178 .WillByDefault(Invoke(this, &USBDeviceImplTest::IsochronousTransfer));
180 return proxy.Pass();
183 DevicePtr GetMockDeviceProxy() {
184 return GetMockDeviceProxy(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");
187 void AddMockConfig(const ConfigBuilder& builder) {
188 const UsbConfigDescriptor& config = builder.config();
189 DCHECK(!ContainsKey(mock_configs_, config.configuration_value));
190 mock_configs_[config.configuration_value] = config;
193 void AddMockInboundData(const std::vector<uint8_t>& data) {
194 mock_inbound_data_.push(data);
197 void AddMockOutboundData(const std::vector<uint8_t>& data) {
198 mock_outbound_data_.push(data);
201 private:
202 void OpenMockHandle(const UsbDevice::OpenCallback& callback) {
203 EXPECT_FALSE(is_device_open_);
204 is_device_open_ = true;
205 callback.Run(mock_handle_);
208 void CloseMockHandle() {
209 EXPECT_TRUE(is_device_open_);
210 is_device_open_ = false;
213 void SetConfiguration(uint8_t value,
214 const UsbDeviceHandle::ResultCallback& callback) {
215 if (mock_configs_.find(value) != mock_configs_.end()) {
216 current_config_ = value;
217 callback.Run(true);
218 } else {
219 callback.Run(false);
223 void ClaimInterface(uint8_t interface_number,
224 const UsbDeviceHandle::ResultCallback& callback) {
225 for (const auto& config : mock_configs_) {
226 for (const auto& interface : config.second.interfaces) {
227 if (interface.interface_number == interface_number) {
228 claimed_interfaces_.insert(interface_number);
229 callback.Run(true);
230 return;
234 callback.Run(false);
237 bool ReleaseInterface(uint8_t interface_number) {
238 if (ContainsKey(claimed_interfaces_, interface_number)) {
239 claimed_interfaces_.erase(interface_number);
240 return true;
242 return false;
245 void SetInterfaceAlternateSetting(
246 uint8_t interface_number,
247 uint8_t alternate_setting,
248 const UsbDeviceHandle::ResultCallback& callback) {
249 for (const auto& config : mock_configs_) {
250 for (const auto& interface : config.second.interfaces) {
251 if (interface.interface_number == interface_number &&
252 interface.alternate_setting == alternate_setting) {
253 callback.Run(true);
254 return;
258 callback.Run(false);
261 void ResetDevice(const UsbDeviceHandle::ResultCallback& callback) {
262 callback.Run(allow_reset_);
265 void InboundTransfer(const UsbDeviceHandle::TransferCallback& callback) {
266 ASSERT_GE(mock_inbound_data_.size(), 1u);
267 const std::vector<uint8_t>& bytes = mock_inbound_data_.front();
268 size_t length = bytes.size();
269 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(length);
270 std::copy(bytes.begin(), bytes.end(), buffer->data());
271 mock_inbound_data_.pop();
272 callback.Run(USB_TRANSFER_COMPLETED, buffer, length);
275 void OutboundTransfer(scoped_refptr<net::IOBuffer> buffer,
276 size_t length,
277 const UsbDeviceHandle::TransferCallback& callback) {
278 ASSERT_GE(mock_outbound_data_.size(), 1u);
279 const std::vector<uint8_t>& bytes = mock_outbound_data_.front();
280 ASSERT_EQ(bytes.size(), length);
281 for (size_t i = 0; i < length; ++i) {
282 EXPECT_EQ(bytes[i], buffer->data()[i])
283 << "Contents differ at index: " << i;
285 mock_outbound_data_.pop();
286 callback.Run(USB_TRANSFER_COMPLETED, buffer, length);
289 void ControlTransfer(UsbEndpointDirection direction,
290 UsbDeviceHandle::TransferRequestType request_type,
291 UsbDeviceHandle::TransferRecipient recipient,
292 uint8_t request,
293 uint16_t value,
294 uint16_t index,
295 scoped_refptr<net::IOBuffer> buffer,
296 size_t length,
297 unsigned int timeout,
298 const UsbDeviceHandle::TransferCallback& callback) {
299 if (direction == USB_DIRECTION_INBOUND)
300 InboundTransfer(callback);
301 else
302 OutboundTransfer(buffer, length, callback);
305 void GenericTransfer(UsbEndpointDirection direction,
306 uint8_t endpoint,
307 scoped_refptr<net::IOBuffer> buffer,
308 size_t length,
309 unsigned int timeout,
310 const UsbDeviceHandle::TransferCallback& callback) {
311 if (direction == USB_DIRECTION_INBOUND)
312 InboundTransfer(callback);
313 else
314 OutboundTransfer(buffer, length, callback);
317 void IsochronousTransfer(UsbEndpointDirection direction,
318 uint8_t endpoint,
319 scoped_refptr<net::IOBuffer> buffer,
320 size_t length,
321 unsigned int packets,
322 unsigned int packet_length,
323 unsigned int timeout,
324 const UsbDeviceHandle::TransferCallback& callback) {
325 if (direction == USB_DIRECTION_INBOUND)
326 InboundTransfer(callback);
327 else
328 OutboundTransfer(buffer, length, callback);
331 scoped_ptr<base::MessageLoop> message_loop_;
332 scoped_refptr<MockUsbDevice> mock_device_;
333 scoped_refptr<MockUsbDeviceHandle> mock_handle_;
334 bool is_device_open_;
335 bool allow_reset_;
337 std::map<uint8_t, UsbConfigDescriptor> mock_configs_;
338 uint8_t current_config_;
340 std::queue<std::vector<uint8_t>> mock_inbound_data_;
341 std::queue<std::vector<uint8_t>> mock_outbound_data_;
343 std::set<uint8_t> claimed_interfaces_;
345 DISALLOW_COPY_AND_ASSIGN(USBDeviceImplTest);
348 } // namespace
350 TEST_F(USBDeviceImplTest, Open) {
351 DevicePtr device = GetMockDeviceProxy();
353 EXPECT_FALSE(is_device_open());
355 EXPECT_CALL(mock_device(), Open(_));
357 base::RunLoop loop;
358 device->Open(
359 base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK, loop.QuitClosure()));
360 loop.Run();
362 EXPECT_CALL(mock_handle(), Close());
365 TEST_F(USBDeviceImplTest, Close) {
366 DevicePtr device = GetMockDeviceProxy();
368 EXPECT_FALSE(is_device_open());
370 EXPECT_CALL(mock_device(), Open(_));
373 base::RunLoop loop;
374 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
375 loop.QuitClosure()));
376 loop.Run();
379 EXPECT_CALL(mock_handle(), Close());
382 base::RunLoop loop;
383 device->Close(loop.QuitClosure());
384 loop.Run();
387 EXPECT_FALSE(is_device_open());
390 // Test that the information returned via the Device::GetDeviceInfo matches that
391 // of the underlying device.
392 TEST_F(USBDeviceImplTest, GetDeviceInfo) {
393 DevicePtr device =
394 GetMockDeviceProxy(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");
396 base::RunLoop loop;
397 device->GetDeviceInfo(base::Bind(&ExpectDeviceInfoAndThen,
398 mock_device().guid(), 0x1234, 0x5678, "ACME",
399 "Frobinator", "ABCDEF", loop.QuitClosure()));
400 loop.Run();
403 TEST_F(USBDeviceImplTest, SetInvalidConfiguration) {
404 DevicePtr device = GetMockDeviceProxy();
406 EXPECT_CALL(mock_device(), Open(_));
409 base::RunLoop loop;
410 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
411 loop.QuitClosure()));
412 loop.Run();
415 EXPECT_CALL(mock_handle(), SetConfiguration(42, _));
418 // SetConfiguration should fail because 42 is not a valid mock
419 // configuration.
420 base::RunLoop loop;
421 device->SetConfiguration(
422 42, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
423 loop.Run();
426 EXPECT_CALL(mock_handle(), Close());
429 TEST_F(USBDeviceImplTest, SetValidConfiguration) {
430 DevicePtr device = GetMockDeviceProxy();
432 EXPECT_CALL(mock_device(), Open(_));
435 base::RunLoop loop;
436 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
437 loop.QuitClosure()));
438 loop.Run();
441 EXPECT_CALL(mock_handle(), SetConfiguration(42, _));
443 AddMockConfig(ConfigBuilder(42));
446 // SetConfiguration should succeed because 42 is a valid mock configuration.
447 base::RunLoop loop;
448 device->SetConfiguration(
449 42, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
450 loop.Run();
453 EXPECT_CALL(mock_handle(), Close());
456 // Verify that the result of Reset() reflects the underlying UsbDeviceHandle's
457 // ResetDevice() result.
458 TEST_F(USBDeviceImplTest, Reset) {
459 DevicePtr device = GetMockDeviceProxy();
461 EXPECT_CALL(mock_device(), Open(_));
464 base::RunLoop loop;
465 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
466 loop.QuitClosure()));
467 loop.Run();
470 EXPECT_CALL(mock_handle(), ResetDevice(_));
472 set_allow_reset(true);
475 base::RunLoop loop;
476 device->Reset(base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
477 loop.Run();
480 EXPECT_CALL(mock_handle(), ResetDevice(_));
482 set_allow_reset(false);
485 base::RunLoop loop;
486 device->Reset(base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
487 loop.Run();
490 EXPECT_CALL(mock_handle(), Close());
493 TEST_F(USBDeviceImplTest, ClaimAndReleaseInterface) {
494 DevicePtr device = GetMockDeviceProxy();
496 EXPECT_CALL(mock_device(), Open(_));
499 base::RunLoop loop;
500 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
501 loop.QuitClosure()));
502 loop.Run();
505 // Now add a mock interface #1.
506 AddMockConfig(ConfigBuilder(0).AddInterface(1, 0, 1, 2, 3));
508 EXPECT_CALL(mock_handle(), ClaimInterface(2, _));
511 // Try to claim an invalid interface and expect failure.
512 base::RunLoop loop;
513 device->ClaimInterface(
514 2, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
515 loop.Run();
518 EXPECT_CALL(mock_handle(), ClaimInterface(1, _));
521 base::RunLoop loop;
522 device->ClaimInterface(
523 1, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
524 loop.Run();
527 EXPECT_CALL(mock_handle(), ReleaseInterface(2));
530 // Releasing a non-existent interface should fail.
531 base::RunLoop loop;
532 device->ReleaseInterface(
533 2, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
534 loop.Run();
537 EXPECT_CALL(mock_handle(), ReleaseInterface(1));
540 // Now this should release the claimed interface and close the handle.
541 base::RunLoop loop;
542 device->ReleaseInterface(
543 1, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
544 loop.Run();
547 EXPECT_CALL(mock_handle(), Close());
550 TEST_F(USBDeviceImplTest, SetInterfaceAlternateSetting) {
551 DevicePtr device = GetMockDeviceProxy();
553 EXPECT_CALL(mock_device(), Open(_));
556 base::RunLoop loop;
557 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
558 loop.QuitClosure()));
559 loop.Run();
562 AddMockConfig(ConfigBuilder(0)
563 .AddInterface(1, 0, 1, 2, 3)
564 .AddInterface(1, 42, 1, 2, 3)
565 .AddInterface(2, 0, 1, 2, 3));
567 EXPECT_CALL(mock_handle(), SetInterfaceAlternateSetting(1, 42, _));
570 base::RunLoop loop;
571 device->SetInterfaceAlternateSetting(
572 1, 42, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
573 loop.Run();
576 EXPECT_CALL(mock_handle(), SetInterfaceAlternateSetting(1, 100, _));
579 base::RunLoop loop;
580 device->SetInterfaceAlternateSetting(
581 1, 100, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
582 loop.Run();
585 EXPECT_CALL(mock_handle(), Close());
588 TEST_F(USBDeviceImplTest, ControlTransfer) {
589 DevicePtr device = GetMockDeviceProxy();
591 EXPECT_CALL(mock_device(), Open(_));
594 base::RunLoop loop;
595 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
596 loop.QuitClosure()));
597 loop.Run();
600 std::vector<uint8_t> fake_data;
601 fake_data.push_back(41);
602 fake_data.push_back(42);
603 fake_data.push_back(43);
605 AddMockInboundData(fake_data);
607 EXPECT_CALL(mock_handle(),
608 ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD,
609 UsbDeviceHandle::DEVICE, 5, 6, 7, _, _, 0, _));
612 auto params = ControlTransferParams::New();
613 params->type = CONTROL_TRANSFER_TYPE_STANDARD;
614 params->recipient = CONTROL_TRANSFER_RECIPIENT_DEVICE;
615 params->request = 5;
616 params->value = 6;
617 params->index = 7;
618 base::RunLoop loop;
619 device->ControlTransferIn(
620 params.Pass(), static_cast<uint32_t>(fake_data.size()), 0,
621 base::Bind(&ExpectTransferInAndThen, TRANSFER_STATUS_COMPLETED,
622 fake_data, loop.QuitClosure()));
623 loop.Run();
626 AddMockConfig(ConfigBuilder(0).AddInterface(7, 0, 1, 2, 3));
627 AddMockOutboundData(fake_data);
629 EXPECT_CALL(mock_handle(),
630 ControlTransfer(USB_DIRECTION_OUTBOUND, UsbDeviceHandle::STANDARD,
631 UsbDeviceHandle::INTERFACE, 5, 6, 7, _, _, 0, _));
634 auto params = ControlTransferParams::New();
635 params->type = CONTROL_TRANSFER_TYPE_STANDARD;
636 params->recipient = CONTROL_TRANSFER_RECIPIENT_INTERFACE;
637 params->request = 5;
638 params->value = 6;
639 params->index = 7;
640 base::RunLoop loop;
641 device->ControlTransferOut(
642 params.Pass(), mojo::Array<uint8_t>::From(fake_data), 0,
643 base::Bind(&ExpectTransferStatusAndThen, TRANSFER_STATUS_COMPLETED,
644 loop.QuitClosure()));
645 loop.Run();
648 EXPECT_CALL(mock_handle(), Close());
651 TEST_F(USBDeviceImplTest, GenericTransfer) {
652 DevicePtr device = GetMockDeviceProxy();
654 EXPECT_CALL(mock_device(), Open(_));
657 base::RunLoop loop;
658 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
659 loop.QuitClosure()));
660 loop.Run();
663 std::string message1 = "say hello please";
664 std::vector<uint8_t> fake_outbound_data(message1.size());
665 std::copy(message1.begin(), message1.end(), fake_outbound_data.begin());
667 std::string message2 = "hello world!";
668 std::vector<uint8_t> fake_inbound_data(message2.size());
669 std::copy(message2.begin(), message2.end(), fake_inbound_data.begin());
671 AddMockConfig(ConfigBuilder(0).AddInterface(7, 0, 1, 2, 3));
672 AddMockOutboundData(fake_outbound_data);
673 AddMockInboundData(fake_inbound_data);
675 EXPECT_CALL(mock_handle(), GenericTransfer(USB_DIRECTION_OUTBOUND, 0x01, _,
676 fake_outbound_data.size(), 0, _));
679 base::RunLoop loop;
680 device->GenericTransferOut(
681 1, mojo::Array<uint8_t>::From(fake_outbound_data), 0,
682 base::Bind(&ExpectTransferStatusAndThen, TRANSFER_STATUS_COMPLETED,
683 loop.QuitClosure()));
684 loop.Run();
687 EXPECT_CALL(mock_handle(), GenericTransfer(USB_DIRECTION_INBOUND, 0x81, _,
688 fake_inbound_data.size(), 0, _));
691 base::RunLoop loop;
692 device->GenericTransferIn(
693 1, static_cast<uint32_t>(fake_inbound_data.size()), 0,
694 base::Bind(&ExpectTransferInAndThen, TRANSFER_STATUS_COMPLETED,
695 fake_inbound_data, loop.QuitClosure()));
696 loop.Run();
699 EXPECT_CALL(mock_handle(), Close());
702 TEST_F(USBDeviceImplTest, IsochronousTransfer) {
703 DevicePtr device = GetMockDeviceProxy();
705 EXPECT_CALL(mock_device(), Open(_));
708 base::RunLoop loop;
709 device->Open(base::Bind(&ExpectOpenAndThen, OPEN_DEVICE_ERROR_OK,
710 loop.QuitClosure()));
711 loop.Run();
714 std::string outbound_packet_data = "aaaaaaaabbbbbbbbccccccccdddddddd";
715 std::vector<uint8_t> fake_outbound_packets(outbound_packet_data.size());
716 std::copy(outbound_packet_data.begin(), outbound_packet_data.end(),
717 fake_outbound_packets.begin());
719 std::string inbound_packet_data = "ddddddddccccccccbbbbbbbbaaaaaaaa";
720 std::vector<uint8_t> fake_inbound_packets(inbound_packet_data.size());
721 std::copy(inbound_packet_data.begin(), inbound_packet_data.end(),
722 fake_inbound_packets.begin());
724 AddMockConfig(ConfigBuilder(0).AddInterface(7, 0, 1, 2, 3));
725 AddMockOutboundData(fake_outbound_packets);
726 AddMockInboundData(fake_inbound_packets);
728 EXPECT_CALL(mock_handle(),
729 IsochronousTransfer(USB_DIRECTION_OUTBOUND, 0x01, _,
730 fake_outbound_packets.size(), 4, 8, 0, _));
733 base::RunLoop loop;
734 mojo::Array<mojo::Array<uint8_t>> packets =
735 mojo::Array<mojo::Array<uint8_t>>::New(4);
736 for (size_t i = 0; i < 4; ++i) {
737 std::vector<uint8_t> bytes(8);
738 std::copy(outbound_packet_data.begin() + i * 8,
739 outbound_packet_data.begin() + i * 8 + 8, bytes.begin());
740 packets[i].Swap(&bytes);
742 device->IsochronousTransferOut(
743 1, packets.Pass(), 0,
744 base::Bind(&ExpectTransferStatusAndThen, TRANSFER_STATUS_COMPLETED,
745 loop.QuitClosure()));
746 loop.Run();
749 EXPECT_CALL(mock_handle(),
750 IsochronousTransfer(USB_DIRECTION_INBOUND, 0x81, _,
751 fake_inbound_packets.size(), 4, 8, 0, _));
754 base::RunLoop loop;
755 std::vector<std::vector<uint8_t>> packets(4);
756 for (size_t i = 0; i < 4; ++i) {
757 packets[i].resize(8);
758 std::copy(inbound_packet_data.begin() + i * 8,
759 inbound_packet_data.begin() + i * 8 + 8, packets[i].begin());
761 device->IsochronousTransferIn(
762 1, 4, 8, 0, base::Bind(&ExpectPacketsAndThen, TRANSFER_STATUS_COMPLETED,
763 packets, loop.QuitClosure()));
764 loop.Run();
767 EXPECT_CALL(mock_handle(), Close());
770 } // namespace usb
771 } // namespace device