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 "device/hid/hid_service.h"
22 #include "device/usb/usb_service.h"
26 struct DefaultSingletonTraits
;
34 namespace extensions
{
36 // Stores information about a device saved with access granted.
37 class DevicePermissionEntry
: public base::RefCounted
<DevicePermissionEntry
> {
44 DevicePermissionEntry(scoped_refptr
<device::UsbDevice
> device
);
45 DevicePermissionEntry(scoped_refptr
<device::HidDeviceInfo
> device
);
46 DevicePermissionEntry(Type type
,
49 const base::string16
& serial_number
,
50 const base::string16
& manufacturer_string
,
51 const base::string16
& product_string
,
52 const base::Time
& last_used
);
54 // A persistent device is one that can be recognized when it is reconnected
55 // and can therefore be remembered persistently by writing information about
56 // it to ExtensionPrefs. Currently this means it has a serial number string.
57 bool IsPersistent() const;
59 // Convert the device to a serializable value, returns a null pointer if the
60 // entry is not persistent.
61 scoped_ptr
<base::Value
> ToValue() const;
63 base::string16
GetPermissionMessageString() const;
65 Type
type() const { return type_
; }
66 uint16_t vendor_id() const { return vendor_id_
; }
67 uint16_t product_id() const { return product_id_
; }
68 const base::string16
& serial_number() const { return serial_number_
; }
69 const base::Time
& last_used() const { return last_used_
; }
71 base::string16
GetManufacturer() const;
72 base::string16
GetProduct() const;
75 friend class base::RefCounted
<DevicePermissionEntry
>;
76 friend class DevicePermissionsManager
;
78 ~DevicePermissionEntry();
80 void set_last_used(const base::Time
& last_used
) { last_used_
= last_used
; }
82 // The USB device tracked by this entry. Will be nullptr if this entry was
83 // restored from ExtensionPrefs or type_ is not Type::USB.
84 scoped_refptr
<device::UsbDevice
> usb_device_
;
85 // The HID device tracked by this entry. Will be nullptr if this entry was
86 // restored from ExtensionPrefs or type_ is not Type::HID.
87 scoped_refptr
<device::HidDeviceInfo
> hid_device_
;
89 // The type of device this entry represents.
91 // The vendor ID of this device.
93 // The product ID of this device.
95 // The serial number (possibly alphanumeric) of this device.
96 base::string16 serial_number_
;
97 // The manufacturer string read from the device (optional).
98 base::string16 manufacturer_string_
;
99 // The product string read from the device (optional).
100 base::string16 product_string_
;
101 // The last time this device was used by the extension.
102 base::Time last_used_
;
105 // Stores device permissions associated with a particular extension.
106 class DevicePermissions
{
108 virtual ~DevicePermissions();
110 // Attempts to find a permission entry matching the given device.
111 scoped_refptr
<DevicePermissionEntry
> FindUsbDeviceEntry(
112 scoped_refptr
<device::UsbDevice
> device
) const;
113 scoped_refptr
<DevicePermissionEntry
> FindHidDeviceEntry(
114 scoped_refptr
<device::HidDeviceInfo
> device
) const;
116 const std::set
<scoped_refptr
<DevicePermissionEntry
>>& entries() const {
121 friend class DevicePermissionsManager
;
123 // Reads permissions out of ExtensionPrefs.
124 DevicePermissions(content::BrowserContext
* context
,
125 const std::string
& extension_id
);
127 std::set
<scoped_refptr
<DevicePermissionEntry
>> entries_
;
128 std::map
<device::UsbDevice
*, scoped_refptr
<DevicePermissionEntry
>>
129 ephemeral_usb_devices_
;
130 std::map
<device::HidDeviceInfo
*, scoped_refptr
<DevicePermissionEntry
>>
131 ephemeral_hid_devices_
;
133 DISALLOW_COPY_AND_ASSIGN(DevicePermissions
);
136 // Manages saved device permissions for all extensions.
137 class DevicePermissionsManager
: public KeyedService
,
138 public device::UsbService::Observer
,
139 public device::HidService::Observer
{
141 static DevicePermissionsManager
* Get(content::BrowserContext
* context
);
143 static base::string16
GetPermissionMessage(
146 const base::string16
& manufacturer_string
,
147 const base::string16
& product_string
,
148 const base::string16
& serial_number
,
149 bool always_include_manufacturer
);
151 // The DevicePermissions object for a given extension.
152 DevicePermissions
* GetForExtension(const std::string
& extension_id
);
154 // Equivalent to calling GetForExtension and extracting the permission string
156 std::vector
<base::string16
> GetPermissionMessageStrings(
157 const std::string
& extension_id
) const;
159 void AllowUsbDevice(const std::string
& extension_id
,
160 scoped_refptr
<device::UsbDevice
> device
);
161 void AllowHidDevice(const std::string
& extension_id
,
162 scoped_refptr
<device::HidDeviceInfo
> device
);
164 // Updates the "last used" timestamp on the given device entry and writes it
165 // out to ExtensionPrefs.
166 void UpdateLastUsed(const std::string
& extension_id
,
167 scoped_refptr
<DevicePermissionEntry
> entry
);
169 // Revokes permission for the extension to access the given device.
170 void RemoveEntry(const std::string
& extension_id
,
171 scoped_refptr
<DevicePermissionEntry
> entry
);
173 // Revokes permission for the extension to access all allowed devices.
174 void Clear(const std::string
& extension_id
);
178 friend class DevicePermissionsManagerFactory
;
179 FRIEND_TEST_ALL_PREFIXES(DevicePermissionsManagerTest
, SuspendExtension
);
181 DevicePermissionsManager(content::BrowserContext
* context
);
182 ~DevicePermissionsManager() override
;
184 DevicePermissions
* GetInternal(const std::string
& extension_id
) const;
186 // UsbService::Observer implementation
187 void OnDeviceRemovedCleanup(scoped_refptr
<device::UsbDevice
> device
) override
;
189 // HidService::Observer implementation
190 void OnDeviceRemovedCleanup(
191 scoped_refptr
<device::HidDeviceInfo
> device
) override
;
193 base::ThreadChecker thread_checker_
;
194 content::BrowserContext
* context_
;
195 std::map
<std::string
, DevicePermissions
*> extension_id_to_device_permissions_
;
196 ScopedObserver
<device::UsbService
, device::UsbService::Observer
>
197 usb_service_observer_
;
198 ScopedObserver
<device::HidService
, device::HidService::Observer
>
199 hid_service_observer_
;
201 DISALLOW_COPY_AND_ASSIGN(DevicePermissionsManager
);
204 class DevicePermissionsManagerFactory
205 : public BrowserContextKeyedServiceFactory
{
207 static DevicePermissionsManager
* GetForBrowserContext(
208 content::BrowserContext
* context
);
209 static DevicePermissionsManagerFactory
* GetInstance();
212 friend struct base::DefaultSingletonTraits
<DevicePermissionsManagerFactory
>;
214 DevicePermissionsManagerFactory();
215 ~DevicePermissionsManagerFactory() override
;
217 // BrowserContextKeyedServiceFactory implementation
218 KeyedService
* BuildServiceInstanceFor(
219 content::BrowserContext
* context
) const override
;
220 content::BrowserContext
* GetBrowserContextToUse(
221 content::BrowserContext
* context
) const override
;
223 DISALLOW_COPY_AND_ASSIGN(DevicePermissionsManagerFactory
);
226 } // namespace extensions
228 #endif // EXTENSIONS_DEVICE_PERMISSION_MANAGER_H_