1 // Copyright 2014 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 #ifndef EXTENSIONS_DEVICE_PERMISSION_MANAGER_H_
6 #define EXTENSIONS_DEVICE_PERMISSION_MANAGER_H_
12 #include "base/gtest_prod_util.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/scoped_observer.h"
17 #include "base/strings/string16.h"
18 #include "base/threading/thread_checker.h"
19 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
20 #include "components/keyed_service/core/keyed_service.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "device/usb/usb_service.h"
23 #include "extensions/browser/process_manager.h"
24 #include "extensions/browser/process_manager_observer.h"
27 struct DefaultSingletonTraits
;
37 namespace extensions
{
39 // Stores information about a device saved with access granted.
40 class DevicePermissionEntry
41 : public base::RefCountedThreadSafe
<DevicePermissionEntry
> {
43 DevicePermissionEntry(scoped_refptr
<device::UsbDevice
> device
);
44 DevicePermissionEntry(uint16_t vendor_id
,
46 const base::string16
& serial_number
,
47 const base::string16
& manufacturer_string
,
48 const base::string16
& product_string
,
49 const base::Time
& last_used
);
51 // A persistent device is one that can be recognized when it is reconnected
52 // and can therefore be remembered persistently by writing information about
53 // it to ExtensionPrefs. Currently this means it has a serial number string.
54 bool IsPersistent() const;
56 // Convert the device to a serializable value, returns a null pointer if the
57 // entry is not persistent.
58 scoped_ptr
<base::Value
> ToValue() const;
60 base::string16
GetPermissionMessageString() const;
62 uint16_t vendor_id() const { return vendor_id_
; }
63 uint16_t product_id() const { return product_id_
; }
64 const base::string16
& serial_number() const { return serial_number_
; }
65 const base::Time
& last_used() const { return last_used_
; }
67 base::string16
GetManufacturer() const;
68 base::string16
GetProduct() const;
71 friend class base::RefCountedThreadSafe
<DevicePermissionEntry
>;
72 friend class DevicePermissionsManager
;
74 ~DevicePermissionEntry();
76 void set_last_used(const base::Time
& last_used
) { last_used_
= last_used
; }
78 // The USB device tracked by this entry, may be null if this entry was
79 // restored from ExtensionPrefs.
80 scoped_refptr
<device::UsbDevice
> device_
;
81 // The vendor ID of this device.
83 // The product ID of this device.
85 // The serial number (possibly alphanumeric) of this device.
86 base::string16 serial_number_
;
87 // The manufacturer string read from the device (optional).
88 base::string16 manufacturer_string_
;
89 // The product string read from the device (optional).
90 base::string16 product_string_
;
91 // The last time this device was used by the extension.
92 base::Time last_used_
;
95 // Stores device permissions associated with a particular extension.
96 class DevicePermissions
{
98 virtual ~DevicePermissions();
100 // Attempts to find a permission entry matching the given device. The device
101 // serial number is presented separately so that this function does not need
102 // to call device->GetSerialNumber() which may not be possible on the
104 scoped_refptr
<DevicePermissionEntry
> FindEntry(
105 scoped_refptr
<device::UsbDevice
> device
) const;
107 const std::set
<scoped_refptr
<DevicePermissionEntry
>>& entries() const {
112 friend class DevicePermissionsManager
;
114 // Reads permissions out of ExtensionPrefs.
115 DevicePermissions(content::BrowserContext
* context
,
116 const std::string
& extension_id
);
118 std::set
<scoped_refptr
<DevicePermissionEntry
>> entries_
;
119 std::map
<scoped_refptr
<device::UsbDevice
>,
120 scoped_refptr
<DevicePermissionEntry
>> ephemeral_devices_
;
122 DISALLOW_COPY_AND_ASSIGN(DevicePermissions
);
125 // Manages saved device permissions for all extensions.
126 class DevicePermissionsManager
: public KeyedService
,
127 public base::NonThreadSafe
,
128 public ProcessManagerObserver
,
129 public device::UsbService::Observer
{
131 static DevicePermissionsManager
* Get(content::BrowserContext
* context
);
133 // The DevicePermissions object for a given extension.
134 DevicePermissions
* GetForExtension(const std::string
& extension_id
);
136 // Equivalent to calling GetForExtension and extracting the permission string
138 std::vector
<base::string16
> GetPermissionMessageStrings(
139 const std::string
& extension_id
) const;
141 void AllowUsbDevice(const std::string
& extension_id
,
142 scoped_refptr
<device::UsbDevice
> device
);
144 // Updates the "last used" timestamp on the given device entry and writes it
145 // out to ExtensionPrefs.
146 void UpdateLastUsed(const std::string
& extension_id
,
147 scoped_refptr
<DevicePermissionEntry
> entry
);
149 // Revokes permission for the extension to access the given device.
150 void RemoveEntry(const std::string
& extension_id
,
151 scoped_refptr
<DevicePermissionEntry
> entry
);
153 // Revokes permission for the extension to access all allowed devices.
154 void Clear(const std::string
& extension_id
);
158 friend class DevicePermissionsManagerFactory
;
159 FRIEND_TEST_ALL_PREFIXES(DevicePermissionsManagerTest
, SuspendExtension
);
161 DevicePermissionsManager(content::BrowserContext
* context
);
162 ~DevicePermissionsManager() override
;
164 DevicePermissions
* GetInternal(const std::string
& extension_id
) const;
166 // ProcessManagerObserver implementation
167 void OnBackgroundHostClose(const std::string
& extension_id
) override
;
169 // UsbService::Observer implementation
170 void OnDeviceRemovedCleanup(scoped_refptr
<device::UsbDevice
> device
) override
;
172 content::BrowserContext
* context_
;
173 std::map
<std::string
, DevicePermissions
*> extension_id_to_device_permissions_
;
174 ScopedObserver
<ProcessManager
, ProcessManagerObserver
>
175 process_manager_observer_
;
176 ScopedObserver
<device::UsbService
, device::UsbService::Observer
>
177 usb_service_observer_
;
179 DISALLOW_COPY_AND_ASSIGN(DevicePermissionsManager
);
182 class DevicePermissionsManagerFactory
183 : public BrowserContextKeyedServiceFactory
{
185 static DevicePermissionsManager
* GetForBrowserContext(
186 content::BrowserContext
* context
);
187 static DevicePermissionsManagerFactory
* GetInstance();
190 friend struct DefaultSingletonTraits
<DevicePermissionsManagerFactory
>;
192 DevicePermissionsManagerFactory();
193 ~DevicePermissionsManagerFactory() override
;
195 // BrowserContextKeyedServiceFactory implementation
196 KeyedService
* BuildServiceInstanceFor(
197 content::BrowserContext
* context
) const override
;
198 content::BrowserContext
* GetBrowserContextToUse(
199 content::BrowserContext
* context
) const override
;
201 DISALLOW_COPY_AND_ASSIGN(DevicePermissionsManagerFactory
);
204 } // namespace extensions
206 #endif // EXTENSIONS_DEVICE_PERMISSION_MANAGER_H_