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

Unified Diff: chrome/browser/media_galleries/media_galleries_preferences.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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media_galleries/media_galleries_preferences.cc
diff --git a/chrome/browser/media_galleries/media_galleries_preferences.cc b/chrome/browser/media_galleries/media_galleries_preferences.cc
index ac1e632cc163580878e9f65b5febe0db43e6b0b7..f3f80975e1cc66bd575d84bcb81a95b86472db0f 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences.cc
+++ b/chrome/browser/media_galleries/media_galleries_preferences.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/media_galleries/media_galleries_preferences.h"
#include "base/base_paths_posix.h"
+#include "base/callback.h"
#include "base/i18n/time_formatting.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
@@ -31,6 +32,7 @@
#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
+#include "content/public/browser/browser_thread.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/text/bytes_formatting.h"
@@ -344,34 +346,97 @@ MediaGalleriesPreferences::GalleryChangeObserver::~GalleryChangeObserver() {}
MediaGalleriesPreferences::MediaGalleriesPreferences(Profile* profile)
: weak_factory_(this),
+ initialized_(false),
+ pre_initialization_callbacks_waiting_(0),
profile_(profile),
- extension_prefs_for_testing_(NULL) {
+ extension_prefs_for_testing_(NULL) {}
+
+MediaGalleriesPreferences::~MediaGalleriesPreferences() {
+ if (StorageMonitor::GetInstance())
+ StorageMonitor::GetInstance()->RemoveObserver(this);
+}
+
+void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ if (IsInitialized()) {
+ if (!callback.is_null())
+ callback.Run();
+ return;
+ }
+
+ on_initialize_callbacks_.push_back(callback);
+ if (on_initialize_callbacks_.size() > 1)
+ return;
+
AddDefaultGalleriesIfFreshProfile();
+ pre_initialization_callbacks_waiting_ = 2;
+
+ // Ensure StorageMonitor is initialized.
+ StorageMonitor::GetInstance()->EnsureInitialized(
+ base::Bind(&MediaGalleriesPreferences::OnInitializationCallbackReturned,
+ weak_factory_.GetWeakPtr()));
+
// Look for optional default galleries every time.
itunes::ITunesFinder::FindITunesLibrary(
- base::Bind(&MediaGalleriesPreferences::OnITunesDeviceID,
+ base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
weak_factory_.GetWeakPtr()));
// TODO(tommycli): Turn on when Picasa code is ready.
#if 0
picasa::PicasaFinder::FindPicasaDatabaseOnUIThread(
- base::Bind(&MediaGalleriesPreferences::OnPicasaDeviceID,
+ base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
weak_factory_.GetWeakPtr()));
#endif
+}
+
+bool MediaGalleriesPreferences::IsInitialized() const { return initialized_; }
+
+Profile* MediaGalleriesPreferences::profile() { return profile_; }
+
+void MediaGalleriesPreferences::OnInitializationCallbackReturned() {
+ DCHECK(!IsInitialized());
+ DCHECK(pre_initialization_callbacks_waiting_ > 0);
+ if (--pre_initialization_callbacks_waiting_ == 0)
+ FinishInitialization();
+}
+
+void MediaGalleriesPreferences::FinishInitialization() {
+ DCHECK(!IsInitialized());
+
+ initialized_ = true;
+
+ StorageMonitor* monitor = StorageMonitor::GetInstance();
+ DCHECK(monitor->IsInitialized());
InitFromPrefs();
StorageMonitor::GetInstance()->AddObserver(this);
-}
-MediaGalleriesPreferences::~MediaGalleriesPreferences() {
- if (StorageMonitor::GetInstance())
- StorageMonitor::GetInstance()->RemoveObserver(this);
-}
+ std::vector<StorageInfo> existing_devices =
+ monitor->GetAllAvailableStorages();
+ for (size_t i = 0; i < existing_devices.size(); i++) {
+ if (!(StorageInfo::IsMediaDevice(existing_devices[i].device_id()) &&
+ StorageInfo::IsRemovableDevice(existing_devices[i].device_id())))
+ continue;
+ AddGallery(existing_devices[i].device_id(),
+ base::FilePath(),
+ false,
+ existing_devices[i].storage_label(),
+ existing_devices[i].vendor_name(),
+ existing_devices[i].model_name(),
+ existing_devices[i].total_size_in_bytes(),
+ base::Time::Now());
+ }
-Profile* MediaGalleriesPreferences::profile() {
- return profile_;
+ for (std::vector<base::Closure>::iterator iter =
+ on_initialize_callbacks_.begin();
+ iter != on_initialize_callbacks_.end();
+ ++iter) {
+ iter->Run();
+ }
+ on_initialize_callbacks_.clear();
}
void MediaGalleriesPreferences::AddDefaultGalleriesIfFreshProfile() {
@@ -442,25 +507,23 @@ bool MediaGalleriesPreferences::UpdateDeviceIDForSingletonType(
return false;
}
-void MediaGalleriesPreferences::OnITunesDeviceID(const std::string& device_id) {
- if (device_id.empty())
- return;
- if (!UpdateDeviceIDForSingletonType(device_id)) {
- AddGalleryInternal(device_id, ASCIIToUTF16(kITunesGalleryName),
- base::FilePath(), false /*not user added*/,
- string16(), string16(), string16(), 0,
- base::Time(), false, 2);
- }
-}
+void MediaGalleriesPreferences::OnFinderDeviceID(const std::string& device_id) {
+ if (!device_id.empty() && !UpdateDeviceIDForSingletonType(device_id)) {
+ std::string gallery_name;
+ if (StorageInfo::IsITunesDevice(device_id))
+ gallery_name = kITunesGalleryName;
+ else if (StorageInfo::IsPicasaDevice(device_id))
+ gallery_name = kPicasaGalleryName;
+ else
+ NOTREACHED();
-void MediaGalleriesPreferences::OnPicasaDeviceID(const std::string& device_id) {
- DCHECK(!device_id.empty());
- if (!UpdateDeviceIDForSingletonType(device_id)) {
- AddGalleryInternal(device_id, ASCIIToUTF16(kPicasaGalleryName),
+ AddGalleryInternal(device_id, ASCIIToUTF16(gallery_name),
base::FilePath(), false /*not user added*/,
string16(), string16(), string16(), 0,
base::Time(), false, 2);
}
+
+ OnInitializationCallbackReturned();
}
void MediaGalleriesPreferences::InitFromPrefs() {
@@ -489,16 +552,19 @@ void MediaGalleriesPreferences::InitFromPrefs() {
void MediaGalleriesPreferences::AddGalleryChangeObserver(
GalleryChangeObserver* observer) {
+ DCHECK(IsInitialized());
gallery_change_observers_.AddObserver(observer);
}
void MediaGalleriesPreferences::RemoveGalleryChangeObserver(
GalleryChangeObserver* observer) {
+ DCHECK(IsInitialized());
gallery_change_observers_.RemoveObserver(observer);
}
void MediaGalleriesPreferences::OnRemovableStorageAttached(
const StorageInfo& info) {
+ DCHECK(IsInitialized());
if (!StorageInfo::IsMediaDevice(info.device_id()))
return;
@@ -514,6 +580,7 @@ void MediaGalleriesPreferences::OnRemovableStorageAttached(
bool MediaGalleriesPreferences::LookUpGalleryByPath(
const base::FilePath& path,
MediaGalleryPrefInfo* gallery_info) const {
+ DCHECK(IsInitialized());
StorageInfo info;
base::FilePath relative_path;
if (!MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
@@ -572,6 +639,7 @@ base::FilePath MediaGalleriesPreferences::LookUpGalleryPathForExtension(
MediaGalleryPrefId gallery_id,
const extensions::Extension* extension,
bool include_unpermitted_galleries) {
+ DCHECK(IsInitialized());
DCHECK(extension);
if (!include_unpermitted_galleries &&
!ContainsKey(GalleriesForExtension(*extension), gallery_id))
@@ -590,6 +658,7 @@ MediaGalleryPrefId MediaGalleriesPreferences::AddGallery(
const string16& volume_label, const string16& vendor_name,
const string16& model_name, uint64 total_size_in_bytes,
base::Time last_attach_time) {
+ DCHECK(IsInitialized());
return AddGalleryInternal(device_id, string16(), relative_path, user_added,
volume_label, vendor_name, model_name,
total_size_in_bytes, last_attach_time, true, 2);
@@ -722,6 +791,7 @@ MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryInternal(
MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryByPath(
const base::FilePath& path) {
+ DCHECK(IsInitialized());
MediaGalleryPrefInfo gallery_info;
if (LookUpGalleryByPath(path, &gallery_info) &&
gallery_info.type != MediaGalleryPrefInfo::kBlackListed) {
@@ -741,6 +811,7 @@ MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryByPath(
}
void MediaGalleriesPreferences::ForgetGalleryById(MediaGalleryPrefId pref_id) {
+ DCHECK(IsInitialized());
PrefService* prefs = profile_->GetPrefs();
scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
prefs, prefs::kMediaGalleriesRememberedGalleries));
@@ -776,6 +847,7 @@ void MediaGalleriesPreferences::ForgetGalleryById(MediaGalleryPrefId pref_id) {
MediaGalleryPrefIdSet MediaGalleriesPreferences::GalleriesForExtension(
const extensions::Extension& extension) const {
+ DCHECK(IsInitialized());
MediaGalleryPrefIdSet result;
if (HasAutoDetectedGalleryPermission(extension)) {
@@ -810,6 +882,7 @@ bool MediaGalleriesPreferences::SetGalleryPermissionForExtension(
const extensions::Extension& extension,
MediaGalleryPrefId pref_id,
bool has_permission) {
+ DCHECK(IsInitialized());
// The gallery may not exist anymore if the user opened a second config
// surface concurrently and removed it. Drop the permission update if so.
MediaGalleriesPrefInfoMap::const_iterator gallery_info =
@@ -840,6 +913,12 @@ bool MediaGalleriesPreferences::SetGalleryPermissionForExtension(
return true;
}
+const MediaGalleriesPrefInfoMap& MediaGalleriesPreferences::known_galleries()
+ const {
+ DCHECK(IsInitialized());
+ return known_galleries_;
+}
+
void MediaGalleriesPreferences::Shutdown() {
weak_factory_.InvalidateWeakPtrs();
profile_ = NULL;
@@ -867,6 +946,7 @@ bool MediaGalleriesPreferences::SetGalleryPermissionInPrefs(
const std::string& extension_id,
MediaGalleryPrefId gallery_id,
bool has_access) {
+ DCHECK(IsInitialized());
ExtensionPrefs::ScopedListUpdate update(GetExtensionPrefs(),
extension_id,
kMediaGalleriesPermissions);
@@ -904,6 +984,7 @@ bool MediaGalleriesPreferences::SetGalleryPermissionInPrefs(
bool MediaGalleriesPreferences::UnsetGalleryPermissionInPrefs(
const std::string& extension_id,
MediaGalleryPrefId gallery_id) {
+ DCHECK(IsInitialized());
ExtensionPrefs::ScopedListUpdate update(GetExtensionPrefs(),
extension_id,
kMediaGalleriesPermissions);
@@ -930,6 +1011,7 @@ bool MediaGalleriesPreferences::UnsetGalleryPermissionInPrefs(
std::vector<MediaGalleryPermission>
MediaGalleriesPreferences::GetGalleryPermissionsFromPrefs(
const std::string& extension_id) const {
+ DCHECK(IsInitialized());
std::vector<MediaGalleryPermission> result;
const ListValue* permissions;
if (!GetExtensionPrefs()->ReadPrefAsList(extension_id,
@@ -954,6 +1036,7 @@ MediaGalleriesPreferences::GetGalleryPermissionsFromPrefs(
void MediaGalleriesPreferences::RemoveGalleryPermissionsFromPrefs(
MediaGalleryPrefId gallery_id) {
+ DCHECK(IsInitialized());
ExtensionPrefs* prefs = GetExtensionPrefs();
const DictionaryValue* extensions =
prefs->pref_service()->GetDictionary(prefs::kExtensionsPref);
@@ -971,6 +1054,7 @@ void MediaGalleriesPreferences::RemoveGalleryPermissionsFromPrefs(
}
ExtensionPrefs* MediaGalleriesPreferences::GetExtensionPrefs() const {
+ DCHECK(IsInitialized());
if (extension_prefs_for_testing_)
return extension_prefs_for_testing_;
return extensions::ExtensionPrefs::Get(profile_);
@@ -978,5 +1062,6 @@ ExtensionPrefs* MediaGalleriesPreferences::GetExtensionPrefs() const {
void MediaGalleriesPreferences::SetExtensionPrefsForTesting(
extensions::ExtensionPrefs* extension_prefs) {
+ DCHECK(IsInitialized());
extension_prefs_for_testing_ = extension_prefs;
}

Powered by Google App Engine
This is Rietveld 408576698