From 4ebb03e08ae49fb5be8306f34bb18c9da905a4aa Mon Sep 17 00:00:00 2001 From: reillyg Date: Tue, 6 Jan 2015 12:58:08 -0800 Subject: Add an Observer interface to UsbService for device add/remove. On platforms where libusb supports hotplug events this observer interface allows clients of UsbService to be notified when devices are added and removed from the system. When hotplug events are not available these events are only generated in response to an explicit enumeration request. The UsbDevice::Observer interface has been removed so that UsbDevice can be a truly thread-safe object. BUG=411715 Review URL: https://codereview.chromium.org/809743006 Cr-Commit-Position: refs/heads/master@{#310140} --- .../browser/api/device_permissions_manager.cc | 36 +++++++++++++--------- .../browser/api/device_permissions_manager.h | 14 ++++----- 2 files changed, 27 insertions(+), 23 deletions(-) (limited to 'extensions') diff --git a/extensions/browser/api/device_permissions_manager.cc b/extensions/browser/api/device_permissions_manager.cc index 87f52f0..0050320 100644 --- a/extensions/browser/api/device_permissions_manager.cc +++ b/extensions/browser/api/device_permissions_manager.cc @@ -10,6 +10,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "device/core/device_client.h" +#include "device/usb/usb_device.h" #include "device/usb/usb_ids.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_prefs.h" @@ -438,7 +440,16 @@ void DevicePermissionsManager::AllowUsbDevice( // Register an observer here so that this set doesn't grow undefinitely. device_permissions->entries_.insert(device_entry); device_permissions->ephemeral_devices_[device] = device_entry; - device->AddObserver(this); + + // Only start observing when an ephemeral device has been added so that + // UsbService is not automatically initialized on profile creation (which it + // would be if this call were in the constructor). + device::UsbService* usb_service = + device::DeviceClient::Get()->GetUsbService(); + DCHECK(usb_service); + if (!usb_service_observer_.IsObserving(usb_service)) { + usb_service_observer_.Add(usb_service); + } } } @@ -464,7 +475,6 @@ void DevicePermissionsManager::RemoveEntry( RemoveDevicePermissionEntry(context_, extension_id, entry); } else { device_permissions->ephemeral_devices_.erase(entry->device_); - entry->device_->RemoveObserver(this); } } @@ -474,9 +484,6 @@ void DevicePermissionsManager::Clear(const std::string& extension_id) { ClearDevicePermissionEntries(ExtensionPrefs::Get(context_), extension_id); DevicePermissions* device_permissions = Get(extension_id); if (device_permissions) { - for (const auto& device_entry : device_permissions->ephemeral_devices_) { - device_entry.first->RemoveObserver(this); - } extension_id_to_device_permissions_.erase(extension_id); delete device_permissions; } @@ -484,16 +491,15 @@ void DevicePermissionsManager::Clear(const std::string& extension_id) { DevicePermissionsManager::DevicePermissionsManager( content::BrowserContext* context) - : context_(context), process_manager_observer_(this) { + : context_(context), + process_manager_observer_(this), + usb_service_observer_(this) { process_manager_observer_.Add(ProcessManager::Get(context)); } DevicePermissionsManager::~DevicePermissionsManager() { for (const auto& map_entry : extension_id_to_device_permissions_) { DevicePermissions* device_permissions = map_entry.second; - for (const auto& device_entry : device_permissions->ephemeral_devices_) { - device_entry.first->RemoveObserver(this); - } delete device_permissions; } } @@ -529,24 +535,24 @@ void DevicePermissionsManager::OnBackgroundHostClose( // When all of the app's windows are closed and the background page is // suspended all ephemeral device permissions are cleared. for (const auto& map_entry : device_permissions->ephemeral_devices_) { - map_entry.first->RemoveObserver(this); device_permissions->entries_.erase(map_entry.second); } device_permissions->ephemeral_devices_.clear(); } } -void DevicePermissionsManager::OnDisconnect(scoped_refptr device) { +void DevicePermissionsManager::OnDeviceRemoved( + scoped_refptr device) { for (const auto& map_entry : extension_id_to_device_permissions_) { // An ephemeral device cannot be identified if it is reconnected and so // permission to access it is cleared on disconnect. DevicePermissions* device_permissions = map_entry.second; const auto& device_entry = device_permissions->ephemeral_devices_.find(device); - DCHECK(device_entry != device_permissions->ephemeral_devices_.end()); - device_permissions->entries_.erase(device_entry->second); - device_permissions->ephemeral_devices_.erase(device); - device->RemoveObserver(this); + if (device_entry != device_permissions->ephemeral_devices_.end()) { + device_permissions->entries_.erase(device_entry->second); + device_permissions->ephemeral_devices_.erase(device); + } } } diff --git a/extensions/browser/api/device_permissions_manager.h b/extensions/browser/api/device_permissions_manager.h index 647addc..52a1bd9 100644 --- a/extensions/browser/api/device_permissions_manager.h +++ b/extensions/browser/api/device_permissions_manager.h @@ -18,7 +18,7 @@ #include "base/threading/thread_checker.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/core/keyed_service.h" -#include "device/usb/usb_device.h" +#include "device/usb/usb_service.h" #include "extensions/browser/process_manager.h" #include "extensions/browser/process_manager_observer.h" @@ -33,10 +33,6 @@ namespace content { class BrowserContext; } -namespace device { -class UsbDevice; -} - namespace extensions { // Stores information about a device saved with access granted. @@ -136,7 +132,7 @@ class DevicePermissions { class DevicePermissionsManager : public KeyedService, public base::NonThreadSafe, public ProcessManagerObserver, - public device::UsbDevice::Observer { + public device::UsbService::Observer { public: static DevicePermissionsManager* Get(content::BrowserContext* context); @@ -184,13 +180,15 @@ class DevicePermissionsManager : public KeyedService, // ProcessManagerObserver implementation void OnBackgroundHostClose(const std::string& extension_id) override; - // device::UsbDevice::Observer implementation - void OnDisconnect(scoped_refptr device) override; + // device::UsbService::Observer implementation + void OnDeviceRemoved(scoped_refptr device) override; content::BrowserContext* context_; std::map extension_id_to_device_permissions_; ScopedObserver process_manager_observer_; + ScopedObserver + usb_service_observer_; DISALLOW_COPY_AND_ASSIGN(DevicePermissionsManager); }; -- cgit v1.1