summaryrefslogtreecommitdiff
path: root/chromium/extensions/browser/api/usb/usb_event_router.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/extensions/browser/api/usb/usb_event_router.cc')
-rw-r--r--chromium/extensions/browser/api/usb/usb_event_router.cc134
1 files changed, 134 insertions, 0 deletions
diff --git a/chromium/extensions/browser/api/usb/usb_event_router.cc b/chromium/extensions/browser/api/usb/usb_event_router.cc
new file mode 100644
index 00000000000..8c8acdd4a3d
--- /dev/null
+++ b/chromium/extensions/browser/api/usb/usb_event_router.cc
@@ -0,0 +1,134 @@
+// 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 "extensions/browser/api/usb/usb_event_router.h"
+
+#include <utility>
+
+#include "device/core/device_client.h"
+#include "device/usb/usb_device.h"
+#include "extensions/browser/api/device_permissions_manager.h"
+#include "extensions/browser/api/usb/usb_guid_map.h"
+#include "extensions/browser/event_router_factory.h"
+#include "extensions/common/api/usb.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/permissions/usb_device_permission.h"
+
+namespace usb = extensions::api::usb;
+
+using content::BrowserThread;
+using device::UsbDevice;
+using device::UsbService;
+
+namespace extensions {
+
+namespace {
+
+// Returns true iff the given extension has permission to receive events
+// regarding this device.
+bool WillDispatchDeviceEvent(scoped_refptr<UsbDevice> device,
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ Event* event,
+ const base::DictionaryValue* listener_filter) {
+ // Check install-time and optional permissions.
+ UsbDevicePermission::CheckParam param(
+ device->vendor_id(), device->product_id(),
+ UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
+ if (extension->permissions_data()->CheckAPIPermissionWithParam(
+ APIPermission::kUsbDevice, &param)) {
+ return true;
+ }
+
+ // Check permissions granted through chrome.usb.getUserSelectedDevices.
+ DevicePermissions* device_permissions =
+ DevicePermissionsManager::Get(browser_context)
+ ->GetForExtension(extension->id());
+ if (device_permissions->FindUsbDeviceEntry(device).get()) {
+ return true;
+ }
+
+ return false;
+}
+
+base::LazyInstance<BrowserContextKeyedAPIFactory<UsbEventRouter>>::Leaky
+ g_event_router_factory = LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+// static
+BrowserContextKeyedAPIFactory<UsbEventRouter>*
+UsbEventRouter::GetFactoryInstance() {
+ return g_event_router_factory.Pointer();
+}
+
+UsbEventRouter::UsbEventRouter(content::BrowserContext* browser_context)
+ : browser_context_(browser_context), observer_(this) {
+ EventRouter* event_router = EventRouter::Get(browser_context_);
+ if (event_router) {
+ event_router->RegisterObserver(this, usb::OnDeviceAdded::kEventName);
+ event_router->RegisterObserver(this, usb::OnDeviceRemoved::kEventName);
+ }
+}
+
+UsbEventRouter::~UsbEventRouter() {
+}
+
+void UsbEventRouter::Shutdown() {
+ EventRouter* event_router = EventRouter::Get(browser_context_);
+ if (event_router) {
+ event_router->UnregisterObserver(this);
+ }
+}
+
+void UsbEventRouter::OnListenerAdded(const EventListenerInfo& details) {
+ UsbService* service = device::DeviceClient::Get()->GetUsbService();
+ if (!observer_.IsObserving(service)) {
+ observer_.Add(service);
+ }
+}
+
+void UsbEventRouter::OnDeviceAdded(scoped_refptr<device::UsbDevice> device) {
+ DispatchEvent(usb::OnDeviceAdded::kEventName, device);
+}
+
+void UsbEventRouter::OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) {
+ DispatchEvent(usb::OnDeviceRemoved::kEventName, device);
+}
+
+void UsbEventRouter::DispatchEvent(const std::string& event_name,
+ scoped_refptr<UsbDevice> device) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ EventRouter* event_router = EventRouter::Get(browser_context_);
+ if (event_router) {
+ usb::Device device_obj;
+ UsbGuidMap::Get(browser_context_)->GetApiDevice(device, &device_obj);
+
+ scoped_ptr<Event> event;
+ if (event_name == usb::OnDeviceAdded::kEventName) {
+ event.reset(new Event(events::USB_ON_DEVICE_ADDED,
+ usb::OnDeviceAdded::kEventName,
+ usb::OnDeviceAdded::Create(device_obj)));
+ } else {
+ DCHECK(event_name == usb::OnDeviceRemoved::kEventName);
+ event.reset(new Event(events::USB_ON_DEVICE_REMOVED,
+ usb::OnDeviceRemoved::kEventName,
+ usb::OnDeviceRemoved::Create(device_obj)));
+ }
+
+ event->will_dispatch_callback =
+ base::Bind(&WillDispatchDeviceEvent, device);
+ event_router->BroadcastEvent(std::move(event));
+ }
+}
+
+template <>
+void BrowserContextKeyedAPIFactory<
+ UsbEventRouter>::DeclareFactoryDependencies() {
+ DependsOn(DevicePermissionsManagerFactory::GetInstance());
+ DependsOn(EventRouterFactory::GetInstance());
+ DependsOn(UsbGuidMap::GetFactoryInstance());
+}
+
+} // extensions