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

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 DCHECK(preferences->IsInitialized());
vandebo (ex-Chrome) 2013/09/26 22:42:36 nit: remove
tommycli 2013/09/26 23:53:33 Done.
442
441 MediaGalleryPrefIdSet galleries = 443 MediaGalleryPrefIdSet galleries =
442 preferences->GalleriesForExtension(*extension); 444 preferences->GalleriesForExtension(*extension);
443 445
444 if (galleries.empty()) { 446 if (galleries.empty()) {
445 callback.Run(std::vector<MediaFileSystemInfo>()); 447 callback.Run(std::vector<MediaFileSystemInfo>());
446 return; 448 return;
447 } 449 }
448 450
449 ExtensionGalleriesHostMap::iterator extension_hosts = 451 ExtensionGalleriesHostMap::iterator extension_hosts =
450 extension_hosts_map_.find(profile); 452 extension_hosts_map_.find(profile);
451 if (extension_hosts->second.empty()) 453 if (extension_hosts->second.empty())
452 preferences->AddGalleryChangeObserver(this); 454 preferences->AddGalleryChangeObserver(this);
453 455
454 ExtensionGalleriesHost* extension_host = 456 ExtensionGalleriesHost* extension_host =
455 extension_hosts->second[extension->id()].get(); 457 extension_hosts->second[extension->id()].get();
456 if (!extension_host) { 458 if (!extension_host) {
457 extension_host = new ExtensionGalleriesHost( 459 extension_host = new ExtensionGalleriesHost(
458 file_system_context_.get(), 460 file_system_context_.get(),
459 base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty, 461 base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty,
460 base::Unretained(this), profile, extension->id())); 462 base::Unretained(this),
463 profile,
464 extension->id()));
461 extension_hosts_map_[profile][extension->id()] = extension_host; 465 extension_hosts_map_[profile][extension->id()] = extension_host;
462 } 466 }
463 extension_host->ReferenceFromRVH(rvh); 467 extension_host->ReferenceFromRVH(rvh);
464 468
465 extension_host->GetMediaFileSystems(galleries, preferences->known_galleries(), 469 extension_host->GetMediaFileSystems(galleries, preferences->known_galleries(),
466 callback); 470 callback);
467 } 471 }
468 472
469 MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences( 473 MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences(
470 Profile* profile) { 474 Profile* profile) {
471 MediaGalleriesPreferences* preferences = 475 // Create an empty ExtensionHostMap for this profile on first initialization.
472 MediaGalleriesPreferencesFactory::GetForProfile(profile); 476 if (!ContainsKey(extension_hosts_map_, profile))
473 if (ContainsKey(extension_hosts_map_, profile)) 477 extension_hosts_map_[profile] = ExtensionHostMap();
474 return preferences;
475 478
476 // Create an empty entry so the initialization code below only gets called 479 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 } 480 }
500 481
501 void MediaFileSystemRegistry::OnRemovableStorageDetached( 482 void MediaFileSystemRegistry::OnRemovableStorageDetached(
502 const StorageInfo& info) { 483 const StorageInfo& info) {
503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 484 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
504 485
505 // Since revoking a gallery in the ExtensionGalleriesHost may cause it 486 // Since revoking a gallery in the ExtensionGalleriesHost may cause it
506 // to be removed from the map and therefore invalidate any iterator pointing 487 // 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 488 // 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 489 // extension hosts in which they may appear (per profile) and revoked it in
509 // a second step. 490 // a second step.
510 std::vector<InvalidatedGalleriesInfo> invalid_galleries_info; 491 std::vector<InvalidatedGalleriesInfo> invalid_galleries_info;
511 492
512 for (ExtensionGalleriesHostMap::iterator profile_it = 493 for (ExtensionGalleriesHostMap::iterator profile_it =
513 extension_hosts_map_.begin(); 494 extension_hosts_map_.begin();
514 profile_it != extension_hosts_map_.end(); 495 profile_it != extension_hosts_map_.end();
515 ++profile_it) { 496 ++profile_it) {
516 MediaGalleriesPreferences* preferences = GetPreferences(profile_it->first); 497 MediaGalleriesPreferences* preferences = GetPreferences(profile_it->first);
498 // If |preferences| is not yet initialized, it won't contain any galleries.
499 if (!preferences->IsInitialized())
500 continue;
501
517 InvalidatedGalleriesInfo invalid_galleries_in_profile; 502 InvalidatedGalleriesInfo invalid_galleries_in_profile;
518 invalid_galleries_in_profile.pref_ids = 503 invalid_galleries_in_profile.pref_ids =
519 preferences->LookUpGalleriesByDeviceId(info.device_id()); 504 preferences->LookUpGalleriesByDeviceId(info.device_id());
520 505
521 for (ExtensionHostMap::const_iterator extension_host_it = 506 for (ExtensionHostMap::const_iterator extension_host_it =
522 profile_it->second.begin(); 507 profile_it->second.begin();
523 extension_host_it != profile_it->second.end(); 508 extension_host_it != profile_it->second.end();
524 ++extension_host_it) { 509 ++extension_host_it) {
525 invalid_galleries_in_profile.extension_hosts.insert( 510 invalid_galleries_in_profile.extension_hosts.insert(
526 extension_host_it->second.get()); 511 extension_host_it->second.get());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 597
613 IsolatedContext::GetInstance()->RevokeFileSystem(fsid); 598 IsolatedContext::GetInstance()->RevokeFileSystem(fsid);
614 } 599 }
615 600
616 private: 601 private:
617 MediaFileSystemRegistry* registry_; 602 MediaFileSystemRegistry* registry_;
618 603
619 DISALLOW_COPY_AND_ASSIGN(MediaFileSystemContextImpl); 604 DISALLOW_COPY_AND_ASSIGN(MediaFileSystemContextImpl);
620 }; 605 };
621 606
607 // Constructor in 'private' section because depends on private class definition.
622 MediaFileSystemRegistry::MediaFileSystemRegistry() 608 MediaFileSystemRegistry::MediaFileSystemRegistry()
623 : file_system_context_(new MediaFileSystemContextImpl(this)) { 609 : file_system_context_(new MediaFileSystemContextImpl(this)) {
624 StorageMonitor::GetInstance()->AddObserver(this); 610 StorageMonitor::GetInstance()->AddObserver(this);
625 } 611 }
626 612
627 MediaFileSystemRegistry::~MediaFileSystemRegistry() { 613 MediaFileSystemRegistry::~MediaFileSystemRegistry() {
628 // TODO(gbillock): This is needed because the unit test uses the 614 // TODO(gbillock): This is needed because the unit test uses the
629 // g_browser_process registry. We should create one in the unit test, 615 // g_browser_process registry. We should create one in the unit test,
630 // and then can remove this. 616 // and then can remove this.
631 if (StorageMonitor::GetInstance()) 617 if (StorageMonitor::GetInstance())
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 DCHECK(extension_hosts != extension_hosts_map_.end()); 712 DCHECK(extension_hosts != extension_hosts_map_.end());
727 ExtensionHostMap::size_type erase_count = 713 ExtensionHostMap::size_type erase_count =
728 extension_hosts->second.erase(extension_id); 714 extension_hosts->second.erase(extension_id);
729 DCHECK_EQ(1U, erase_count); 715 DCHECK_EQ(1U, erase_count);
730 if (extension_hosts->second.empty()) { 716 if (extension_hosts->second.empty()) {
731 // When a profile has no ExtensionGalleriesHosts left, remove the 717 // When a profile has no ExtensionGalleriesHosts left, remove the
732 // matching gallery-change-watcher since it is no longer needed. Leave the 718 // matching gallery-change-watcher since it is no longer needed. Leave the
733 // |extension_hosts| entry alone, since it indicates the profile has been 719 // |extension_hosts| entry alone, since it indicates the profile has been
734 // previously used. 720 // previously used.
735 MediaGalleriesPreferences* preferences = GetPreferences(profile); 721 MediaGalleriesPreferences* preferences = GetPreferences(profile);
722 DCHECK(preferences->IsInitialized());
vandebo (ex-Chrome) 2013/09/26 22:42:36 nit: remove
tommycli 2013/09/26 23:53:33 Done.
736 preferences->RemoveGalleryChangeObserver(this); 723 preferences->RemoveGalleryChangeObserver(this);
737 } 724 }
738 } 725 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698