Home | History | Annotate | Download | only in usb
      1 // 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 
      5 #include "base/bind.h"
      6 #include "base/message_loop/message_loop.h"
      7 #include "base/run_loop.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "device/test/usb_test_gadget.h"
     10 #include "device/usb/usb_device.h"
     11 #include "device/usb/usb_device_handle.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace device {
     15 
     16 namespace {
     17 
     18 class UsbDeviceHandleTest : public ::testing::Test {
     19  public:
     20   virtual void SetUp() {
     21     if (!UsbTestGadget::IsTestEnabled()) {
     22       return;
     23     }
     24 
     25     message_loop_.reset(new base::MessageLoopForIO);
     26 
     27     gadget_ = UsbTestGadget::Claim();
     28     ASSERT_TRUE(gadget_.get());
     29 
     30     ASSERT_TRUE(gadget_->SetType(UsbTestGadget::ECHO));
     31 
     32     handle_ = gadget_->GetDevice()->Open();
     33     ASSERT_TRUE(handle_.get());
     34   }
     35 
     36   virtual void TearDown() {
     37     if (handle_.get()) {
     38       handle_->Close();
     39     }
     40     gadget_.reset(NULL);
     41     message_loop_.reset(NULL);
     42   }
     43 
     44  protected:
     45   scoped_refptr<UsbDeviceHandle> handle_;
     46 
     47  private:
     48   scoped_ptr<UsbTestGadget> gadget_;
     49   scoped_ptr<base::MessageLoop> message_loop_;
     50 };
     51 
     52 class TestCompletionCallback {
     53  public:
     54   TestCompletionCallback()
     55       : callback_(base::Bind(&TestCompletionCallback::SetResult,
     56                              base::Unretained(this))) {}
     57 
     58   void SetResult(UsbTransferStatus status,
     59                  scoped_refptr<net::IOBuffer> buffer,
     60                  size_t transferred) {
     61     status_ = status;
     62     transferred_ = transferred;
     63     run_loop_.Quit();
     64   }
     65 
     66   void WaitForResult() { run_loop_.Run(); }
     67 
     68   const UsbTransferCallback& callback() const { return callback_; }
     69   UsbTransferStatus status() const { return status_; }
     70   size_t transferred() const { return transferred_; }
     71 
     72  private:
     73   const UsbTransferCallback callback_;
     74   base::RunLoop run_loop_;
     75   UsbTransferStatus status_;
     76   size_t transferred_;
     77 };
     78 
     79 TEST_F(UsbDeviceHandleTest, InterruptTransfer) {
     80   if (!handle_.get()) {
     81     return;
     82   }
     83 
     84   scoped_refptr<net::IOBufferWithSize> in_buffer(new net::IOBufferWithSize(64));
     85   TestCompletionCallback in_completion;
     86   handle_->InterruptTransfer(USB_DIRECTION_INBOUND,
     87                              0x81,
     88                              in_buffer.get(),
     89                              in_buffer->size(),
     90                              5000,  // 5 second timeout
     91                              in_completion.callback());
     92 
     93   scoped_refptr<net::IOBufferWithSize> out_buffer(
     94       new net::IOBufferWithSize(in_buffer->size()));
     95   TestCompletionCallback out_completion;
     96   for (int i = 0; i < out_buffer->size(); ++i) {
     97     out_buffer->data()[i] = i;
     98   }
     99 
    100   handle_->InterruptTransfer(USB_DIRECTION_OUTBOUND,
    101                              0x01,
    102                              out_buffer.get(),
    103                              out_buffer->size(),
    104                              5000,  // 5 second timeout
    105                              out_completion.callback());
    106   out_completion.WaitForResult();
    107   ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status());
    108   ASSERT_EQ(static_cast<size_t>(out_buffer->size()),
    109             out_completion.transferred());
    110 
    111   in_completion.WaitForResult();
    112   ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status());
    113   ASSERT_EQ(static_cast<size_t>(in_buffer->size()),
    114             in_completion.transferred());
    115   for (int i = 0; i < in_buffer->size(); ++i) {
    116     ASSERT_EQ(out_buffer->data()[i], in_buffer->data()[i]);
    117   }
    118 }
    119 
    120 TEST_F(UsbDeviceHandleTest, BulkTransfer) {
    121   if (!handle_.get()) {
    122     return;
    123   }
    124 
    125   scoped_refptr<net::IOBufferWithSize> in_buffer(
    126       new net::IOBufferWithSize(512));
    127   TestCompletionCallback in_completion;
    128   handle_->BulkTransfer(USB_DIRECTION_INBOUND,
    129                         0x81,
    130                         in_buffer.get(),
    131                         in_buffer->size(),
    132                         5000,  // 5 second timeout
    133                         in_completion.callback());
    134 
    135   scoped_refptr<net::IOBufferWithSize> out_buffer(
    136       new net::IOBufferWithSize(in_buffer->size()));
    137   TestCompletionCallback out_completion;
    138   for (int i = 0; i < out_buffer->size(); ++i) {
    139     out_buffer->data()[i] = i;
    140   }
    141 
    142   handle_->BulkTransfer(USB_DIRECTION_OUTBOUND,
    143                         0x01,
    144                         out_buffer.get(),
    145                         out_buffer->size(),
    146                         5000,  // 5 second timeout
    147                         out_completion.callback());
    148   out_completion.WaitForResult();
    149   ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status());
    150   ASSERT_EQ(static_cast<size_t>(out_buffer->size()),
    151             out_completion.transferred());
    152 
    153   in_completion.WaitForResult();
    154   ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status());
    155   ASSERT_EQ(static_cast<size_t>(in_buffer->size()),
    156             in_completion.transferred());
    157   for (int i = 0; i < in_buffer->size(); ++i) {
    158     ASSERT_EQ(out_buffer->data()[i], in_buffer->data()[i]);
    159   }
    160 }
    161 
    162 }  // namespace
    163 
    164 }  // namespace device
    165