Chromium Code Reviews| Index: chrome/browser/devtools/device/usb/android_usb_browser_test.cc |
| diff --git a/chrome/browser/devtools/device/usb/android_usb_browser_test.cc b/chrome/browser/devtools/device/usb/android_usb_browser_test.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..26f4294358c177e7227fc3933210b3a2605b6da3 |
| --- /dev/null |
| +++ b/chrome/browser/devtools/device/usb/android_usb_browser_test.cc |
| @@ -0,0 +1,228 @@ |
| +// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <algorithm> |
| + |
| +#include "chrome/browser/devtools/device/devtools_android_bridge.h" |
| +#include "chrome/browser/ui/browser.h" |
| +#include "chrome/test/base/in_process_browser_test.h" |
| +#include "components/usb_service/usb_device.h" |
| +#include "components/usb_service/usb_device_handle.h" |
| +#include "components/usb_service/usb_interface.h" |
| +#include "components/usb_service/usb_service.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/test/test_utils.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +using content::BrowserThread; |
| +using usb_service::UsbConfigDescriptor; |
| +using usb_service::UsbDevice; |
| +using usb_service::UsbDeviceHandle; |
| +using usb_service::UsbEndpointDescriptor; |
| +using usb_service::UsbInterfaceAltSettingDescriptor; |
| +using usb_service::UsbInterfaceDescriptor; |
| +using usb_service::UsbService; |
| + |
| +struct AndroidTraits { |
| + static const int kClass = 0xff; |
| + static const int kSubclass = 0x42; |
| + static const int kProtocol = 0x1; |
| +}; |
| + |
| +struct NonAndroidTraits { |
| + static const int kClass = 0xf0; |
| + static const int kSubclass = 0x42; |
| + static const int kProtocol = 0x2; |
| +}; |
| + |
| +template <class T> |
| +class MockUsbInterfaceAltSettingDescriptor |
| + : public UsbInterfaceAltSettingDescriptor { |
| + public: |
| + MockUsbInterfaceAltSettingDescriptor(int interface_number, |
| + int alternate_setting) |
| + : interface_number_(interface_number), |
| + alternate_setting_(alternate_setting) {} |
| + |
| + virtual size_t GetNumEndpoints() const OVERRIDE { |
| + // See IsAndroidInterface function in android_usb_device.cc |
| + return 2; |
| + } |
| + |
| + virtual scoped_refptr<const UsbEndpointDescriptor> GetEndpoint( |
| + size_t index) const OVERRIDE { |
| + EXPECT_GT(static_cast<size_t>(2), index); |
| + return NULL; |
| + } |
| + |
| + virtual int GetInterfaceNumber() const OVERRIDE { return interface_number_; } |
| + |
| + virtual int GetAlternateSetting() const OVERRIDE { |
| + return alternate_setting_; |
| + } |
| + |
| + virtual int GetInterfaceClass() const OVERRIDE { return T::kClass; } |
| + |
| + virtual int GetInterfaceSubclass() const OVERRIDE { return T::kSubclass; } |
| + |
| + virtual int GetInterfaceProtocol() const OVERRIDE { return T::kProtocol; } |
| + |
| + protected: |
| + virtual ~MockUsbInterfaceAltSettingDescriptor() {}; |
| + |
| + private: |
| + const int interface_number_; |
| + const int alternate_setting_; |
| +}; |
| + |
| +template <class T> |
| +class MockUsbInterfaceDescriptor : public UsbInterfaceDescriptor { |
| + public: |
| + explicit MockUsbInterfaceDescriptor(int interface_number) |
| + : interface_number_(interface_number) {} |
| + |
| + virtual size_t GetNumAltSettings() const OVERRIDE { |
| + // See IsAndroidInterface function in android_usb_device.cc |
| + return 1; |
| + } |
| + virtual scoped_refptr<const UsbInterfaceAltSettingDescriptor> GetAltSetting( |
| + size_t index) const OVERRIDE { |
| + EXPECT_EQ(static_cast<size_t>(0), index); |
| + return new MockUsbInterfaceAltSettingDescriptor<T>(interface_number_, 0); |
| + } |
| + |
| + protected: |
| + const int interface_number_; |
| + virtual ~MockUsbInterfaceDescriptor() {} |
| +}; |
| + |
| +template <class T> |
| +class MockUsbConfigDescriptor : public UsbConfigDescriptor { |
| + public: |
| + MockUsbConfigDescriptor() {} |
| + |
| + virtual size_t GetNumInterfaces() const OVERRIDE { return 1; } |
| + |
| + virtual scoped_refptr<const UsbInterfaceDescriptor> GetInterface( |
| + size_t index) const OVERRIDE { |
| + EXPECT_EQ(static_cast<size_t>(0), index); |
| + return new MockUsbInterfaceDescriptor<T>(index); |
| + } |
| + |
| + protected: |
| + virtual ~MockUsbConfigDescriptor() {}; |
| +}; |
| + |
| +template <class T> |
| +class MockUsbDevice : public UsbDevice { |
| + public: |
| + MockUsbDevice() : UsbDevice(0, 0, 0) {} |
| + |
| + virtual ~MockUsbDevice() {} |
| + |
| + virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE { return NULL; } |
| + |
| + virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() OVERRIDE { |
| + return new MockUsbConfigDescriptor<T>(); |
| + } |
| + |
| + virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) { return true; } |
| + |
| +#if defined(OS_CHROMEOS) |
| + // On ChromeOS, if an interface of a claimed device is not claimed, the |
| + // permission broker can change the owner of the device so that the unclaimed |
| + // interfaces can be used. If this argument is missing, permission broker will |
| + // not be used and this method fails if the device is claimed. |
| + virtual void RequestUsbAcess( |
| + int interface_id, |
| + const base::Callback<void(bool success)>& callback) OVERRIDE { |
| + callback.Run(true); |
| + } |
| +#endif // OS_CHROMEOS |
| +}; |
| + |
| +class MockUsbService : public UsbService { |
| + public: |
| + virtual ~MockUsbService() {} |
| + |
| + virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE { |
| + NOTIMPLEMENTED(); |
| + return NULL; |
| + } |
| + |
| + virtual void GetDevices( |
| + std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE { |
| + STLClearObject(devices); |
| + |
| + std::copy(devices_.begin(), devices_.end(), back_inserter(*devices)); |
| + } |
| + |
| + std::vector<scoped_refptr<UsbDevice> > devices_; |
| +}; |
| + |
| +class AndroidUsbBrowserTest |
| + : public InProcessBrowserTest, |
| + public DevToolsAndroidBridge::DeviceCountListener { |
| + protected: |
| + AndroidUsbBrowserTest() : step_(0), service_(new MockUsbService()) {} |
| + |
| + void init() { runner_ = new content::MessageLoopRunner; } |
| + |
| + virtual void DeviceCountChanged(int count) OVERRIDE { |
| + switch (step_) { |
| + case 0: |
| + // Check for 0 devices when no devices present |
| + EXPECT_EQ(0, count); |
| + service_->devices_.push_back(new MockUsbDevice<AndroidTraits>()); |
| + break; |
| + case 1: |
| + // Check for 1 device when only android device present |
| + EXPECT_EQ(1, count); |
| + service_->devices_.push_back(new MockUsbDevice<NonAndroidTraits>()); |
| + break; |
| + case 2: |
| + // Check for 1 device when android and non-android devices present |
| + EXPECT_EQ(1, count); |
| + service_->devices_.erase(service_->devices_.begin()); |
| + break; |
| + case 3: |
| + // Check for 0 devices when only non-android devices present |
| + EXPECT_EQ(0, count); |
| + adb_bridge_->RemoveDeviceCountListener(this); |
| + runner_->Quit(); |
| + break; |
| + default: |
| + EXPECT_TRUE(false) << "Unknown step " << step_; |
| + } |
| + step_++; |
| + } |
| + |
| + int step_; |
| + scoped_refptr<content::MessageLoopRunner> runner_; |
| + MockUsbService* service_; |
| + scoped_refptr<DevToolsAndroidBridge> adb_bridge_; |
| +}; |
| + |
| +IN_PROC_BROWSER_TEST_F(AndroidUsbBrowserTest, TestDeviceCounting) { |
| + init(); |
| + |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, |
| + FROM_HERE, |
| + base::Bind(&UsbService::SetInstanceForTest, service_)); |
| + |
| + adb_bridge_ = |
| + DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile()); |
| + |
| + if (!adb_bridge_) { |
| + FAIL() << "Failed to get DevToolsAndroidBridge."; |
| + } |
| + |
| + adb_bridge_->set_polling_interval_for_test(1); |
|
Vladislav Kaznacheev
2014/05/12 17:21:08
You can do without this call if you just remove an
Dmitry Zvorygin
2014/05/15 11:35:13
Done.
|
| + adb_bridge_->AddDeviceCountListener(this); |
| + |
| + runner_->Run(); |
| + |
| + adb_bridge_->set_polling_interval_for_test(0); |
| +} |