Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / extensions / browser / api / device_permissions_manager.cc
blobdb7cc3025930c5504c6bbfa0719275d0e0e47d3a
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 #include "extensions/browser/api/device_permissions_manager.h"
7 #include "base/bind.h"
8 #include "base/memory/singleton.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "components/keyed_service/content/browser_context_dependency_manager.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "device/core/device_client.h"
16 #include "device/hid/hid_device_info.h"
17 #include "device/hid/hid_service.h"
18 #include "device/usb/usb_device.h"
19 #include "device/usb/usb_ids.h"
20 #include "extensions/browser/extension_host.h"
21 #include "extensions/browser/extension_prefs.h"
22 #include "extensions/browser/extensions_browser_client.h"
23 #include "extensions/browser/process_manager.h"
24 #include "extensions/browser/process_manager_factory.h"
25 #include "extensions/common/value_builder.h"
26 #include "extensions/strings/grit/extensions_strings.h"
27 #include "ui/base/l10n/l10n_util.h"
29 namespace extensions {
31 using content::BrowserContext;
32 using content::BrowserThread;
33 using device::HidDeviceInfo;
34 using device::HidService;
35 using device::UsbDevice;
36 using device::UsbService;
37 using extensions::APIPermission;
38 using extensions::Extension;
39 using extensions::ExtensionHost;
40 using extensions::ExtensionPrefs;
42 namespace {
44 // Preference keys
46 // The device that the app has permission to access.
47 const char kDevices[] = "devices";
49 // The type of device saved.
50 const char kDeviceType[] = "type";
52 // Type identifier for USB devices.
53 const char kDeviceTypeUsb[] = "usb";
55 // Type identifier for HID devices.
56 const char kDeviceTypeHid[] = "hid";
58 // The vendor ID of the device that the app had permission to access.
59 const char kDeviceVendorId[] = "vendor_id";
61 // The product ID of the device that the app had permission to access.
62 const char kDeviceProductId[] = "product_id";
64 // The serial number of the device that the app has permission to access.
65 const char kDeviceSerialNumber[] = "serial_number";
67 // The manufacturer string read from the device that the app has permission to
68 // access.
69 const char kDeviceManufacturerString[] = "manufacturer_string";
71 // The product string read from the device that the app has permission to
72 // access.
73 const char kDeviceProductString[] = "product_string";
75 // Serialized timestamp of the last time when the device was opened by the app.
76 const char kDeviceLastUsed[] = "last_used_time";
78 // Converts a DevicePermissionEntry::Type to a string for the prefs file.
79 const char* TypeToString(DevicePermissionEntry::Type type) {
80 switch (type) {
81 case DevicePermissionEntry::Type::USB:
82 return kDeviceTypeUsb;
83 case DevicePermissionEntry::Type::HID:
84 return kDeviceTypeHid;
86 NOTREACHED();
87 return "";
90 // Persists a DevicePermissionEntry in ExtensionPrefs.
91 void SaveDevicePermissionEntry(BrowserContext* context,
92 const std::string& extension_id,
93 scoped_refptr<DevicePermissionEntry> entry) {
94 ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
95 ExtensionPrefs::ScopedListUpdate update(prefs, extension_id, kDevices);
96 base::ListValue* devices = update.Get();
97 if (!devices) {
98 devices = update.Create();
101 scoped_ptr<base::Value> device_entry(entry->ToValue());
102 DCHECK(devices->Find(*device_entry.get()) == devices->end());
103 devices->Append(device_entry.release());
106 bool MatchesDevicePermissionEntry(const base::DictionaryValue* value,
107 scoped_refptr<DevicePermissionEntry> entry) {
108 std::string type;
109 if (!value->GetStringWithoutPathExpansion(kDeviceType, &type) ||
110 type != TypeToString(entry->type())) {
111 return false;
113 int vendor_id;
114 if (!value->GetIntegerWithoutPathExpansion(kDeviceVendorId, &vendor_id) ||
115 vendor_id != entry->vendor_id()) {
116 return false;
118 int product_id;
119 if (!value->GetIntegerWithoutPathExpansion(kDeviceProductId, &product_id) ||
120 product_id != entry->product_id()) {
121 return false;
123 base::string16 serial_number;
124 if (!value->GetStringWithoutPathExpansion(kDeviceSerialNumber,
125 &serial_number) ||
126 serial_number != entry->serial_number()) {
127 return false;
129 return true;
132 // Updates the timestamp stored in ExtensionPrefs for the given
133 // DevicePermissionEntry.
134 void UpdateDevicePermissionEntry(BrowserContext* context,
135 const std::string& extension_id,
136 scoped_refptr<DevicePermissionEntry> entry) {
137 ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
138 ExtensionPrefs::ScopedListUpdate update(prefs, extension_id, kDevices);
139 base::ListValue* devices = update.Get();
140 if (!devices) {
141 return;
144 for (size_t i = 0; i < devices->GetSize(); ++i) {
145 base::DictionaryValue* dict_value;
146 if (!devices->GetDictionary(i, &dict_value)) {
147 continue;
149 if (!MatchesDevicePermissionEntry(dict_value, entry)) {
150 continue;
152 devices->Set(i, entry->ToValue().release());
153 break;
157 // Removes the given DevicePermissionEntry from ExtensionPrefs.
158 void RemoveDevicePermissionEntry(BrowserContext* context,
159 const std::string& extension_id,
160 scoped_refptr<DevicePermissionEntry> entry) {
161 ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
162 ExtensionPrefs::ScopedListUpdate update(prefs, extension_id, kDevices);
163 base::ListValue* devices = update.Get();
164 if (!devices) {
165 return;
168 for (size_t i = 0; i < devices->GetSize(); ++i) {
169 base::DictionaryValue* dict_value;
170 if (!devices->GetDictionary(i, &dict_value)) {
171 continue;
173 if (!MatchesDevicePermissionEntry(dict_value, entry)) {
174 continue;
176 devices->Remove(i, nullptr);
177 break;
181 // Clears all DevicePermissionEntries for the app from ExtensionPrefs.
182 void ClearDevicePermissionEntries(ExtensionPrefs* prefs,
183 const std::string& extension_id) {
184 prefs->UpdateExtensionPref(extension_id, kDevices, NULL);
187 scoped_refptr<DevicePermissionEntry> ReadDevicePermissionEntry(
188 const base::DictionaryValue* entry) {
189 int vendor_id;
190 if (!entry->GetIntegerWithoutPathExpansion(kDeviceVendorId, &vendor_id) ||
191 vendor_id < 0 || vendor_id > UINT16_MAX) {
192 return nullptr;
195 int product_id;
196 if (!entry->GetIntegerWithoutPathExpansion(kDeviceProductId, &product_id) ||
197 product_id < 0 || product_id > UINT16_MAX) {
198 return nullptr;
201 base::string16 serial_number;
202 if (!entry->GetStringWithoutPathExpansion(kDeviceSerialNumber,
203 &serial_number)) {
204 return nullptr;
207 base::string16 manufacturer_string;
208 // Ignore failure as this string is optional.
209 entry->GetStringWithoutPathExpansion(kDeviceManufacturerString,
210 &manufacturer_string);
212 base::string16 product_string;
213 // Ignore failure as this string is optional.
214 entry->GetStringWithoutPathExpansion(kDeviceProductString, &product_string);
216 // If a last used time is not stored in ExtensionPrefs last_used.is_null()
217 // will be true.
218 std::string last_used_str;
219 int64 last_used_i64 = 0;
220 base::Time last_used;
221 if (entry->GetStringWithoutPathExpansion(kDeviceLastUsed, &last_used_str) &&
222 base::StringToInt64(last_used_str, &last_used_i64)) {
223 last_used = base::Time::FromInternalValue(last_used_i64);
226 std::string type;
227 if (!entry->GetStringWithoutPathExpansion(kDeviceType, &type)) {
228 return nullptr;
231 if (type == kDeviceTypeUsb) {
232 return new DevicePermissionEntry(
233 DevicePermissionEntry::Type::USB, vendor_id, product_id, serial_number,
234 manufacturer_string, product_string, last_used);
235 } else if (type == kDeviceTypeHid) {
236 return new DevicePermissionEntry(
237 DevicePermissionEntry::Type::HID, vendor_id, product_id, serial_number,
238 base::string16(), product_string, last_used);
240 return nullptr;
243 // Returns all DevicePermissionEntries for the app.
244 std::set<scoped_refptr<DevicePermissionEntry>> GetDevicePermissionEntries(
245 ExtensionPrefs* prefs,
246 const std::string& extension_id) {
247 std::set<scoped_refptr<DevicePermissionEntry>> result;
248 const base::ListValue* devices = NULL;
249 if (!prefs->ReadPrefAsList(extension_id, kDevices, &devices)) {
250 return result;
253 for (const base::Value* entry : *devices) {
254 const base::DictionaryValue* entry_dict;
255 if (entry->GetAsDictionary(&entry_dict)) {
256 scoped_refptr<DevicePermissionEntry> device_entry =
257 ReadDevicePermissionEntry(entry_dict);
258 if (entry_dict) {
259 result.insert(device_entry);
263 return result;
266 } // namespace
268 DevicePermissionEntry::DevicePermissionEntry(scoped_refptr<UsbDevice> device)
269 : usb_device_(device),
270 type_(Type::USB),
271 vendor_id_(device->vendor_id()),
272 product_id_(device->product_id()),
273 serial_number_(device->serial_number()),
274 manufacturer_string_(device->manufacturer_string()),
275 product_string_(device->product_string()) {
278 DevicePermissionEntry::DevicePermissionEntry(
279 scoped_refptr<HidDeviceInfo> device)
280 : hid_device_(device),
281 type_(Type::HID),
282 vendor_id_(device->vendor_id()),
283 product_id_(device->product_id()),
284 serial_number_(base::UTF8ToUTF16(device->serial_number())),
285 product_string_(base::UTF8ToUTF16(device->product_name())) {
288 DevicePermissionEntry::DevicePermissionEntry(
289 Type type,
290 uint16_t vendor_id,
291 uint16_t product_id,
292 const base::string16& serial_number,
293 const base::string16& manufacturer_string,
294 const base::string16& product_string,
295 const base::Time& last_used)
296 : type_(type),
297 vendor_id_(vendor_id),
298 product_id_(product_id),
299 serial_number_(serial_number),
300 manufacturer_string_(manufacturer_string),
301 product_string_(product_string),
302 last_used_(last_used) {
305 DevicePermissionEntry::~DevicePermissionEntry() {
308 bool DevicePermissionEntry::IsPersistent() const {
309 return !serial_number_.empty();
312 scoped_ptr<base::Value> DevicePermissionEntry::ToValue() const {
313 if (!IsPersistent()) {
314 return nullptr;
317 DCHECK(!serial_number_.empty());
318 scoped_ptr<base::DictionaryValue> entry_dict(
319 DictionaryBuilder()
320 .Set(kDeviceType, TypeToString(type_))
321 .Set(kDeviceVendorId, vendor_id_)
322 .Set(kDeviceProductId, product_id_)
323 .Set(kDeviceSerialNumber, serial_number_)
324 .Build());
326 if (!manufacturer_string_.empty()) {
327 entry_dict->SetStringWithoutPathExpansion(kDeviceManufacturerString,
328 manufacturer_string_);
330 if (!product_string_.empty()) {
331 entry_dict->SetStringWithoutPathExpansion(kDeviceProductString,
332 product_string_);
334 if (!last_used_.is_null()) {
335 entry_dict->SetStringWithoutPathExpansion(
336 kDeviceLastUsed, base::Int64ToString(last_used_.ToInternalValue()));
339 return entry_dict.Pass();
342 base::string16 DevicePermissionEntry::GetPermissionMessageString() const {
343 return DevicePermissionsManager::GetPermissionMessage(
344 vendor_id_, product_id_, manufacturer_string_, product_string_,
345 serial_number_, type_ == Type::USB);
348 DevicePermissions::~DevicePermissions() {
351 scoped_refptr<DevicePermissionEntry> DevicePermissions::FindUsbDeviceEntry(
352 scoped_refptr<UsbDevice> device) const {
353 const auto& ephemeral_device_entry =
354 ephemeral_usb_devices_.find(device.get());
355 if (ephemeral_device_entry != ephemeral_usb_devices_.end()) {
356 return ephemeral_device_entry->second;
359 if (device->serial_number().empty()) {
360 return nullptr;
363 for (const auto& entry : entries_) {
364 if (entry->IsPersistent() && entry->vendor_id() == device->vendor_id() &&
365 entry->product_id() == device->product_id() &&
366 entry->serial_number() == device->serial_number()) {
367 return entry;
370 return nullptr;
373 scoped_refptr<DevicePermissionEntry> DevicePermissions::FindHidDeviceEntry(
374 scoped_refptr<HidDeviceInfo> device) const {
375 const auto& ephemeral_device_entry =
376 ephemeral_hid_devices_.find(device.get());
377 if (ephemeral_device_entry != ephemeral_hid_devices_.end()) {
378 return ephemeral_device_entry->second;
381 if (device->serial_number().empty()) {
382 return nullptr;
385 base::string16 serial_number = base::UTF8ToUTF16(device->serial_number());
386 for (const auto& entry : entries_) {
387 if (entry->IsPersistent() && entry->vendor_id() == device->vendor_id() &&
388 entry->product_id() == device->product_id() &&
389 entry->serial_number() == serial_number) {
390 return entry;
393 return nullptr;
396 DevicePermissions::DevicePermissions(BrowserContext* context,
397 const std::string& extension_id) {
398 ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
399 entries_ = GetDevicePermissionEntries(prefs, extension_id);
402 // static
403 DevicePermissionsManager* DevicePermissionsManager::Get(
404 BrowserContext* context) {
405 return DevicePermissionsManagerFactory::GetForBrowserContext(context);
408 // static
409 base::string16 DevicePermissionsManager::GetPermissionMessage(
410 uint16 vendor_id,
411 uint16 product_id,
412 const base::string16& manufacturer_string,
413 const base::string16& product_string,
414 const base::string16& serial_number,
415 bool always_include_manufacturer) {
416 base::string16 product = product_string;
417 if (product.empty()) {
418 const char* product_name =
419 device::UsbIds::GetProductName(vendor_id, product_id);
420 if (product_name) {
421 product = base::UTF8ToUTF16(product_name);
425 base::string16 manufacturer = manufacturer_string;
426 if (manufacturer_string.empty()) {
427 const char* vendor_name = device::UsbIds::GetVendorName(vendor_id);
428 if (vendor_name) {
429 manufacturer = base::UTF8ToUTF16(vendor_name);
433 if (serial_number.empty()) {
434 if (product.empty()) {
435 product = base::ASCIIToUTF16(base::StringPrintf("%04x", product_id));
436 if (manufacturer.empty()) {
437 manufacturer =
438 base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
439 return l10n_util::GetStringFUTF16(
440 IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_UNKNOWN_VENDOR, product,
441 manufacturer);
442 } else {
443 return l10n_util::GetStringFUTF16(
444 IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_VENDOR, product, manufacturer);
446 } else {
447 if (always_include_manufacturer) {
448 if (manufacturer.empty()) {
449 manufacturer =
450 base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
451 return l10n_util::GetStringFUTF16(
452 IDS_DEVICE_NAME_WITH_PRODUCT_UNKNOWN_VENDOR, product,
453 manufacturer);
454 } else {
455 return l10n_util::GetStringFUTF16(IDS_DEVICE_NAME_WITH_PRODUCT_VENDOR,
456 product, manufacturer);
458 } else {
459 return product;
462 } else {
463 if (product.empty()) {
464 product = base::ASCIIToUTF16(base::StringPrintf("%04x", product_id));
465 if (manufacturer.empty()) {
466 manufacturer =
467 base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
468 return l10n_util::GetStringFUTF16(
469 IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_UNKNOWN_VENDOR_SERIAL, product,
470 manufacturer, serial_number);
471 } else {
472 return l10n_util::GetStringFUTF16(
473 IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_VENDOR_SERIAL, product,
474 manufacturer, serial_number);
476 } else {
477 if (always_include_manufacturer) {
478 if (manufacturer.empty()) {
479 manufacturer =
480 base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
481 return l10n_util::GetStringFUTF16(
482 IDS_DEVICE_NAME_WITH_PRODUCT_UNKNOWN_VENDOR_SERIAL, product,
483 manufacturer, serial_number);
484 } else {
485 return l10n_util::GetStringFUTF16(
486 IDS_DEVICE_NAME_WITH_PRODUCT_VENDOR_SERIAL, product, manufacturer,
487 serial_number);
489 } else {
490 return l10n_util::GetStringFUTF16(IDS_DEVICE_NAME_WITH_PRODUCT_SERIAL,
491 product, serial_number);
497 DevicePermissions* DevicePermissionsManager::GetForExtension(
498 const std::string& extension_id) {
499 DCHECK(thread_checker_.CalledOnValidThread());
500 DevicePermissions* device_permissions = GetInternal(extension_id);
501 if (!device_permissions) {
502 device_permissions = new DevicePermissions(context_, extension_id);
503 extension_id_to_device_permissions_[extension_id] = device_permissions;
506 return device_permissions;
509 std::vector<base::string16>
510 DevicePermissionsManager::GetPermissionMessageStrings(
511 const std::string& extension_id) const {
512 DCHECK(thread_checker_.CalledOnValidThread());
513 std::vector<base::string16> messages;
514 const DevicePermissions* device_permissions = GetInternal(extension_id);
515 if (device_permissions) {
516 for (const scoped_refptr<DevicePermissionEntry>& entry :
517 device_permissions->entries()) {
518 messages.push_back(entry->GetPermissionMessageString());
521 return messages;
524 void DevicePermissionsManager::AllowUsbDevice(const std::string& extension_id,
525 scoped_refptr<UsbDevice> device) {
526 DCHECK(thread_checker_.CalledOnValidThread());
527 DevicePermissions* device_permissions = GetForExtension(extension_id);
529 scoped_refptr<DevicePermissionEntry> device_entry(
530 new DevicePermissionEntry(device));
532 if (device_entry->IsPersistent()) {
533 for (const auto& entry : device_permissions->entries()) {
534 if (entry->vendor_id() == device_entry->vendor_id() &&
535 entry->product_id() == device_entry->product_id() &&
536 entry->serial_number() == device_entry->serial_number()) {
537 return;
541 device_permissions->entries_.insert(device_entry);
542 SaveDevicePermissionEntry(context_, extension_id, device_entry);
543 } else if (!ContainsKey(device_permissions->ephemeral_usb_devices_,
544 device.get())) {
545 // Non-persistent devices cannot be reliably identified when they are
546 // reconnected so such devices are only remembered until disconnect.
547 // Register an observer here so that this set doesn't grow undefinitely.
548 device_permissions->entries_.insert(device_entry);
549 device_permissions->ephemeral_usb_devices_[device.get()] = device_entry;
551 // Only start observing when an ephemeral device has been added so that
552 // UsbService is not automatically initialized on profile creation (which it
553 // would be if this call were in the constructor).
554 UsbService* usb_service = device::DeviceClient::Get()->GetUsbService();
555 if (!usb_service_observer_.IsObserving(usb_service)) {
556 usb_service_observer_.Add(usb_service);
561 void DevicePermissionsManager::AllowHidDevice(
562 const std::string& extension_id,
563 scoped_refptr<HidDeviceInfo> device) {
564 DCHECK(thread_checker_.CalledOnValidThread());
565 DevicePermissions* device_permissions = GetForExtension(extension_id);
567 scoped_refptr<DevicePermissionEntry> device_entry(
568 new DevicePermissionEntry(device));
570 if (device_entry->IsPersistent()) {
571 for (const auto& entry : device_permissions->entries()) {
572 if (entry->vendor_id() == device_entry->vendor_id() &&
573 entry->product_id() == device_entry->product_id() &&
574 entry->serial_number() == device_entry->serial_number()) {
575 return;
579 device_permissions->entries_.insert(device_entry);
580 SaveDevicePermissionEntry(context_, extension_id, device_entry);
581 } else if (!ContainsKey(device_permissions->ephemeral_hid_devices_,
582 device.get())) {
583 // Non-persistent devices cannot be reliably identified when they are
584 // reconnected so such devices are only remembered until disconnect.
585 // Register an observer here so that this set doesn't grow undefinitely.
586 device_permissions->entries_.insert(device_entry);
587 device_permissions->ephemeral_hid_devices_[device.get()] = device_entry;
589 // Only start observing when an ephemeral device has been added so that
590 // HidService is not automatically initialized on profile creation (which it
591 // would be if this call were in the constructor).
592 HidService* hid_service = device::DeviceClient::Get()->GetHidService();
593 if (!hid_service_observer_.IsObserving(hid_service)) {
594 hid_service_observer_.Add(hid_service);
599 void DevicePermissionsManager::UpdateLastUsed(
600 const std::string& extension_id,
601 scoped_refptr<DevicePermissionEntry> entry) {
602 DCHECK(thread_checker_.CalledOnValidThread());
603 entry->set_last_used(base::Time::Now());
604 if (entry->IsPersistent()) {
605 UpdateDevicePermissionEntry(context_, extension_id, entry);
609 void DevicePermissionsManager::RemoveEntry(
610 const std::string& extension_id,
611 scoped_refptr<DevicePermissionEntry> entry) {
612 DCHECK(thread_checker_.CalledOnValidThread());
613 DevicePermissions* device_permissions = GetInternal(extension_id);
614 DCHECK(device_permissions);
615 DCHECK(ContainsKey(device_permissions->entries_, entry));
616 device_permissions->entries_.erase(entry);
617 if (entry->IsPersistent()) {
618 RemoveDevicePermissionEntry(context_, extension_id, entry);
619 } else if (entry->type_ == DevicePermissionEntry::Type::USB) {
620 device_permissions->ephemeral_usb_devices_.erase(entry->usb_device_.get());
621 } else if (entry->type_ == DevicePermissionEntry::Type::HID) {
622 device_permissions->ephemeral_hid_devices_.erase(entry->hid_device_.get());
623 } else {
624 NOTREACHED();
628 void DevicePermissionsManager::Clear(const std::string& extension_id) {
629 DCHECK(thread_checker_.CalledOnValidThread());
631 ClearDevicePermissionEntries(ExtensionPrefs::Get(context_), extension_id);
632 DevicePermissions* device_permissions = GetInternal(extension_id);
633 if (device_permissions) {
634 extension_id_to_device_permissions_.erase(extension_id);
635 delete device_permissions;
639 DevicePermissionsManager::DevicePermissionsManager(
640 content::BrowserContext* context)
641 : context_(context),
642 process_manager_observer_(this),
643 usb_service_observer_(this),
644 hid_service_observer_(this) {
645 process_manager_observer_.Add(ProcessManager::Get(context));
648 DevicePermissionsManager::~DevicePermissionsManager() {
649 for (const auto& map_entry : extension_id_to_device_permissions_) {
650 DevicePermissions* device_permissions = map_entry.second;
651 delete device_permissions;
655 DevicePermissions* DevicePermissionsManager::GetInternal(
656 const std::string& extension_id) const {
657 std::map<std::string, DevicePermissions*>::const_iterator it =
658 extension_id_to_device_permissions_.find(extension_id);
659 if (it != extension_id_to_device_permissions_.end()) {
660 return it->second;
663 return NULL;
666 void DevicePermissionsManager::OnBackgroundHostClose(
667 const std::string& extension_id) {
668 DCHECK(thread_checker_.CalledOnValidThread());
670 DevicePermissions* device_permissions = GetInternal(extension_id);
671 if (device_permissions) {
672 // When all of the app's windows are closed and the background page is
673 // suspended all ephemeral device permissions are cleared.
674 for (const auto& map_entry : device_permissions->ephemeral_usb_devices_) {
675 device_permissions->entries_.erase(map_entry.second);
677 device_permissions->ephemeral_usb_devices_.clear();
678 for (const auto& map_entry : device_permissions->ephemeral_hid_devices_) {
679 device_permissions->entries_.erase(map_entry.second);
681 device_permissions->ephemeral_hid_devices_.clear();
685 void DevicePermissionsManager::OnDeviceRemovedCleanup(
686 scoped_refptr<UsbDevice> device) {
687 DCHECK(thread_checker_.CalledOnValidThread());
688 for (const auto& map_entry : extension_id_to_device_permissions_) {
689 // An ephemeral device cannot be identified if it is reconnected and so
690 // permission to access it is cleared on disconnect.
691 DevicePermissions* device_permissions = map_entry.second;
692 const auto& device_entry =
693 device_permissions->ephemeral_usb_devices_.find(device.get());
694 if (device_entry != device_permissions->ephemeral_usb_devices_.end()) {
695 device_permissions->entries_.erase(device_entry->second);
696 device_permissions->ephemeral_usb_devices_.erase(device_entry);
701 void DevicePermissionsManager::OnDeviceRemovedCleanup(
702 scoped_refptr<device::HidDeviceInfo> device) {
703 DCHECK(thread_checker_.CalledOnValidThread());
704 for (const auto& map_entry : extension_id_to_device_permissions_) {
705 // An ephemeral device cannot be identified if it is reconnected and so
706 // permission to access it is cleared on disconnect.
707 DevicePermissions* device_permissions = map_entry.second;
708 const auto& device_entry =
709 device_permissions->ephemeral_hid_devices_.find(device.get());
710 if (device_entry != device_permissions->ephemeral_hid_devices_.end()) {
711 device_permissions->entries_.erase(device_entry->second);
712 device_permissions->ephemeral_hid_devices_.erase(device_entry);
717 // static
718 DevicePermissionsManager* DevicePermissionsManagerFactory::GetForBrowserContext(
719 content::BrowserContext* context) {
720 return static_cast<DevicePermissionsManager*>(
721 GetInstance()->GetServiceForBrowserContext(context, true));
724 // static
725 DevicePermissionsManagerFactory*
726 DevicePermissionsManagerFactory::GetInstance() {
727 return Singleton<DevicePermissionsManagerFactory>::get();
730 DevicePermissionsManagerFactory::DevicePermissionsManagerFactory()
731 : BrowserContextKeyedServiceFactory(
732 "DevicePermissionsManager",
733 BrowserContextDependencyManager::GetInstance()) {
734 DependsOn(ProcessManagerFactory::GetInstance());
737 DevicePermissionsManagerFactory::~DevicePermissionsManagerFactory() {
740 KeyedService* DevicePermissionsManagerFactory::BuildServiceInstanceFor(
741 content::BrowserContext* context) const {
742 return new DevicePermissionsManager(context);
745 BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse(
746 BrowserContext* context) const {
747 // Return the original (possibly off-the-record) browser context so that a
748 // separate instance of the DevicePermissionsManager is used in incognito
749 // mode. The parent class's implemenation returns NULL.
750 return context;
753 } // namespace extensions