Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / extensions / browser / api / usb / usb_event_router.cc
blobcb6a518e4efb84f84bbdae882372f597ff54c26e
1 // Copyright 2015 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.
5 #include "extensions/browser/api/usb/usb_event_router.h"
7 #include "device/core/device_client.h"
8 #include "device/usb/usb_device.h"
9 #include "extensions/browser/api/device_permissions_manager.h"
10 #include "extensions/browser/api/usb/usb_guid_map.h"
11 #include "extensions/browser/event_router_factory.h"
12 #include "extensions/common/api/usb.h"
13 #include "extensions/common/permissions/permissions_data.h"
14 #include "extensions/common/permissions/usb_device_permission.h"
16 namespace usb = extensions::api::usb;
18 using content::BrowserThread;
19 using device::UsbDevice;
20 using device::UsbService;
22 namespace extensions {
24 namespace {
26 // Returns true iff the given extension has permission to receive events
27 // regarding this device.
28 bool WillDispatchDeviceEvent(scoped_refptr<UsbDevice> device,
29 content::BrowserContext* browser_context,
30 const Extension* extension,
31 Event* event,
32 const base::DictionaryValue* listener_filter) {
33 // Check install-time and optional permissions.
34 UsbDevicePermission::CheckParam param(
35 device->vendor_id(), device->product_id(),
36 UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
37 if (extension->permissions_data()->CheckAPIPermissionWithParam(
38 APIPermission::kUsbDevice, &param)) {
39 return true;
42 // Check permissions granted through chrome.usb.getUserSelectedDevices.
43 DevicePermissions* device_permissions =
44 DevicePermissionsManager::Get(browser_context)
45 ->GetForExtension(extension->id());
46 if (device_permissions->FindUsbDeviceEntry(device).get()) {
47 return true;
50 return false;
53 base::LazyInstance<BrowserContextKeyedAPIFactory<UsbEventRouter>>::Leaky
54 g_event_router_factory = LAZY_INSTANCE_INITIALIZER;
56 } // namespace
58 // static
59 BrowserContextKeyedAPIFactory<UsbEventRouter>*
60 UsbEventRouter::GetFactoryInstance() {
61 return g_event_router_factory.Pointer();
64 UsbEventRouter::UsbEventRouter(content::BrowserContext* browser_context)
65 : browser_context_(browser_context), observer_(this) {
66 EventRouter* event_router = EventRouter::Get(browser_context_);
67 if (event_router) {
68 event_router->RegisterObserver(this, usb::OnDeviceAdded::kEventName);
69 event_router->RegisterObserver(this, usb::OnDeviceRemoved::kEventName);
73 UsbEventRouter::~UsbEventRouter() {
76 void UsbEventRouter::Shutdown() {
77 EventRouter* event_router = EventRouter::Get(browser_context_);
78 if (event_router) {
79 event_router->UnregisterObserver(this);
83 void UsbEventRouter::OnListenerAdded(const EventListenerInfo& details) {
84 UsbService* service = device::DeviceClient::Get()->GetUsbService();
85 if (!observer_.IsObserving(service)) {
86 observer_.Add(service);
90 void UsbEventRouter::OnDeviceAdded(scoped_refptr<device::UsbDevice> device) {
91 DispatchEvent(usb::OnDeviceAdded::kEventName, device);
94 void UsbEventRouter::OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) {
95 DispatchEvent(usb::OnDeviceRemoved::kEventName, device);
98 void UsbEventRouter::DispatchEvent(const std::string& event_name,
99 scoped_refptr<UsbDevice> device) {
100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
101 EventRouter* event_router = EventRouter::Get(browser_context_);
102 if (event_router) {
103 usb::Device device_obj;
104 UsbGuidMap::Get(browser_context_)->GetApiDevice(device, &device_obj);
106 scoped_ptr<Event> event;
107 if (event_name == usb::OnDeviceAdded::kEventName) {
108 event.reset(new Event(events::USB_ON_DEVICE_ADDED,
109 usb::OnDeviceAdded::kEventName,
110 usb::OnDeviceAdded::Create(device_obj)));
111 } else {
112 DCHECK(event_name == usb::OnDeviceRemoved::kEventName);
113 event.reset(new Event(events::USB_ON_DEVICE_REMOVED,
114 usb::OnDeviceRemoved::kEventName,
115 usb::OnDeviceRemoved::Create(device_obj)));
118 event->will_dispatch_callback =
119 base::Bind(&WillDispatchDeviceEvent, device);
120 event_router->BroadcastEvent(event.Pass());
124 template <>
125 void BrowserContextKeyedAPIFactory<
126 UsbEventRouter>::DeclareFactoryDependencies() {
127 DependsOn(DevicePermissionsManagerFactory::GetInstance());
128 DependsOn(EventRouterFactory::GetInstance());
129 DependsOn(UsbGuidMap::GetFactoryInstance());
132 } // extensions