| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/browser/api/usb/usb_event_router.h" | 5 #include "extensions/browser/api/usb/usb_event_router.h" |
| 6 | 6 |
| 7 #include "device/core/device_client.h" | 7 #include "device/core/device_client.h" |
| 8 #include "device/usb/usb_device.h" | 8 #include "device/usb/usb_device.h" |
| 9 #include "device/usb/usb_service.h" | |
| 10 #include "extensions/browser/api/device_permissions_manager.h" | 9 #include "extensions/browser/api/device_permissions_manager.h" |
| 11 #include "extensions/common/api/usb.h" | 10 #include "extensions/common/api/usb.h" |
| 12 #include "extensions/common/permissions/permissions_data.h" | 11 #include "extensions/common/permissions/permissions_data.h" |
| 13 #include "extensions/common/permissions/usb_device_permission.h" | 12 #include "extensions/common/permissions/usb_device_permission.h" |
| 14 | 13 |
| 15 namespace usb = extensions::core_api::usb; | 14 namespace usb = extensions::core_api::usb; |
| 16 | 15 |
| 17 using content::BrowserThread; | 16 using content::BrowserThread; |
| 18 using device::UsbDevice; | 17 using device::UsbDevice; |
| 19 using device::UsbService; | 18 using device::UsbService; |
| 20 | 19 |
| 21 namespace extensions { | 20 namespace extensions { |
| 22 | 21 |
| 23 namespace { | 22 namespace { |
| 24 | 23 |
| 25 // Returns true iff the given extension has permission to receive events | 24 // Returns true iff the given extension has permission to receive events |
| 26 // regarding this device. | 25 // regarding this device. |
| 27 bool WillDispatchDeviceEvent(scoped_refptr<UsbDevice> device, | 26 bool WillDispatchDeviceEvent(scoped_refptr<UsbDevice> device, |
| 28 const base::string16& serial_number, | |
| 29 content::BrowserContext* browser_context, | 27 content::BrowserContext* browser_context, |
| 30 const Extension* extension, | 28 const Extension* extension, |
| 31 base::ListValue* event_args) { | 29 base::ListValue* event_args) { |
| 32 // Check install-time and optional permissions. | 30 // Check install-time and optional permissions. |
| 33 UsbDevicePermission::CheckParam param( | 31 UsbDevicePermission::CheckParam param( |
| 34 device->vendor_id(), device->product_id(), | 32 device->vendor_id(), device->product_id(), |
| 35 UsbDevicePermissionData::UNSPECIFIED_INTERFACE); | 33 UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
| 36 if (extension->permissions_data()->CheckAPIPermissionWithParam( | 34 if (extension->permissions_data()->CheckAPIPermissionWithParam( |
| 37 APIPermission::kUsbDevice, ¶m)) { | 35 APIPermission::kUsbDevice, ¶m)) { |
| 38 return true; | 36 return true; |
| 39 } | 37 } |
| 40 | 38 |
| 41 // Check permissions granted through chrome.usb.getUserSelectedDevices. | 39 // Check permissions granted through chrome.usb.getUserSelectedDevices. |
| 42 scoped_ptr<DevicePermissions> device_permissions = | 40 DevicePermissions* device_permissions = |
| 43 DevicePermissionsManager::Get(browser_context) | 41 DevicePermissionsManager::Get(browser_context) |
| 44 ->GetForExtension(extension->id()); | 42 ->GetForExtension(extension->id()); |
| 45 if (device_permissions->FindEntry(device, serial_number).get()) { | 43 if (device_permissions->FindEntry(device).get()) { |
| 46 return true; | 44 return true; |
| 47 } | 45 } |
| 48 | 46 |
| 49 return false; | 47 return false; |
| 50 } | 48 } |
| 51 | 49 |
| 52 base::LazyInstance<BrowserContextKeyedAPIFactory<UsbEventRouter>>::Leaky | 50 base::LazyInstance<BrowserContextKeyedAPIFactory<UsbEventRouter>>::Leaky |
| 53 g_event_router_factory = LAZY_INSTANCE_INITIALIZER; | 51 g_event_router_factory = LAZY_INSTANCE_INITIALIZER; |
| 54 | 52 |
| 55 } // namespace | 53 } // namespace |
| 56 | 54 |
| 57 class UsbEventRouter::FileThreadHelper : public UsbService::Observer { | |
| 58 public: | |
| 59 FileThreadHelper(base::WeakPtr<UsbEventRouter> usb_event_router) | |
| 60 : usb_event_router_(usb_event_router), observer_(this) {} | |
| 61 virtual ~FileThreadHelper() {} | |
| 62 | |
| 63 void Start() { | |
| 64 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | |
| 65 UsbService* service = device::DeviceClient::Get()->GetUsbService(); | |
| 66 if (service) { | |
| 67 observer_.Add(service); | |
| 68 } | |
| 69 } | |
| 70 | |
| 71 private: | |
| 72 // UsbService::Observer implementation. | |
| 73 void OnDeviceAdded(scoped_refptr<device::UsbDevice> device) override { | |
| 74 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | |
| 75 | |
| 76 base::string16 serial_number; | |
| 77 device->GetSerialNumber(&serial_number); | |
| 78 | |
| 79 BrowserThread::PostTask( | |
| 80 BrowserThread::UI, FROM_HERE, | |
| 81 base::Bind(&UsbEventRouter::DispatchEvent, usb_event_router_, | |
| 82 usb::OnDeviceAdded::kEventName, device, serial_number)); | |
| 83 } | |
| 84 | |
| 85 void OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) override { | |
| 86 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | |
| 87 | |
| 88 base::string16 serial_number; | |
| 89 device->GetSerialNumber(&serial_number); | |
| 90 | |
| 91 BrowserThread::PostTask( | |
| 92 BrowserThread::UI, FROM_HERE, | |
| 93 base::Bind(&UsbEventRouter::DispatchEvent, usb_event_router_, | |
| 94 usb::OnDeviceRemoved::kEventName, device, serial_number)); | |
| 95 } | |
| 96 | |
| 97 base::WeakPtr<UsbEventRouter> usb_event_router_; | |
| 98 ScopedObserver<device::UsbService, device::UsbService::Observer> observer_; | |
| 99 }; | |
| 100 | |
| 101 // static | 55 // static |
| 102 BrowserContextKeyedAPIFactory<UsbEventRouter>* | 56 BrowserContextKeyedAPIFactory<UsbEventRouter>* |
| 103 UsbEventRouter::GetFactoryInstance() { | 57 UsbEventRouter::GetFactoryInstance() { |
| 104 return g_event_router_factory.Pointer(); | 58 return g_event_router_factory.Pointer(); |
| 105 } | 59 } |
| 106 | 60 |
| 107 UsbEventRouter::UsbEventRouter(content::BrowserContext* browser_context) | 61 UsbEventRouter::UsbEventRouter(content::BrowserContext* browser_context) |
| 108 : browser_context_(browser_context), weak_factory_(this) { | 62 : browser_context_(browser_context), observer_(this) { |
| 109 EventRouter* event_router = EventRouter::Get(browser_context_); | 63 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 110 if (event_router) { | 64 if (event_router) { |
| 111 event_router->RegisterObserver(this, usb::OnDeviceAdded::kEventName); | 65 event_router->RegisterObserver(this, usb::OnDeviceAdded::kEventName); |
| 112 event_router->RegisterObserver(this, usb::OnDeviceRemoved::kEventName); | 66 event_router->RegisterObserver(this, usb::OnDeviceRemoved::kEventName); |
| 113 } | 67 } |
| 114 } | 68 } |
| 115 | 69 |
| 116 UsbEventRouter::~UsbEventRouter() { | 70 UsbEventRouter::~UsbEventRouter() { |
| 117 } | 71 } |
| 118 | 72 |
| 119 void UsbEventRouter::Shutdown() { | 73 void UsbEventRouter::Shutdown() { |
| 120 EventRouter* event_router = EventRouter::Get(browser_context_); | 74 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 121 if (event_router) { | 75 if (event_router) { |
| 122 event_router->UnregisterObserver(this); | 76 event_router->UnregisterObserver(this); |
| 123 } | 77 } |
| 124 helper_.reset(nullptr); | |
| 125 } | 78 } |
| 126 | 79 |
| 127 void UsbEventRouter::OnListenerAdded(const EventListenerInfo& details) { | 80 void UsbEventRouter::OnListenerAdded(const EventListenerInfo& details) { |
| 128 if (!helper_) { | 81 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
| 129 helper_.reset(new FileThreadHelper(weak_factory_.GetWeakPtr())); | 82 if (!observer_.IsObserving(service)) { |
| 130 BrowserThread::PostTask( | 83 observer_.Add(service); |
| 131 BrowserThread::FILE, FROM_HERE, | |
| 132 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get()))); | |
| 133 } | 84 } |
| 134 } | 85 } |
| 135 | 86 |
| 87 void UsbEventRouter::OnDeviceAdded(scoped_refptr<device::UsbDevice> device) { |
| 88 DispatchEvent(usb::OnDeviceAdded::kEventName, device); |
| 89 } |
| 90 |
| 91 void UsbEventRouter::OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) { |
| 92 DispatchEvent(usb::OnDeviceRemoved::kEventName, device); |
| 93 } |
| 94 |
| 136 void UsbEventRouter::DispatchEvent(const std::string& event_name, | 95 void UsbEventRouter::DispatchEvent(const std::string& event_name, |
| 137 scoped_refptr<UsbDevice> device, | 96 scoped_refptr<UsbDevice> device) { |
| 138 const base::string16& serial_number) { | 97 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 139 EventRouter* event_router = EventRouter::Get(browser_context_); | 98 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 140 if (event_router) { | 99 if (event_router) { |
| 141 usb::Device device_obj; | 100 usb::Device device_obj; |
| 142 device_obj.device = device->unique_id(); | 101 device_obj.device = device->unique_id(); |
| 143 device_obj.vendor_id = device->vendor_id(); | 102 device_obj.vendor_id = device->vendor_id(); |
| 144 device_obj.product_id = device->product_id(); | 103 device_obj.product_id = device->product_id(); |
| 145 | 104 |
| 146 scoped_ptr<Event> event; | 105 scoped_ptr<Event> event; |
| 147 if (event_name == usb::OnDeviceAdded::kEventName) { | 106 if (event_name == usb::OnDeviceAdded::kEventName) { |
| 148 event.reset(new Event(usb::OnDeviceAdded::kEventName, | 107 event.reset(new Event(usb::OnDeviceAdded::kEventName, |
| 149 usb::OnDeviceAdded::Create(device_obj))); | 108 usb::OnDeviceAdded::Create(device_obj))); |
| 150 } else { | 109 } else { |
| 151 DCHECK(event_name == usb::OnDeviceRemoved::kEventName); | 110 DCHECK(event_name == usb::OnDeviceRemoved::kEventName); |
| 152 event.reset(new Event(usb::OnDeviceRemoved::kEventName, | 111 event.reset(new Event(usb::OnDeviceRemoved::kEventName, |
| 153 usb::OnDeviceRemoved::Create(device_obj))); | 112 usb::OnDeviceRemoved::Create(device_obj))); |
| 154 } | 113 } |
| 155 | 114 |
| 156 event->will_dispatch_callback = | 115 event->will_dispatch_callback = |
| 157 base::Bind(&WillDispatchDeviceEvent, device, serial_number); | 116 base::Bind(&WillDispatchDeviceEvent, device); |
| 158 event_router->BroadcastEvent(event.Pass()); | 117 event_router->BroadcastEvent(event.Pass()); |
| 159 } | 118 } |
| 160 } | 119 } |
| 161 | 120 |
| 162 } // extensions | 121 } // extensions |
| OLD | NEW |