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
{
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
,
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
, ¶m
)) {
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()) {
53 base::LazyInstance
<BrowserContextKeyedAPIFactory
<UsbEventRouter
>>::Leaky
54 g_event_router_factory
= LAZY_INSTANCE_INITIALIZER
;
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_
);
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_
);
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_
);
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
)));
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());
125 void BrowserContextKeyedAPIFactory
<
126 UsbEventRouter
>::DeclareFactoryDependencies() {
127 DependsOn(DevicePermissionsManagerFactory::GetInstance());
128 DependsOn(EventRouterFactory::GetInstance());
129 DependsOn(UsbGuidMap::GetFactoryInstance());