| 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..37356d00063e0ec5122ec40b52bd526c2333f377
|
| --- /dev/null
|
| +++ b/chrome/browser/devtools/device/usb/android_usb_browser_test.cc
|
| @@ -0,0 +1,268 @@
|
| +// 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;
|
| +
|
| +namespace {
|
| +
|
| +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);
|
| + // This switch should be kept in sync with
|
| + // AndroidUsbBrowserTest::DeviceCountChanged.
|
| + switch (step_) {
|
| + case 0:
|
| + // No devices.
|
| + break;
|
| + case 1:
|
| + // Android device.
|
| + devices->push_back(new MockUsbDevice<AndroidTraits>());
|
| + break;
|
| + case 2:
|
| + // Android and non-android device.
|
| + devices->push_back(new MockUsbDevice<AndroidTraits>());
|
| + devices->push_back(new MockUsbDevice<NonAndroidTraits>());
|
| + break;
|
| + case 3:
|
| + // Non-android device.
|
| + devices->push_back(new MockUsbDevice<NonAndroidTraits>());
|
| + break;
|
| + }
|
| + step_++;
|
| + }
|
| +
|
| + private:
|
| + int step_ = 0;
|
| +};
|
| +
|
| +class AndroidUsbBrowserTest
|
| + : public InProcessBrowserTest,
|
| + public DevToolsAndroidBridge::DeviceCountListener {
|
| + protected:
|
| + AndroidUsbBrowserTest() : step_(0) {}
|
| +
|
| + virtual void SetUpOnMainThread() OVERRIDE {
|
| + scoped_refptr<content::MessageLoopRunner> runner =
|
| + new content::MessageLoopRunner;
|
| +
|
| + BrowserThread::PostTaskAndReply(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&AndroidUsbBrowserTest::SetUpService, this),
|
| + runner->QuitClosure());
|
| + runner->Run();
|
| + runner_ = new content::MessageLoopRunner;
|
| + adb_bridge_ =
|
| + DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile());
|
| +
|
| + if (!adb_bridge_)
|
| + FAIL() << "Failed to get DevToolsAndroidBridge.";
|
| +
|
| + adb_bridge_->AddDeviceCountListener(this);
|
| + }
|
| +
|
| + void SetUpService() {
|
| + service_ = new MockUsbService();
|
| + UsbService::SetInstanceForTest(service_);
|
| + }
|
| +
|
| + virtual void CleanUpOnMainThread() OVERRIDE {
|
| + scoped_refptr<content::MessageLoopRunner> runner =
|
| + new content::MessageLoopRunner;
|
| + UsbService* service = NULL;
|
| + BrowserThread::PostTaskAndReply(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&UsbService::SetInstanceForTest, service),
|
| + runner->QuitClosure());
|
| + runner->Run();
|
| + }
|
| +
|
| + virtual void DeviceCountChanged(int count) OVERRIDE {
|
| + adb_bridge_->RemoveDeviceCountListener(this);
|
| + adb_bridge_->AddDeviceCountListener(this);
|
| + // This switch should be kept in sync with MockUsbService::GetDevice.
|
| + switch (step_) {
|
| + case 0:
|
| + // Check for 0 devices when no devices present.
|
| + EXPECT_EQ(0, count);
|
| + break;
|
| + case 1:
|
| + // Check for 1 device when only android device present.
|
| + EXPECT_EQ(1, count);
|
| + break;
|
| + case 2:
|
| + // Check for 1 device when android and non-android devices present.
|
| + EXPECT_EQ(1, count);
|
| + 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_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +IN_PROC_BROWSER_TEST_F(AndroidUsbBrowserTest, TestDeviceCounting) {
|
| + runner_->Run();
|
| +}
|
|
|