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/common/api/usb.h"
12 #include "extensions/common/permissions/permissions_data.h"
13 #include "extensions/common/permissions/usb_device_permission.h"
15 namespace usb
= extensions::api::usb
;
17 using content::BrowserThread
;
18 using device::UsbDevice
;
19 using device::UsbService
;
21 namespace extensions
{
25 // Returns true iff the given extension has permission to receive events
26 // regarding this device.
27 bool WillDispatchDeviceEvent(scoped_refptr
<UsbDevice
> device
,
28 content::BrowserContext
* browser_context
,
29 const Extension
* extension
,
30 base::ListValue
* event_args
,
31 const base::DictionaryValue
* listener_filter
) {
32 // Check install-time and optional permissions.
33 UsbDevicePermission::CheckParam
param(
34 device
->vendor_id(), device
->product_id(),
35 UsbDevicePermissionData::UNSPECIFIED_INTERFACE
);
36 if (extension
->permissions_data()->CheckAPIPermissionWithParam(
37 APIPermission::kUsbDevice
, ¶m
)) {
41 // Check permissions granted through chrome.usb.getUserSelectedDevices.
42 DevicePermissions
* device_permissions
=
43 DevicePermissionsManager::Get(browser_context
)
44 ->GetForExtension(extension
->id());
45 if (device_permissions
->FindUsbDeviceEntry(device
).get()) {
52 base::LazyInstance
<BrowserContextKeyedAPIFactory
<UsbEventRouter
>>::Leaky
53 g_event_router_factory
= LAZY_INSTANCE_INITIALIZER
;
58 BrowserContextKeyedAPIFactory
<UsbEventRouter
>*
59 UsbEventRouter::GetFactoryInstance() {
60 return g_event_router_factory
.Pointer();
63 UsbEventRouter::UsbEventRouter(content::BrowserContext
* browser_context
)
64 : browser_context_(browser_context
), observer_(this) {
65 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
67 event_router
->RegisterObserver(this, usb::OnDeviceAdded::kEventName
);
68 event_router
->RegisterObserver(this, usb::OnDeviceRemoved::kEventName
);
72 UsbEventRouter::~UsbEventRouter() {
75 void UsbEventRouter::Shutdown() {
76 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
78 event_router
->UnregisterObserver(this);
82 void UsbEventRouter::OnListenerAdded(const EventListenerInfo
& details
) {
83 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
84 if (!observer_
.IsObserving(service
)) {
85 observer_
.Add(service
);
89 void UsbEventRouter::OnDeviceAdded(scoped_refptr
<device::UsbDevice
> device
) {
90 DispatchEvent(usb::OnDeviceAdded::kEventName
, device
);
93 void UsbEventRouter::OnDeviceRemoved(scoped_refptr
<device::UsbDevice
> device
) {
94 DispatchEvent(usb::OnDeviceRemoved::kEventName
, device
);
97 void UsbEventRouter::DispatchEvent(const std::string
& event_name
,
98 scoped_refptr
<UsbDevice
> device
) {
99 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
100 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
102 usb::Device device_obj
;
104 UsbGuidMap::Get(browser_context_
)->GetIdFromGuid(device
->guid());
105 device_obj
.vendor_id
= device
->vendor_id();
106 device_obj
.product_id
= device
->product_id();
108 scoped_ptr
<Event
> event
;
109 if (event_name
== usb::OnDeviceAdded::kEventName
) {
110 event
.reset(new Event(events::USB_ON_DEVICE_ADDED
,
111 usb::OnDeviceAdded::kEventName
,
112 usb::OnDeviceAdded::Create(device_obj
)));
114 DCHECK(event_name
== usb::OnDeviceRemoved::kEventName
);
115 event
.reset(new Event(events::USB_ON_DEVICE_REMOVED
,
116 usb::OnDeviceRemoved::kEventName
,
117 usb::OnDeviceRemoved::Create(device_obj
)));
120 event
->will_dispatch_callback
=
121 base::Bind(&WillDispatchDeviceEvent
, device
);
122 event_router
->BroadcastEvent(event
.Pass());
127 void BrowserContextKeyedAPIFactory
<
128 UsbEventRouter
>::DeclareFactoryDependencies() {
129 DependsOn(DevicePermissionsManagerFactory::GetInstance());
130 DependsOn(UsbGuidMap::GetFactoryInstance());