Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: extensions/browser/api/device_permissions_manager.cc

Issue 882813002: Observe UsbService from the FILE thread in DevicePermissionsManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « extensions/browser/api/device_permissions_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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/device_permissions_manager.h" 5 #include "extensions/browser/api/device_permissions_manager.h"
6 6
7 #include "base/bind.h"
7 #include "base/memory/singleton.h" 8 #include "base/memory/singleton.h"
8 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h" 12 #include "base/values.h"
12 #include "components/keyed_service/content/browser_context_dependency_manager.h" 13 #include "components/keyed_service/content/browser_context_dependency_manager.h"
14 #include "content/public/browser/browser_thread.h"
13 #include "device/core/device_client.h" 15 #include "device/core/device_client.h"
14 #include "device/usb/usb_device.h" 16 #include "device/usb/usb_device.h"
15 #include "device/usb/usb_ids.h" 17 #include "device/usb/usb_ids.h"
16 #include "extensions/browser/extension_host.h" 18 #include "extensions/browser/extension_host.h"
17 #include "extensions/browser/extension_prefs.h" 19 #include "extensions/browser/extension_prefs.h"
18 #include "extensions/browser/extensions_browser_client.h" 20 #include "extensions/browser/extensions_browser_client.h"
19 #include "extensions/browser/process_manager.h" 21 #include "extensions/browser/process_manager.h"
20 #include "extensions/browser/process_manager_factory.h" 22 #include "extensions/browser/process_manager_factory.h"
21 #include "extensions/strings/grit/extensions_strings.h" 23 #include "extensions/strings/grit/extensions_strings.h"
22 #include "ui/base/l10n/l10n_util.h" 24 #include "ui/base/l10n/l10n_util.h"
23 25
24 namespace extensions { 26 namespace extensions {
25 27
26 using content::BrowserContext; 28 using content::BrowserContext;
29 using content::BrowserThread;
27 using device::UsbDevice; 30 using device::UsbDevice;
31 using device::UsbService;
28 using extensions::APIPermission; 32 using extensions::APIPermission;
29 using extensions::Extension; 33 using extensions::Extension;
30 using extensions::ExtensionHost; 34 using extensions::ExtensionHost;
31 using extensions::ExtensionPrefs; 35 using extensions::ExtensionPrefs;
32 36
33 namespace { 37 namespace {
34 38
35 // Preference keys 39 // Preference keys
36 40
37 // The device that the app has permission to access. 41 // The device that the app has permission to access.
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 const std::string& extension_id) { 374 const std::string& extension_id) {
371 ExtensionPrefs* prefs = ExtensionPrefs::Get(context); 375 ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
372 entries_ = GetDevicePermissionEntries(prefs, extension_id); 376 entries_ = GetDevicePermissionEntries(prefs, extension_id);
373 } 377 }
374 378
375 DevicePermissions::DevicePermissions(const DevicePermissions* original) 379 DevicePermissions::DevicePermissions(const DevicePermissions* original)
376 : entries_(original->entries_), 380 : entries_(original->entries_),
377 ephemeral_devices_(original->ephemeral_devices_) { 381 ephemeral_devices_(original->ephemeral_devices_) {
378 } 382 }
379 383
384 class DevicePermissionsManager::FileThreadHelper : public UsbService::Observer {
385 public:
386 FileThreadHelper(
387 base::WeakPtr<DevicePermissionsManager> device_permissions_manager)
388 : device_permissions_manager_(device_permissions_manager),
389 observer_(this) {}
390 virtual ~FileThreadHelper() {}
391
392 void Start() {
393 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
394 UsbService* service = device::DeviceClient::Get()->GetUsbService();
395 if (service) {
396 observer_.Add(service);
397 }
398 }
399
400 private:
401 void OnDeviceRemoved(scoped_refptr<UsbDevice> device) override {
402 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
403 // To avoid holding references to every ephemeral device until the browser
404 // is closed permissions should be cleared when the device is disconnected.
405 // There are however permissions checks that occur after the device is
406 // removed for delivering the device removal event and so a delay is
407 // required.
408 BrowserThread::PostDelayedTask(
409 BrowserThread::UI, FROM_HERE,
410 base::Bind(&DevicePermissionsManager::OnDeviceRemoved,
411 device_permissions_manager_, device),
412 base::TimeDelta::FromMinutes(5));
scheib 2015/01/27 23:56:25 ಠ_ಠ
413 }
414
415 base::WeakPtr<DevicePermissionsManager> device_permissions_manager_;
416 ScopedObserver<UsbService, UsbService::Observer> observer_;
417 };
418
380 // static 419 // static
381 DevicePermissionsManager* DevicePermissionsManager::Get( 420 DevicePermissionsManager* DevicePermissionsManager::Get(
382 BrowserContext* context) { 421 BrowserContext* context) {
383 return DevicePermissionsManagerFactory::GetForBrowserContext(context); 422 return DevicePermissionsManagerFactory::GetForBrowserContext(context);
384 } 423 }
385 424
386 scoped_ptr<DevicePermissions> DevicePermissionsManager::GetForExtension( 425 scoped_ptr<DevicePermissions> DevicePermissionsManager::GetForExtension(
387 const std::string& extension_id) { 426 const std::string& extension_id) {
388 DCHECK(CalledOnValidThread()); 427 DCHECK(CalledOnValidThread());
389 return make_scoped_ptr(new DevicePermissions(GetOrInsert(extension_id))); 428 return make_scoped_ptr(new DevicePermissions(GetOrInsert(extension_id)));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 } else if (!ContainsKey(device_permissions->ephemeral_devices_, device)) { 473 } else if (!ContainsKey(device_permissions->ephemeral_devices_, device)) {
435 // Non-persistent devices cannot be reliably identified when they are 474 // Non-persistent devices cannot be reliably identified when they are
436 // reconnected so such devices are only remembered until disconnect. 475 // reconnected so such devices are only remembered until disconnect.
437 // Register an observer here so that this set doesn't grow undefinitely. 476 // Register an observer here so that this set doesn't grow undefinitely.
438 device_permissions->entries_.insert(device_entry); 477 device_permissions->entries_.insert(device_entry);
439 device_permissions->ephemeral_devices_[device] = device_entry; 478 device_permissions->ephemeral_devices_[device] = device_entry;
440 479
441 // Only start observing when an ephemeral device has been added so that 480 // Only start observing when an ephemeral device has been added so that
442 // UsbService is not automatically initialized on profile creation (which it 481 // UsbService is not automatically initialized on profile creation (which it
443 // would be if this call were in the constructor). 482 // would be if this call were in the constructor).
444 device::UsbService* usb_service = 483 if (!helper_) {
445 device::DeviceClient::Get()->GetUsbService(); 484 helper_ = new FileThreadHelper(weak_factory_.GetWeakPtr());
446 DCHECK(usb_service); 485 // base::Unretained is safe because any task to delete helper_ will be
447 if (!usb_service_observer_.IsObserving(usb_service)) { 486 // executed after this call.
448 usb_service_observer_.Add(usb_service); 487 BrowserThread::PostTask(
488 BrowserThread::FILE, FROM_HERE,
489 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_)));
449 } 490 }
450 } 491 }
451 } 492 }
452 493
453 void DevicePermissionsManager::UpdateLastUsed( 494 void DevicePermissionsManager::UpdateLastUsed(
454 const std::string& extension_id, 495 const std::string& extension_id,
455 scoped_refptr<DevicePermissionEntry> entry) { 496 scoped_refptr<DevicePermissionEntry> entry) {
456 DCHECK(CalledOnValidThread()); 497 DCHECK(CalledOnValidThread());
457 entry->set_last_used(base::Time::Now()); 498 entry->set_last_used(base::Time::Now());
458 if (entry->IsPersistent()) { 499 if (entry->IsPersistent()) {
(...skipping 24 matching lines...) Expand all
483 if (device_permissions) { 524 if (device_permissions) {
484 extension_id_to_device_permissions_.erase(extension_id); 525 extension_id_to_device_permissions_.erase(extension_id);
485 delete device_permissions; 526 delete device_permissions;
486 } 527 }
487 } 528 }
488 529
489 DevicePermissionsManager::DevicePermissionsManager( 530 DevicePermissionsManager::DevicePermissionsManager(
490 content::BrowserContext* context) 531 content::BrowserContext* context)
491 : context_(context), 532 : context_(context),
492 process_manager_observer_(this), 533 process_manager_observer_(this),
493 usb_service_observer_(this) { 534 helper_(nullptr),
535 weak_factory_(this) {
494 process_manager_observer_.Add(ProcessManager::Get(context)); 536 process_manager_observer_.Add(ProcessManager::Get(context));
495 } 537 }
496 538
497 DevicePermissionsManager::~DevicePermissionsManager() { 539 DevicePermissionsManager::~DevicePermissionsManager() {
498 for (const auto& map_entry : extension_id_to_device_permissions_) { 540 for (const auto& map_entry : extension_id_to_device_permissions_) {
499 DevicePermissions* device_permissions = map_entry.second; 541 DevicePermissions* device_permissions = map_entry.second;
500 delete device_permissions; 542 delete device_permissions;
501 } 543 }
544 if (helper_) {
545 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, helper_);
546 helper_ = nullptr;
547 }
502 } 548 }
503 549
504 DevicePermissions* DevicePermissionsManager::Get( 550 DevicePermissions* DevicePermissionsManager::Get(
505 const std::string& extension_id) const { 551 const std::string& extension_id) const {
506 std::map<std::string, DevicePermissions*>::const_iterator it = 552 std::map<std::string, DevicePermissions*>::const_iterator it =
507 extension_id_to_device_permissions_.find(extension_id); 553 extension_id_to_device_permissions_.find(extension_id);
508 if (it != extension_id_to_device_permissions_.end()) { 554 if (it != extension_id_to_device_permissions_.end()) {
509 return it->second; 555 return it->second;
510 } 556 }
511 557
(...skipping 21 matching lines...) Expand all
533 // suspended all ephemeral device permissions are cleared. 579 // suspended all ephemeral device permissions are cleared.
534 for (const auto& map_entry : device_permissions->ephemeral_devices_) { 580 for (const auto& map_entry : device_permissions->ephemeral_devices_) {
535 device_permissions->entries_.erase(map_entry.second); 581 device_permissions->entries_.erase(map_entry.second);
536 } 582 }
537 device_permissions->ephemeral_devices_.clear(); 583 device_permissions->ephemeral_devices_.clear();
538 } 584 }
539 } 585 }
540 586
541 void DevicePermissionsManager::OnDeviceRemoved( 587 void DevicePermissionsManager::OnDeviceRemoved(
542 scoped_refptr<UsbDevice> device) { 588 scoped_refptr<UsbDevice> device) {
589 DCHECK(CalledOnValidThread());
543 for (const auto& map_entry : extension_id_to_device_permissions_) { 590 for (const auto& map_entry : extension_id_to_device_permissions_) {
544 // An ephemeral device cannot be identified if it is reconnected and so 591 // An ephemeral device cannot be identified if it is reconnected and so
545 // permission to access it is cleared on disconnect. 592 // permission to access it is cleared on disconnect.
546 DevicePermissions* device_permissions = map_entry.second; 593 DevicePermissions* device_permissions = map_entry.second;
547 const auto& device_entry = 594 const auto& device_entry =
548 device_permissions->ephemeral_devices_.find(device); 595 device_permissions->ephemeral_devices_.find(device);
549 if (device_entry != device_permissions->ephemeral_devices_.end()) { 596 if (device_entry != device_permissions->ephemeral_devices_.end()) {
550 device_permissions->entries_.erase(device_entry->second); 597 device_permissions->entries_.erase(device_entry->second);
551 device_permissions->ephemeral_devices_.erase(device); 598 device_permissions->ephemeral_devices_.erase(device);
552 } 599 }
(...skipping 30 matching lines...) Expand all
583 630
584 BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse( 631 BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse(
585 BrowserContext* context) const { 632 BrowserContext* context) const {
586 // Return the original (possibly off-the-record) browser context so that a 633 // Return the original (possibly off-the-record) browser context so that a
587 // separate instance of the DevicePermissionsManager is used in incognito 634 // separate instance of the DevicePermissionsManager is used in incognito
588 // mode. The parent class's implemenation returns NULL. 635 // mode. The parent class's implemenation returns NULL.
589 return context; 636 return context;
590 } 637 }
591 638
592 } // namespace extensions 639 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/api/device_permissions_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698