Chromium Code Reviews| Index: chrome/browser/media_gallery/media_galleries_dialog_controller.cc |
| =================================================================== |
| --- chrome/browser/media_gallery/media_galleries_dialog_controller.cc (revision 180515) |
| +++ chrome/browser/media_gallery/media_galleries_dialog_controller.cc (working copy) |
| @@ -5,6 +5,7 @@ |
| #include "chrome/browser/media_gallery/media_galleries_dialog_controller.h" |
| #include "base/path_service.h" |
| +#include "base/stl_util.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/media_gallery/media_file_system_registry.h" |
| @@ -59,6 +60,8 @@ |
| RemovableStorageNotifications::GetInstance(); |
| if (notifications) |
| notifications->AddObserver(this); |
| + |
| + preferences_->AddGalleryChangeObserver(this); |
| } |
| MediaGalleriesDialogController::MediaGalleriesDialogController() |
| @@ -137,6 +140,10 @@ |
| known_galleries_.find(gallery->pref_id); |
| if (iter != known_galleries_.end()) { |
| iter->second.allowed = enabled; |
|
vandebo (ex-Chrome)
2013/02/06 00:42:23
DCHECK_NE(iter->second.allowed, enabled) ?
Lei Zhang
2013/02/07 01:44:56
Done.
|
| + if (ContainsKey(toggled_galleries_, gallery->pref_id)) |
| + toggled_galleries_.erase(gallery->pref_id); |
| + else |
| + toggled_galleries_.insert(gallery->pref_id); |
| return; |
| } |
| @@ -153,6 +160,12 @@ |
| } |
| void MediaGalleriesDialogController::DialogFinished(bool accepted) { |
| + // The dialog has finished, so there is no need to watch for more updates |
| + // from |preferences_|. Do this here and not in the dtor since this is the |
| + // only non-test code path that deletes |this|. The test ctor never adds |
|
vandebo (ex-Chrome)
2013/02/06 00:42:23
How can the test ctor never add the observer? The
Lei Zhang
2013/02/07 01:44:56
The tests go through MediaGalleriesDialogControlle
|
| + // this observer in the first place. |
| + preferences_->RemoveGalleryChangeObserver(this); |
| + |
| if (accepted) |
| SavePermissions(); |
| @@ -172,20 +185,16 @@ |
| void MediaGalleriesDialogController::FileSelected(const FilePath& path, |
| int /*index*/, |
| void* /*params*/) { |
| - // Try to find it in |known_galleries_|. |
| + // Try to find it in the prefs. |
| MediaGalleryPrefInfo gallery; |
| bool gallery_exists = preferences_->LookUpGalleryByPath(path, &gallery); |
| if (gallery_exists && gallery.type != MediaGalleryPrefInfo::kBlackListed) { |
| + // The prefs are in sync with |known_galleries_|, so it should exist in |
| + // |known_galleries_| as well. User selecting a known gallery effectively |
| + // just sets the gallery to permitted. |
| KnownGalleryPermissions::const_iterator iter = |
| known_galleries_.find(gallery.pref_id); |
| - |
| - if (iter == known_galleries_.end()) { |
| - // This is rare, but could happen if a gallery was not "known" |
| - // when the controller first initialized, but has since been added. |
| - known_galleries_[gallery.pref_id] = GalleryPermission(gallery, true); |
| - iter = known_galleries_.find(gallery.pref_id); |
| - } |
| - |
| + DCHECK(iter != known_galleries_.end()); |
| dialog_->UpdateGallery(&iter->second.pref_info, true); |
| return; |
| } |
| @@ -201,7 +210,7 @@ |
| } |
| } |
| - // Lastly, add it to |new_galleries_|. |
| + // Lastly, add a new gallery to |new_galleries_|. |
| new_galleries_.push_back(GalleryPermission(gallery, true)); |
| dialog_->UpdateGallery(&new_galleries_.back().pref_info, true); |
| } |
| @@ -216,6 +225,12 @@ |
| UpdateGalleriesOnDeviceEvent(info.device_id); |
| } |
| +void MediaGalleriesDialogController::OnGalleryChanged( |
| + MediaGalleriesPreferences* pref) { |
| + DCHECK_EQ(preferences_, pref); |
| + UpdateGalleriesOnPreferencesEvent(); |
| +} |
| + |
| void MediaGalleriesDialogController::InitializePermissions() { |
| const MediaGalleriesPrefInfoMap& galleries = preferences_->known_galleries(); |
| for (MediaGalleriesPrefInfoMap::const_iterator iter = galleries.begin(); |
| @@ -233,6 +248,9 @@ |
| for (MediaGalleryPrefIdSet::iterator iter = permitted.begin(); |
| iter != permitted.end(); ++iter) { |
| + if (ContainsKey(toggled_galleries_, *iter)) |
| + continue; |
| + DCHECK(ContainsKey(known_galleries_, *iter)); |
| known_galleries_[*iter].allowed = true; |
| } |
| } |
| @@ -253,11 +271,66 @@ |
| const MediaGalleryPrefInfo& gallery = iter->pref_info; |
| MediaGalleryPrefId id = preferences_->AddGallery( |
| gallery.device_id, gallery.display_name, gallery.path, true); |
| - preferences_->SetGalleryPermissionForExtension( |
| - *extension_, id, true); |
| + preferences_->SetGalleryPermissionForExtension(*extension_, id, true); |
| } |
| } |
| +void MediaGalleriesDialogController::UpdateGalleriesOnPreferencesEvent() { |
|
vandebo (ex-Chrome)
2013/02/06 00:42:23
I've previously suggested walking both lists concu
|
| + // Merge in the permissions from |preferences_|. Afterwards, |
| + // |known_galleries_| may contain galleries that no longer belong there. |
| + InitializePermissions(); |
| + |
| + // If a gallery still belong in |known_galleries_|, update its view. |
| + // If it no longer belongs in |known_galleries_|, forget it in the model/view. |
| + const MediaGalleriesPrefInfoMap& pref_galleries = |
| + preferences_->known_galleries(); |
| + MediaGalleryPrefIdSet galleries_to_forget; |
| + for (KnownGalleryPermissions::const_iterator it = known_galleries_.begin(); |
| + it != known_galleries_.end(); |
| + ++it) { |
| + const MediaGalleryPrefId& gallery_id = it->first; |
| + const GalleryPermission& gallery = it->second; |
| + MediaGalleriesPrefInfoMap::const_iterator pref_it = |
| + pref_galleries.find(gallery_id); |
| + if (pref_it == pref_galleries.end() || |
| + pref_it->second.type == MediaGalleryPrefInfo::kBlackListed) { |
| + galleries_to_forget.insert(gallery_id); |
| + dialog_->ForgetGallery(&gallery.pref_info); |
| + } else { |
| + dialog_->UpdateGallery(&gallery.pref_info, gallery.allowed); |
| + } |
| + } |
| + |
| + // Remove the galleries to forget from |known_galleries_|. Doing it in the |
| + // above loop would invalidate the iterator there. |
| + for (MediaGalleryPrefIdSet::const_iterator it = galleries_to_forget.begin(); |
| + it != galleries_to_forget.end(); |
| + ++it) { |
| + known_galleries_.erase(*it); |
| + } |
| + |
| + // Resolve |new_galleries_| against the updated |known_galleries_|. |
|
vandebo (ex-Chrome)
2013/02/06 00:42:23
Does this need to go first? We will have already
Lei Zhang
2013/02/07 01:44:56
I think it's fine to do it here. There's no way to
vandebo (ex-Chrome)
2013/02/07 02:08:05
I just don't know how the dialog actually works so
|
| + NewGalleryPermissions::iterator new_it = new_galleries_.begin(); |
| + while (new_it != new_galleries_.end()) { |
| + bool new_gallery_in_known_galleries = false; |
| + for (KnownGalleryPermissions::const_iterator it = known_galleries_.begin(); |
| + it != known_galleries_.end(); ++it) { |
| + const MediaGalleryPrefInfo& gallery = it->second.pref_info; |
| + if (new_it->pref_info.path == gallery.path && |
| + new_it->pref_info.device_id == gallery.device_id) { |
| + new_gallery_in_known_galleries = true; |
| + break; |
| + } |
| + } |
| + if (new_gallery_in_known_galleries) { |
| + dialog_->ForgetGallery(&new_it->pref_info); |
| + new_it = new_galleries_.erase(new_it); |
| + } else { |
| + ++new_it; |
| + } |
| + } |
| +} |
| + |
| void MediaGalleriesDialogController::UpdateGalleriesOnDeviceEvent( |
| const std::string& device_id) { |
| for (KnownGalleryPermissions::iterator iter = known_galleries_.begin(); |