Skip to content

Commit

Permalink
Reland: Build a basic Mojo service framework for device/usb
Browse files Browse the repository at this point in the history
This is a reland of https://codereview.chromium.org/1155163008
now with extra deps to satisfy Win8 GN builds.

BUG=492805
TBR=reillyg@chromium.org,sky@chromium.org

Review URL: https://codereview.chromium.org/1158323003

Cr-Commit-Position: refs/heads/master@{#331719}
  • Loading branch information
krockot authored and Commit bot committed May 28, 2015
1 parent 58aad3a commit 8fcc275
Show file tree
Hide file tree
Showing 26 changed files with 976 additions and 4 deletions.
3 changes: 3 additions & 0 deletions chrome/browser/OWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ per-file chrome_content_browser_client_unittest.cc=*
per-file chrome_browser_field_trials*=asvitkine@chromium.org
per-file chrome_browser_field_trials*=stevet@chromium.org

per-file chrome_device_client*=reillyg@chromium.org
per-file chrome_device_client*=rockot@chromium.org

per-file chrome_elf_init_*=csharp@chromium.org
per-file chrome_elf_init_*=robertshield@chromium.org

Expand Down
30 changes: 30 additions & 0 deletions chrome/browser/chrome_device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,34 @@
#include "chrome/browser/chrome_device_client.h"

#include "base/logging.h"
#include "base/macros.h"
#include "content/public/browser/browser_thread.h"
#include "device/hid/hid_service.h"
#include "device/usb/public/cpp/device_manager_delegate.h"
#include "device/usb/public/cpp/device_manager_factory.h"
#include "device/usb/public/interfaces/device.mojom.h"
#include "device/usb/usb_service.h"

using content::BrowserThread;

namespace {

// DeviceManagerDelegate implementation which allows access to all devices.
class BrowserDeviceManagerDelegate : public device::usb::DeviceManagerDelegate {
public:
BrowserDeviceManagerDelegate() {}
~BrowserDeviceManagerDelegate() override {}

private:
bool IsDeviceAllowed(const device::usb::DeviceInfo& device) override {
return true;
}

DISALLOW_COPY_AND_ASSIGN(BrowserDeviceManagerDelegate);
};

} // namespace

ChromeDeviceClient::ChromeDeviceClient() {}

ChromeDeviceClient::~ChromeDeviceClient() {}
Expand All @@ -21,6 +43,14 @@ device::UsbService* ChromeDeviceClient::GetUsbService() {
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
}

void ChromeDeviceClient::ConnectToUSBDeviceManager(
mojo::InterfaceRequest<device::usb::DeviceManager> request) {
device::usb::DeviceManagerFactory::Build(
request.Pass(),
scoped_ptr<device::usb::DeviceManagerDelegate>(
new BrowserDeviceManagerDelegate));
}

device::HidService* ChromeDeviceClient::GetHidService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return device::HidService::GetInstance(
Expand Down
4 changes: 3 additions & 1 deletion chrome/browser/chrome_device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
class ChromeDeviceClient : device::DeviceClient {
public:
ChromeDeviceClient();
virtual ~ChromeDeviceClient();
~ChromeDeviceClient() override;

// device::DeviceClient implementation
device::UsbService* GetUsbService() override;
void ConnectToUSBDeviceManager(
mojo::InterfaceRequest<device::usb::DeviceManager> request) override;
device::HidService* GetHidService() override;

private:
Expand Down
5 changes: 5 additions & 0 deletions device/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,18 @@ test("device_unittests") {
if (!is_android && !is_ios) {
sources += [
"test/usb_test_gadget_impl.cc",
"usb/device_impl_unittest.cc",
"usb/device_manager_impl_unittest.cc",
"usb/usb_context_unittest.cc",
"usb/usb_device_filter_unittest.cc",
"usb/usb_device_handle_unittest.cc",
"usb/usb_ids_unittest.cc",
"usb/usb_service_unittest.cc",
]
deps += [
"//device/core",
"//device/usb/public/cpp",
"//device/usb/public/interfaces",
"//device/usb",
"//device/usb:mocks",
"//third_party/libusb",
Expand Down
3 changes: 2 additions & 1 deletion device/core/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ source_set("core") {
"device_monitor_win.h",
]

deps = [
public_deps = [
"//base",
"//third_party/mojo/src/mojo/public/cpp/bindings",
]
}
3 changes: 3 additions & 0 deletions device/core/core.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
'device_monitor_win.cc',
'device_monitor_win.h',
],
'dependencies': [
'<(DEPTH)/third_party/mojo/mojo_public.gyp:mojo_cpp_bindings',
],
},
],
}
4 changes: 4 additions & 0 deletions device/core/device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ UsbService* DeviceClient::GetUsbService() {
return NULL;
}

void DeviceClient::ConnectToUSBDeviceManager(
mojo::InterfaceRequest<usb::DeviceManager> request) {
}

HidService* DeviceClient::GetHidService() {
// This should never be called by clients which do not support the HID API.
NOTREACHED();
Expand Down
12 changes: 11 additions & 1 deletion device/core/device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@
#define DEVICE_CORE_DEVICE_CLIENT_H_

#include "base/macros.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"

namespace device {

class HidService;
class UsbService;

namespace usb {
class DeviceManager;
}

// Interface used by consumers of //device APIs to get pointers to the service
// singletons appropriate for a given embedding application. For an example see
// //chrome/browser/chrome_device_client.h.
Expand All @@ -21,14 +26,19 @@ class DeviceClient {
DeviceClient();

// Destruction clears the single instance.
~DeviceClient();
virtual ~DeviceClient();

// Returns the single instance of |this|.
static DeviceClient* Get();

// Returns the UsbService instance for this embedder.
virtual UsbService* GetUsbService();

// Connects a USB DeviceManager client to a concrete implementation. If
// no such implementation is available the request is dropped.
virtual void ConnectToUSBDeviceManager(
mojo::InterfaceRequest<usb::DeviceManager> request);

// Returns the HidService instance for this embedder.
virtual HidService* GetHidService();

Expand Down
2 changes: 2 additions & 0 deletions device/device_tests.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
'serial/serial_service_unittest.cc',
'test/run_all_unittests.cc',
'test/usb_test_gadget_impl.cc',
'usb/device_impl_unittest.cc',
'usb/device_manager_impl_unittest.cc',
'usb/usb_context_unittest.cc',
'usb/usb_device_filter_unittest.cc',
'usb/usb_device_handle_unittest.cc',
Expand Down
14 changes: 14 additions & 0 deletions device/usb/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ generated_ids = "$target_gen_dir/usb_ids_gen.cc"

source_set("usb") {
sources = [
"device_impl.cc",
"device_impl.h",
"device_manager_impl.cc",
"device_manager_impl.h",
"type_converters.cc",
"type_converters.h",
"usb_context.cc",
"usb_context.h",
"usb_descriptors.cc",
Expand Down Expand Up @@ -39,8 +45,16 @@ source_set("usb") {
"//base/third_party/dynamic_annotations",
"//components/device_event_log",
"//device/core",
"//device/usb/public/cpp",
"//mojo/environment:chromium",
"//net",
"//third_party/libusb",
"//third_party/mojo/src/mojo/edk/system",
"//third_party/mojo/src/mojo/public/cpp/bindings",
]

public_deps = [
"//device/usb/public/interfaces",
]

if (is_linux) {
Expand Down
34 changes: 34 additions & 0 deletions device/usb/device_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2015 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 "device/usb/device_impl.h"
#include "device/usb/type_converters.h"
#include "device/usb/usb_device.h"

namespace device {
namespace usb {

DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device,
mojo::InterfaceRequest<Device> request)
: binding_(this, request.Pass()),
device_(device),
info_(DeviceInfo::From(*device)) {
// TODO(rockot/reillyg): Support more than just the current configuration.
// Also, converting configuration info should be done in the TypeConverter,
// but GetConfiguration() is non-const so we do it here for now.
const UsbConfigDescriptor* config = device->GetConfiguration();
info_->configurations = mojo::Array<ConfigurationInfoPtr>::New(0);
if (config)
info_->configurations.push_back(ConfigurationInfo::From(*config));
}

DeviceImpl::~DeviceImpl() {
}

void DeviceImpl::GetDeviceInfo(const GetDeviceInfoCallback& callback) {
callback.Run(info_.Clone());
}

} // namespace usb
} // namespace device
44 changes: 44 additions & 0 deletions device/usb/device_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2015 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.

#ifndef DEVICE_USB_DEVICE_IMPL_H_
#define DEVICE_USB_DEVICE_IMPL_H_

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "device/usb/public/interfaces/device.mojom.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"

namespace device {

class UsbDevice;

namespace usb {

// Implementation of the public Device interface. Instances of this class are
// constructed by DeviceManagerImpl and are strongly bound to their MessagePipe
// lifetime.
class DeviceImpl : public Device {
public:
DeviceImpl(scoped_refptr<UsbDevice> device,
mojo::InterfaceRequest<Device> request);
~DeviceImpl() override;

private:
// Device implementation:
void GetDeviceInfo(const GetDeviceInfoCallback& callback) override;

mojo::StrongBinding<Device> binding_;

scoped_refptr<UsbDevice> device_;
DeviceInfoPtr info_;

DISALLOW_COPY_AND_ASSIGN(DeviceImpl);
};

} // namespace usb
} // namespace device

#endif // DEVICE_USB_DEVICE_IMPL_H_
55 changes: 55 additions & 0 deletions device/usb/device_impl_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2015 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 "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "device/usb/device_impl.h"
#include "device/usb/mock_usb_device.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"

namespace device {
namespace usb {

namespace {

using DeviceImplTest = testing::Test;

void ExpectDeviceInfoAndThen(uint16_t vendor_id,
uint16_t product_id,
const std::string& manufacturer,
const std::string& product,
const std::string& serial_number,
const base::Closure& continuation,
DeviceInfoPtr device_info) {
EXPECT_EQ(vendor_id, device_info->vendor_id);
EXPECT_EQ(product_id, device_info->product_id);
EXPECT_EQ(manufacturer, device_info->manufacturer);
EXPECT_EQ(product, device_info->product);
EXPECT_EQ(serial_number, device_info->serial_number);
continuation.Run();
}

} // namespace

// Test that the information returned via the Device::GetDeviceInfo matches that
// of the underlying device.
TEST_F(DeviceImplTest, GetDeviceInfo) {
base::MessageLoop message_loop;
scoped_refptr<MockUsbDevice> fake_device =
new MockUsbDevice(0x1234, 0x5678, "ACME", "Frobinator", "ABCDEF");
DevicePtr device;
EXPECT_CALL(*fake_device.get(), GetConfiguration());
new DeviceImpl(fake_device, mojo::GetProxy(&device));

base::RunLoop run_loop;
device->GetDeviceInfo(base::Bind(&ExpectDeviceInfoAndThen, 0x1234, 0x5678,
"ACME", "Frobinator", "ABCDEF",
run_loop.QuitClosure()));
run_loop.Run();
}

} // namespace usb
} // namespace device
Loading

0 comments on commit 8fcc275

Please sign in to comment.