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

Side by Side Diff: chrome/browser/media_galleries/media_file_system_registry.cc

Issue 24269007: Media Galleries API: Fix MediaGalleriesPreferences finders race. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // MediaFileSystemRegistry implementation. 5 // MediaFileSystemRegistry implementation.
6 6
7 #include "chrome/browser/media_galleries/media_file_system_registry.h" 7 #include "chrome/browser/media_galleries/media_file_system_registry.h"
8 8
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 431
432 void MediaFileSystemRegistry::GetMediaFileSystemsForExtension( 432 void MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
433 const content::RenderViewHost* rvh, 433 const content::RenderViewHost* rvh,
434 const extensions::Extension* extension, 434 const extensions::Extension* extension,
435 const MediaFileSystemsCallback& callback) { 435 const MediaFileSystemsCallback& callback) {
436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
437 437
438 Profile* profile = 438 Profile* profile =
439 Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext()); 439 Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext());
440 MediaGalleriesPreferences* preferences = GetPreferences(profile); 440 MediaGalleriesPreferences* preferences = GetPreferences(profile);
441 MediaGalleryPrefIdSet galleries = 441 preferences->EnsureInitialized(base::Bind(
vandebo (ex-Chrome) 2013/09/21 01:20:59 Are we not already sure that preferences have been
tommycli 2013/09/23 20:39:12 I made this assume it was already initialized, and
442 preferences->GalleriesForExtension(*extension); 442 &MediaFileSystemRegistry::FinishGetMediaFileSystemsForExtension,
443 443 weak_factory_.GetWeakPtr(),
444 if (galleries.empty()) { 444 rvh,
445 callback.Run(std::vector<MediaFileSystemInfo>()); 445 extension,
446 return; 446 callback));
447 }
448
449 ExtensionGalleriesHostMap::iterator extension_hosts =
450 extension_hosts_map_.find(profile);
451 if (extension_hosts->second.empty())
452 preferences->AddGalleryChangeObserver(this);
453
454 ExtensionGalleriesHost* extension_host =
455 extension_hosts->second[extension->id()].get();
456 if (!extension_host) {
457 extension_host = new ExtensionGalleriesHost(
458 file_system_context_.get(),
459 base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty,
460 base::Unretained(this), profile, extension->id()));
461 extension_hosts_map_[profile][extension->id()] = extension_host;
462 }
463 extension_host->ReferenceFromRVH(rvh);
464
465 extension_host->GetMediaFileSystems(galleries, preferences->known_galleries(),
466 callback);
467 } 447 }
468 448
469 MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences( 449 MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences(
470 Profile* profile) { 450 Profile* profile) {
471 MediaGalleriesPreferences* preferences = 451 // Create an empty ExtensionHostMap for this profile on first initialization.
472 MediaGalleriesPreferencesFactory::GetForProfile(profile); 452 if (!ContainsKey(extension_hosts_map_, profile))
473 if (ContainsKey(extension_hosts_map_, profile)) 453 extension_hosts_map_[profile] = ExtensionHostMap();
474 return preferences;
475 454
476 // Create an empty entry so the initialization code below only gets called 455 return MediaGalleriesPreferencesFactory::GetForProfile(profile);
477 // once per profile.
478 extension_hosts_map_[profile] = ExtensionHostMap();
479
480 // TODO(gbillock): Move this stanza to MediaGalleriesPreferences init code.
481 StorageMonitor* monitor = StorageMonitor::GetInstance();
482 DCHECK(monitor->IsInitialized());
483 std::vector<StorageInfo> existing_devices =
484 monitor->GetAllAvailableStorages();
485 for (size_t i = 0; i < existing_devices.size(); i++) {
486 if (!(StorageInfo::IsMediaDevice(existing_devices[i].device_id()) &&
487 StorageInfo::IsRemovableDevice(existing_devices[i].device_id())))
488 continue;
489 preferences->AddGallery(existing_devices[i].device_id(),
490 base::FilePath(),
491 false,
492 existing_devices[i].storage_label(),
493 existing_devices[i].vendor_name(),
494 existing_devices[i].model_name(),
495 existing_devices[i].total_size_in_bytes(),
496 base::Time::Now());
497 }
498 return preferences;
499 } 456 }
500 457
501 void MediaFileSystemRegistry::OnRemovableStorageDetached( 458 void MediaFileSystemRegistry::OnRemovableStorageDetached(
502 const StorageInfo& info) { 459 const StorageInfo& info) {
503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 460 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
504 461
505 // Since revoking a gallery in the ExtensionGalleriesHost may cause it 462 // Since revoking a gallery in the ExtensionGalleriesHost may cause it
506 // to be removed from the map and therefore invalidate any iterator pointing 463 // to be removed from the map and therefore invalidate any iterator pointing
507 // to it, this code first copies all the invalid gallery ids and the 464 // to it, this code first copies all the invalid gallery ids and the
508 // extension hosts in which they may appear (per profile) and revoked it in 465 // extension hosts in which they may appear (per profile) and revoked it in
509 // a second step. 466 // a second step.
510 std::vector<InvalidatedGalleriesInfo> invalid_galleries_info; 467 std::vector<InvalidatedGalleriesInfo> invalid_galleries_info;
511 468
512 for (ExtensionGalleriesHostMap::iterator profile_it = 469 for (ExtensionGalleriesHostMap::iterator profile_it =
513 extension_hosts_map_.begin(); 470 extension_hosts_map_.begin();
514 profile_it != extension_hosts_map_.end(); 471 profile_it != extension_hosts_map_.end();
515 ++profile_it) { 472 ++profile_it) {
516 MediaGalleriesPreferences* preferences = GetPreferences(profile_it->first); 473 MediaGalleriesPreferences* preferences = GetPreferences(profile_it->first);
474 // If |preferences| is not yet initialized, it won't contain any galleries.
475 if (!preferences->IsInitialized())
476 continue;
477
517 InvalidatedGalleriesInfo invalid_galleries_in_profile; 478 InvalidatedGalleriesInfo invalid_galleries_in_profile;
518 invalid_galleries_in_profile.pref_ids = 479 invalid_galleries_in_profile.pref_ids =
519 preferences->LookUpGalleriesByDeviceId(info.device_id()); 480 preferences->LookUpGalleriesByDeviceId(info.device_id());
520 481
521 for (ExtensionHostMap::const_iterator extension_host_it = 482 for (ExtensionHostMap::const_iterator extension_host_it =
522 profile_it->second.begin(); 483 profile_it->second.begin();
523 extension_host_it != profile_it->second.end(); 484 extension_host_it != profile_it->second.end();
524 ++extension_host_it) { 485 ++extension_host_it) {
525 invalid_galleries_in_profile.extension_hosts.insert( 486 invalid_galleries_in_profile.extension_hosts.insert(
526 extension_host_it->second.get()); 487 extension_host_it->second.get());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 573
613 IsolatedContext::GetInstance()->RevokeFileSystem(fsid); 574 IsolatedContext::GetInstance()->RevokeFileSystem(fsid);
614 } 575 }
615 576
616 private: 577 private:
617 MediaFileSystemRegistry* registry_; 578 MediaFileSystemRegistry* registry_;
618 579
619 DISALLOW_COPY_AND_ASSIGN(MediaFileSystemContextImpl); 580 DISALLOW_COPY_AND_ASSIGN(MediaFileSystemContextImpl);
620 }; 581 };
621 582
583 // Constructor in 'private' section because depends on private class definition.
622 MediaFileSystemRegistry::MediaFileSystemRegistry() 584 MediaFileSystemRegistry::MediaFileSystemRegistry()
623 : file_system_context_(new MediaFileSystemContextImpl(this)) { 585 : weak_factory_(this),
586 file_system_context_(new MediaFileSystemContextImpl(this)) {
624 StorageMonitor::GetInstance()->AddObserver(this); 587 StorageMonitor::GetInstance()->AddObserver(this);
625 } 588 }
626 589
627 MediaFileSystemRegistry::~MediaFileSystemRegistry() { 590 MediaFileSystemRegistry::~MediaFileSystemRegistry() {
628 // TODO(gbillock): This is needed because the unit test uses the 591 // TODO(gbillock): This is needed because the unit test uses the
629 // g_browser_process registry. We should create one in the unit test, 592 // g_browser_process registry. We should create one in the unit test,
630 // and then can remove this. 593 // and then can remove this.
631 if (StorageMonitor::GetInstance()) 594 if (StorageMonitor::GetInstance())
632 StorageMonitor::GetInstance()->RemoveObserver(this); 595 StorageMonitor::GetInstance()->RemoveObserver(this);
633 DCHECK(mtp_device_delegate_map_.empty()); 596 DCHECK(mtp_device_delegate_map_.empty());
634 } 597 }
635 598
599 void MediaFileSystemRegistry::FinishGetMediaFileSystemsForExtension(
600 const content::RenderViewHost* rvh,
601 const extensions::Extension* extension,
602 const MediaFileSystemsCallback& callback) {
603 Profile* profile =
604 Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext());
605 MediaGalleriesPreferences* preferences = GetPreferences(profile);
606 DCHECK(preferences->IsInitialized());
607 MediaGalleryPrefIdSet galleries =
608 preferences->GalleriesForExtension(*extension);
609
610 if (galleries.empty()) {
611 callback.Run(std::vector<MediaFileSystemInfo>());
612 return;
613 }
614
615 ExtensionGalleriesHostMap::iterator extension_hosts =
616 extension_hosts_map_.find(profile);
617 if (extension_hosts->second.empty())
618 preferences->AddGalleryChangeObserver(this);
619
620 ExtensionGalleriesHost* extension_host =
621 extension_hosts->second[extension->id()].get();
622 if (!extension_host) {
623 extension_host = new ExtensionGalleriesHost(
624 file_system_context_.get(),
625 base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty,
626 base::Unretained(this),
627 profile,
628 extension->id()));
629 extension_hosts_map_[profile][extension->id()] = extension_host;
630 }
631 extension_host->ReferenceFromRVH(rvh);
632
633 extension_host->GetMediaFileSystems(
634 galleries, preferences->known_galleries(), callback);
635 }
636
636 void MediaFileSystemRegistry::OnPermissionRemoved( 637 void MediaFileSystemRegistry::OnPermissionRemoved(
637 MediaGalleriesPreferences* prefs, 638 MediaGalleriesPreferences* prefs,
638 const std::string& extension_id, 639 const std::string& extension_id,
639 MediaGalleryPrefId pref_id) { 640 MediaGalleryPrefId pref_id) {
640 Profile* profile = prefs->profile(); 641 Profile* profile = prefs->profile();
641 ExtensionGalleriesHostMap::const_iterator host_map_it = 642 ExtensionGalleriesHostMap::const_iterator host_map_it =
642 extension_hosts_map_.find(profile); 643 extension_hosts_map_.find(profile);
643 DCHECK(host_map_it != extension_hosts_map_.end()); 644 DCHECK(host_map_it != extension_hosts_map_.end());
644 const ExtensionHostMap& extension_host_map = host_map_it->second; 645 const ExtensionHostMap& extension_host_map = host_map_it->second;
645 ExtensionHostMap::const_iterator gallery_host_it = 646 ExtensionHostMap::const_iterator gallery_host_it =
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 DCHECK(extension_hosts != extension_hosts_map_.end()); 727 DCHECK(extension_hosts != extension_hosts_map_.end());
727 ExtensionHostMap::size_type erase_count = 728 ExtensionHostMap::size_type erase_count =
728 extension_hosts->second.erase(extension_id); 729 extension_hosts->second.erase(extension_id);
729 DCHECK_EQ(1U, erase_count); 730 DCHECK_EQ(1U, erase_count);
730 if (extension_hosts->second.empty()) { 731 if (extension_hosts->second.empty()) {
731 // When a profile has no ExtensionGalleriesHosts left, remove the 732 // When a profile has no ExtensionGalleriesHosts left, remove the
732 // matching gallery-change-watcher since it is no longer needed. Leave the 733 // matching gallery-change-watcher since it is no longer needed. Leave the
733 // |extension_hosts| entry alone, since it indicates the profile has been 734 // |extension_hosts| entry alone, since it indicates the profile has been
734 // previously used. 735 // previously used.
735 MediaGalleriesPreferences* preferences = GetPreferences(profile); 736 MediaGalleriesPreferences* preferences = GetPreferences(profile);
737 DCHECK(preferences->IsInitialized());
736 preferences->RemoveGalleryChangeObserver(this); 738 preferences->RemoveGalleryChangeObserver(this);
737 } 739 }
738 } 740 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698