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/common/api/usb.h"
11 #include "extensions/common/permissions/permissions_data.h"
12 #include "extensions/common/permissions/usb_device_permission.h"
14 namespace usb
= extensions::core_api::usb
;
16 using content::BrowserThread
;
17 using device::UsbDevice
;
18 using device::UsbService
;
20 namespace extensions
{
24 // Returns true iff the given extension has permission to receive events
25 // regarding this device.
26 bool WillDispatchDeviceEvent(scoped_refptr
<UsbDevice
> device
,
27 content::BrowserContext
* browser_context
,
28 const Extension
* extension
,
29 base::ListValue
* event_args
) {
30 // Check install-time and optional permissions.
31 UsbDevicePermission::CheckParam
param(
32 device
->vendor_id(), device
->product_id(),
33 UsbDevicePermissionData::UNSPECIFIED_INTERFACE
);
34 if (extension
->permissions_data()->CheckAPIPermissionWithParam(
35 APIPermission::kUsbDevice
, ¶m
)) {
39 // Check permissions granted through chrome.usb.getUserSelectedDevices.
40 DevicePermissions
* device_permissions
=
41 DevicePermissionsManager::Get(browser_context
)
42 ->GetForExtension(extension
->id());
43 if (device_permissions
->FindUsbDeviceEntry(device
).get()) {
50 base::LazyInstance
<BrowserContextKeyedAPIFactory
<UsbEventRouter
>>::Leaky
51 g_event_router_factory
= LAZY_INSTANCE_INITIALIZER
;
56 BrowserContextKeyedAPIFactory
<UsbEventRouter
>*
57 UsbEventRouter::GetFactoryInstance() {
58 return g_event_router_factory
.Pointer();
61 UsbEventRouter::UsbEventRouter(content::BrowserContext
* browser_context
)
62 : browser_context_(browser_context
), observer_(this) {
63 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
65 event_router
->RegisterObserver(this, usb::OnDeviceAdded::kEventName
);
66 event_router
->RegisterObserver(this, usb::OnDeviceRemoved::kEventName
);
70 UsbEventRouter::~UsbEventRouter() {
73 void UsbEventRouter::Shutdown() {
74 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
76 event_router
->UnregisterObserver(this);
80 void UsbEventRouter::OnListenerAdded(const EventListenerInfo
& details
) {
81 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
82 if (!observer_
.IsObserving(service
)) {
83 observer_
.Add(service
);
87 void UsbEventRouter::OnDeviceAdded(scoped_refptr
<device::UsbDevice
> device
) {
88 DispatchEvent(usb::OnDeviceAdded::kEventName
, device
);
91 void UsbEventRouter::OnDeviceRemoved(scoped_refptr
<device::UsbDevice
> device
) {
92 DispatchEvent(usb::OnDeviceRemoved::kEventName
, device
);
95 void UsbEventRouter::DispatchEvent(const std::string
& event_name
,
96 scoped_refptr
<UsbDevice
> device
) {
97 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
98 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
100 usb::Device device_obj
;
101 device_obj
.device
= device
->unique_id();
102 device_obj
.vendor_id
= device
->vendor_id();
103 device_obj
.product_id
= device
->product_id();
105 scoped_ptr
<Event
> event
;
106 if (event_name
== usb::OnDeviceAdded::kEventName
) {
107 event
.reset(new Event(usb::OnDeviceAdded::kEventName
,
108 usb::OnDeviceAdded::Create(device_obj
)));
110 DCHECK(event_name
== usb::OnDeviceRemoved::kEventName
);
111 event
.reset(new Event(usb::OnDeviceRemoved::kEventName
,
112 usb::OnDeviceRemoved::Create(device_obj
)));
115 event
->will_dispatch_callback
=
116 base::Bind(&WillDispatchDeviceEvent
, device
);
117 event_router
->BroadcastEvent(event
.Pass());