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

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

Issue 980023002: Move device/usb classes from the FILE thread to UI thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed first round of rocket@ feedback. Created 5 years, 8 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
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/bind.h"
8 #include "base/memory/singleton.h" 8 #include "base/memory/singleton.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 result.insert(new DevicePermissionEntry(vendor_id, product_id, 226 result.insert(new DevicePermissionEntry(vendor_id, product_id,
227 serial_number, manufacturer_string, 227 serial_number, manufacturer_string,
228 product_string, last_used)); 228 product_string, last_used));
229 } 229 }
230 return result; 230 return result;
231 } 231 }
232 232
233 } // namespace 233 } // namespace
234 234
235 DevicePermissionEntry::DevicePermissionEntry( 235 DevicePermissionEntry::DevicePermissionEntry(
236 scoped_refptr<device::UsbDevice> device, 236 scoped_refptr<device::UsbDevice> device)
237 const base::string16& serial_number,
238 const base::string16& manufacturer_string,
239 const base::string16& product_string)
240 : device_(device), 237 : device_(device),
241 vendor_id_(device->vendor_id()), 238 vendor_id_(device->vendor_id()),
242 product_id_(device->product_id()), 239 product_id_(device->product_id()),
243 serial_number_(serial_number), 240 serial_number_(device->serial_number()),
244 manufacturer_string_(manufacturer_string), 241 manufacturer_string_(device->manufacturer_string()),
245 product_string_(product_string) { 242 product_string_(device->product_string()) {
246 } 243 }
247 244
248 DevicePermissionEntry::DevicePermissionEntry( 245 DevicePermissionEntry::DevicePermissionEntry(
249 uint16_t vendor_id, 246 uint16_t vendor_id,
250 uint16_t product_id, 247 uint16_t product_id,
251 const base::string16& serial_number, 248 const base::string16& serial_number,
252 const base::string16& manufacturer_string, 249 const base::string16& manufacturer_string,
253 const base::string16& product_string, 250 const base::string16& product_string,
254 const base::Time& last_used) 251 const base::Time& last_used)
255 : vendor_id_(vendor_id), 252 : vendor_id_(vendor_id),
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 } 331 }
335 } else { 332 } else {
336 return product_string_; 333 return product_string_;
337 } 334 }
338 } 335 }
339 336
340 DevicePermissions::~DevicePermissions() { 337 DevicePermissions::~DevicePermissions() {
341 } 338 }
342 339
343 scoped_refptr<DevicePermissionEntry> DevicePermissions::FindEntry( 340 scoped_refptr<DevicePermissionEntry> DevicePermissions::FindEntry(
344 scoped_refptr<device::UsbDevice> device, 341 scoped_refptr<device::UsbDevice> device) const {
345 const base::string16& serial_number) const {
346 const auto& ephemeral_device_entry = ephemeral_devices_.find(device); 342 const auto& ephemeral_device_entry = ephemeral_devices_.find(device);
347 if (ephemeral_device_entry != ephemeral_devices_.end()) { 343 if (ephemeral_device_entry != ephemeral_devices_.end()) {
348 return ephemeral_device_entry->second; 344 return ephemeral_device_entry->second;
349 } 345 }
350 346
351 if (serial_number.empty()) { 347 if (device->serial_number().empty()) {
352 return nullptr; 348 return nullptr;
353 } 349 }
354 350
355 for (const auto& entry : entries_) { 351 for (const auto& entry : entries_) {
356 if (!entry->IsPersistent()) { 352 if (!entry->IsPersistent()) {
357 continue; 353 continue;
358 } 354 }
359 if (entry->vendor_id() != device->vendor_id()) { 355 if (entry->vendor_id() != device->vendor_id()) {
360 continue; 356 continue;
361 } 357 }
362 if (entry->product_id() != device->product_id()) { 358 if (entry->product_id() != device->product_id()) {
363 continue; 359 continue;
364 } 360 }
365 if (entry->serial_number() != serial_number) { 361 if (entry->serial_number() != device->serial_number()) {
366 continue; 362 continue;
367 } 363 }
368 return entry; 364 return entry;
369 } 365 }
370 return nullptr; 366 return nullptr;
371 } 367 }
372 368
373 DevicePermissions::DevicePermissions(BrowserContext* context, 369 DevicePermissions::DevicePermissions(BrowserContext* context,
374 const std::string& extension_id) { 370 const std::string& extension_id) {
375 ExtensionPrefs* prefs = ExtensionPrefs::Get(context); 371 ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
376 entries_ = GetDevicePermissionEntries(prefs, extension_id); 372 entries_ = GetDevicePermissionEntries(prefs, extension_id);
377 } 373 }
378 374
379 DevicePermissions::DevicePermissions(const DevicePermissions* original)
380 : entries_(original->entries_),
381 ephemeral_devices_(original->ephemeral_devices_) {
382 }
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 OnDeviceRemovedCleanup(scoped_refptr<UsbDevice> device) override {
402 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
403 BrowserThread::PostTask(
404 BrowserThread::UI, FROM_HERE,
405 base::Bind(&DevicePermissionsManager::OnDeviceRemoved,
406 device_permissions_manager_, device));
407 }
408
409 base::WeakPtr<DevicePermissionsManager> device_permissions_manager_;
410 ScopedObserver<UsbService, UsbService::Observer> observer_;
411 };
412
413 // static 375 // static
414 DevicePermissionsManager* DevicePermissionsManager::Get( 376 DevicePermissionsManager* DevicePermissionsManager::Get(
415 BrowserContext* context) { 377 BrowserContext* context) {
416 return DevicePermissionsManagerFactory::GetForBrowserContext(context); 378 return DevicePermissionsManagerFactory::GetForBrowserContext(context);
417 } 379 }
418 380
419 scoped_ptr<DevicePermissions> DevicePermissionsManager::GetForExtension( 381 DevicePermissions* DevicePermissionsManager::GetForExtension(
420 const std::string& extension_id) { 382 const std::string& extension_id) {
421 DCHECK(CalledOnValidThread()); 383 DCHECK(CalledOnValidThread());
422 return make_scoped_ptr(new DevicePermissions(GetOrInsert(extension_id))); 384 DevicePermissions* device_permissions = Get(extension_id);
385 if (!device_permissions) {
386 device_permissions = new DevicePermissions(context_, extension_id);
387 extension_id_to_device_permissions_[extension_id] = device_permissions;
388 }
389
390 return device_permissions;
423 } 391 }
424 392
425 std::vector<base::string16> 393 std::vector<base::string16>
426 DevicePermissionsManager::GetPermissionMessageStrings( 394 DevicePermissionsManager::GetPermissionMessageStrings(
427 const std::string& extension_id) const { 395 const std::string& extension_id) const {
428 DCHECK(CalledOnValidThread()); 396 DCHECK(CalledOnValidThread());
429 std::vector<base::string16> messages; 397 std::vector<base::string16> messages;
430 const DevicePermissions* device_permissions = Get(extension_id); 398 const DevicePermissions* device_permissions = Get(extension_id);
431 if (device_permissions) { 399 if (device_permissions) {
432 for (const scoped_refptr<DevicePermissionEntry>& entry : 400 for (const scoped_refptr<DevicePermissionEntry>& entry :
433 device_permissions->entries()) { 401 device_permissions->entries()) {
434 messages.push_back(entry->GetPermissionMessageString()); 402 messages.push_back(entry->GetPermissionMessageString());
435 } 403 }
436 } 404 }
437 return messages; 405 return messages;
438 } 406 }
439 407
440 void DevicePermissionsManager::AllowUsbDevice( 408 void DevicePermissionsManager::AllowUsbDevice(
441 const std::string& extension_id, 409 const std::string& extension_id,
442 scoped_refptr<device::UsbDevice> device, 410 scoped_refptr<device::UsbDevice> device) {
443 const base::string16& product_string,
444 const base::string16& manufacturer_string,
445 const base::string16& serial_number) {
446 DCHECK(CalledOnValidThread()); 411 DCHECK(CalledOnValidThread());
447 DevicePermissions* device_permissions = GetOrInsert(extension_id); 412 DevicePermissions* device_permissions = GetForExtension(extension_id);
448 413
449 scoped_refptr<DevicePermissionEntry> device_entry(new DevicePermissionEntry( 414 scoped_refptr<DevicePermissionEntry> device_entry(
450 device, serial_number, manufacturer_string, product_string)); 415 new DevicePermissionEntry(device));
451 416
452 if (device_entry->IsPersistent()) { 417 if (device_entry->IsPersistent()) {
453 for (const auto& entry : device_permissions->entries()) { 418 for (const auto& entry : device_permissions->entries()) {
454 if (entry->vendor_id() != device_entry->vendor_id()) { 419 if (entry->vendor_id() != device_entry->vendor_id()) {
455 continue; 420 continue;
456 } 421 }
457 if (entry->product_id() != device_entry->product_id()) { 422 if (entry->product_id() != device_entry->product_id()) {
458 continue; 423 continue;
459 } 424 }
460 if (entry->serial_number() == device_entry->serial_number()) { 425 if (entry->serial_number() == device_entry->serial_number()) {
461 return; 426 return;
462 } 427 }
463 } 428 }
464 429
465 device_permissions->entries_.insert(device_entry); 430 device_permissions->entries_.insert(device_entry);
466 SaveDevicePermissionEntry(context_, extension_id, device_entry); 431 SaveDevicePermissionEntry(context_, extension_id, device_entry);
467 } else if (!ContainsKey(device_permissions->ephemeral_devices_, device)) { 432 } else if (!ContainsKey(device_permissions->ephemeral_devices_, device)) {
468 // Non-persistent devices cannot be reliably identified when they are 433 // Non-persistent devices cannot be reliably identified when they are
469 // reconnected so such devices are only remembered until disconnect. 434 // reconnected so such devices are only remembered until disconnect.
470 // Register an observer here so that this set doesn't grow undefinitely. 435 // Register an observer here so that this set doesn't grow undefinitely.
471 device_permissions->entries_.insert(device_entry); 436 device_permissions->entries_.insert(device_entry);
472 device_permissions->ephemeral_devices_[device] = device_entry; 437 device_permissions->ephemeral_devices_[device] = device_entry;
473 438
474 // Only start observing when an ephemeral device has been added so that 439 // Only start observing when an ephemeral device has been added so that
475 // UsbService is not automatically initialized on profile creation (which it 440 // UsbService is not automatically initialized on profile creation (which it
476 // would be if this call were in the constructor). 441 // would be if this call were in the constructor).
477 if (!helper_) { 442 UsbService* usb_service = device::DeviceClient::Get()->GetUsbService();
478 helper_ = new FileThreadHelper(weak_factory_.GetWeakPtr()); 443 if (!usb_service_observer_.IsObserving(usb_service)) {
479 // base::Unretained is safe because any task to delete helper_ will be 444 usb_service_observer_.Add(usb_service);
480 // executed after this call.
481 BrowserThread::PostTask(
482 BrowserThread::FILE, FROM_HERE,
483 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_)));
484 } 445 }
485 } 446 }
486 } 447 }
487 448
488 void DevicePermissionsManager::UpdateLastUsed( 449 void DevicePermissionsManager::UpdateLastUsed(
489 const std::string& extension_id, 450 const std::string& extension_id,
490 scoped_refptr<DevicePermissionEntry> entry) { 451 scoped_refptr<DevicePermissionEntry> entry) {
491 DCHECK(CalledOnValidThread()); 452 DCHECK(CalledOnValidThread());
492 entry->set_last_used(base::Time::Now()); 453 entry->set_last_used(base::Time::Now());
493 if (entry->IsPersistent()) { 454 if (entry->IsPersistent()) {
(...skipping 24 matching lines...) Expand all
518 if (device_permissions) { 479 if (device_permissions) {
519 extension_id_to_device_permissions_.erase(extension_id); 480 extension_id_to_device_permissions_.erase(extension_id);
520 delete device_permissions; 481 delete device_permissions;
521 } 482 }
522 } 483 }
523 484
524 DevicePermissionsManager::DevicePermissionsManager( 485 DevicePermissionsManager::DevicePermissionsManager(
525 content::BrowserContext* context) 486 content::BrowserContext* context)
526 : context_(context), 487 : context_(context),
527 process_manager_observer_(this), 488 process_manager_observer_(this),
528 helper_(nullptr), 489 usb_service_observer_(this) {
529 weak_factory_(this) {
530 process_manager_observer_.Add(ProcessManager::Get(context)); 490 process_manager_observer_.Add(ProcessManager::Get(context));
531 } 491 }
532 492
533 DevicePermissionsManager::~DevicePermissionsManager() { 493 DevicePermissionsManager::~DevicePermissionsManager() {
534 for (const auto& map_entry : extension_id_to_device_permissions_) { 494 for (const auto& map_entry : extension_id_to_device_permissions_) {
535 DevicePermissions* device_permissions = map_entry.second; 495 DevicePermissions* device_permissions = map_entry.second;
536 delete device_permissions; 496 delete device_permissions;
537 } 497 }
538 if (helper_) {
539 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, helper_);
540 helper_ = nullptr;
541 }
542 } 498 }
543 499
544 DevicePermissions* DevicePermissionsManager::Get( 500 DevicePermissions* DevicePermissionsManager::Get(
545 const std::string& extension_id) const { 501 const std::string& extension_id) const {
546 std::map<std::string, DevicePermissions*>::const_iterator it = 502 std::map<std::string, DevicePermissions*>::const_iterator it =
547 extension_id_to_device_permissions_.find(extension_id); 503 extension_id_to_device_permissions_.find(extension_id);
548 if (it != extension_id_to_device_permissions_.end()) { 504 if (it != extension_id_to_device_permissions_.end()) {
549 return it->second; 505 return it->second;
550 } 506 }
551 507
552 return NULL; 508 return NULL;
553 } 509 }
554 510
555 DevicePermissions* DevicePermissionsManager::GetOrInsert(
556 const std::string& extension_id) {
557 DevicePermissions* device_permissions = Get(extension_id);
558 if (!device_permissions) {
559 device_permissions = new DevicePermissions(context_, extension_id);
560 extension_id_to_device_permissions_[extension_id] = device_permissions;
561 }
562
563 return device_permissions;
564 }
565
566 void DevicePermissionsManager::OnBackgroundHostClose( 511 void DevicePermissionsManager::OnBackgroundHostClose(
567 const std::string& extension_id) { 512 const std::string& extension_id) {
568 DCHECK(CalledOnValidThread()); 513 DCHECK(CalledOnValidThread());
569 514
570 DevicePermissions* device_permissions = Get(extension_id); 515 DevicePermissions* device_permissions = Get(extension_id);
571 if (device_permissions) { 516 if (device_permissions) {
572 // When all of the app's windows are closed and the background page is 517 // When all of the app's windows are closed and the background page is
573 // suspended all ephemeral device permissions are cleared. 518 // suspended all ephemeral device permissions are cleared.
574 for (const auto& map_entry : device_permissions->ephemeral_devices_) { 519 for (const auto& map_entry : device_permissions->ephemeral_devices_) {
575 device_permissions->entries_.erase(map_entry.second); 520 device_permissions->entries_.erase(map_entry.second);
576 } 521 }
577 device_permissions->ephemeral_devices_.clear(); 522 device_permissions->ephemeral_devices_.clear();
578 } 523 }
579 } 524 }
580 525
581 void DevicePermissionsManager::OnDeviceRemoved( 526 void DevicePermissionsManager::OnDeviceRemovedCleanup(
582 scoped_refptr<UsbDevice> device) { 527 scoped_refptr<UsbDevice> device) {
583 DCHECK(CalledOnValidThread()); 528 DCHECK(CalledOnValidThread());
584 for (const auto& map_entry : extension_id_to_device_permissions_) { 529 for (const auto& map_entry : extension_id_to_device_permissions_) {
585 // An ephemeral device cannot be identified if it is reconnected and so 530 // An ephemeral device cannot be identified if it is reconnected and so
586 // permission to access it is cleared on disconnect. 531 // permission to access it is cleared on disconnect.
587 DevicePermissions* device_permissions = map_entry.second; 532 DevicePermissions* device_permissions = map_entry.second;
588 const auto& device_entry = 533 const auto& device_entry =
589 device_permissions->ephemeral_devices_.find(device); 534 device_permissions->ephemeral_devices_.find(device);
590 if (device_entry != device_permissions->ephemeral_devices_.end()) { 535 if (device_entry != device_permissions->ephemeral_devices_.end()) {
591 device_permissions->entries_.erase(device_entry->second); 536 device_permissions->entries_.erase(device_entry->second);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 569
625 BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse( 570 BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse(
626 BrowserContext* context) const { 571 BrowserContext* context) const {
627 // Return the original (possibly off-the-record) browser context so that a 572 // Return the original (possibly off-the-record) browser context so that a
628 // separate instance of the DevicePermissionsManager is used in incognito 573 // separate instance of the DevicePermissionsManager is used in incognito
629 // mode. The parent class's implemenation returns NULL. 574 // mode. The parent class's implemenation returns NULL.
630 return context; 575 return context;
631 } 576 }
632 577
633 } // namespace extensions 578 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698