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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PERMISSION_CONTROLLER_H_ 6 #define CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PERMISSION_CONTROLLER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/strings/string16.h" 15 #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h" 16 #include "chrome/browser/media_galleries/media_galleries_preferences.h" 17 #include "components/storage_monitor/removable_storage_observer.h" 18 #include "ui/gfx/native_widget_types.h" 19 #include "ui/shell_dialogs/select_file_dialog.h" 20 21 namespace content { 22 class WebContents; 23 } 24 25 namespace extensions { 26 class Extension; 27 } 28 29 namespace ui { 30 class MenuModel; 31 } 32 33 class MediaGalleriesDialogController; 34 class MediaGalleryContextMenu; 35 class Profile; 36 37 // Newly added galleries are not added to preferences until the dialog commits, 38 // so they do not have a pref id while the dialog is open; leading to 39 // complicated code in the dialogs. To solve this complication, the controller 40 // maps pref ids into a new space where it can also assign ids to new galleries. 41 // The new number space is only valid for the lifetime of the controller. To 42 // make it more clear where real pref ids are used and where the fake ids are 43 // used, the GalleryDialogId type is used where fake ids are needed. 44 typedef MediaGalleryPrefId GalleryDialogId; 45 46 class MediaGalleriesPermissionController 47 : public MediaGalleriesDialogController, 48 public ui::SelectFileDialog::Listener, 49 public storage_monitor::RemovableStorageObserver, 50 public MediaGalleriesPreferences::GalleryChangeObserver { 51 public: 52 // The constructor creates a dialog controller which owns itself. 53 MediaGalleriesPermissionController(content::WebContents* web_contents, 54 const extensions::Extension& extension, 55 const base::Closure& on_finish); 56 57 // MediaGalleriesDialogController implementation. 58 virtual base::string16 GetHeader() const OVERRIDE; 59 virtual base::string16 GetSubtext() const OVERRIDE; 60 virtual bool IsAcceptAllowed() const OVERRIDE; 61 virtual bool ShouldShowFolderViewer(const Entry& entry) const OVERRIDE; 62 virtual std::vector<base::string16> GetSectionHeaders() const OVERRIDE; 63 virtual Entries GetSectionEntries(size_t index) const OVERRIDE; 64 // Auxiliary button for this dialog is the 'Add Folder' button. 65 virtual base::string16 GetAuxiliaryButtonText() const OVERRIDE; 66 virtual void DidClickAuxiliaryButton() OVERRIDE; 67 virtual void DidToggleEntry(GalleryDialogId gallery_id, 68 bool selected) OVERRIDE; 69 virtual void DidClickOpenFolderViewer(GalleryDialogId gallery_id) OVERRIDE; 70 virtual void DidForgetEntry(GalleryDialogId gallery_id) OVERRIDE; 71 virtual base::string16 GetAcceptButtonText() const OVERRIDE; 72 virtual void DialogFinished(bool accepted) OVERRIDE; 73 virtual ui::MenuModel* GetContextMenu(GalleryDialogId gallery_id) OVERRIDE; 74 virtual content::WebContents* WebContents() OVERRIDE; 75 76 protected: 77 friend class MediaGalleriesPermissionControllerTest; 78 79 typedef base::Callback<MediaGalleriesDialog* ( 80 MediaGalleriesDialogController*)> CreateDialogCallback; 81 82 // For use with tests. 83 MediaGalleriesPermissionController( 84 const extensions::Extension& extension, 85 MediaGalleriesPreferences* preferences, 86 const CreateDialogCallback& create_dialog_callback, 87 const base::Closure& on_finish); 88 89 virtual ~MediaGalleriesPermissionController(); 90 91 private: 92 // This type keeps track of media galleries already known to the prefs system. 93 typedef std::map<GalleryDialogId, Entry> GalleryPermissionsMap; 94 typedef std::map<GalleryDialogId, bool /*permitted*/> ToggledGalleryMap; 95 96 class DialogIdMap { 97 public: 98 DialogIdMap(); 99 ~DialogIdMap(); 100 GalleryDialogId GetDialogId(MediaGalleryPrefId pref_id); 101 MediaGalleryPrefId GetPrefId(GalleryDialogId id) const; 102 103 private: 104 GalleryDialogId next_dialog_id_; 105 std::map<MediaGalleryPrefId, GalleryDialogId> back_map_; 106 std::vector<MediaGalleryPrefId> forward_mapping_; 107 DISALLOW_COPY_AND_ASSIGN(DialogIdMap); 108 }; 109 110 111 // Bottom half of constructor -- called when |preferences_| is initialized. 112 void OnPreferencesInitialized(); 113 114 // SelectFileDialog::Listener implementation: 115 virtual void FileSelected(const base::FilePath& path, 116 int index, 117 void* params) OVERRIDE; 118 119 // RemovableStorageObserver implementation. 120 // Used to keep dialog in sync with removable device status. 121 virtual void OnRemovableStorageAttached( 122 const storage_monitor::StorageInfo& info) OVERRIDE; 123 virtual void OnRemovableStorageDetached( 124 const storage_monitor::StorageInfo& info) OVERRIDE; 125 126 // MediaGalleriesPreferences::GalleryChangeObserver implementations. 127 // Used to keep the dialog in sync when the preferences change. 128 virtual void OnPermissionAdded(MediaGalleriesPreferences* pref, 129 const std::string& extension_id, 130 MediaGalleryPrefId pref_id) OVERRIDE; 131 virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref, 132 const std::string& extension_id, 133 MediaGalleryPrefId pref_id) OVERRIDE; 134 virtual void OnGalleryAdded(MediaGalleriesPreferences* pref, 135 MediaGalleryPrefId pref_id) OVERRIDE; 136 virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref, 137 MediaGalleryPrefId pref_id) OVERRIDE; 138 virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref, 139 MediaGalleryPrefId pref_id) OVERRIDE; 140 141 // Populates |known_galleries_| from |preferences_|. Subsequent calls merge 142 // into |known_galleries_| and do not change permissions for user toggled 143 // galleries. 144 void InitializePermissions(); 145 146 // Saves state of |known_galleries_|, |new_galleries_| and 147 // |forgotten_galleries_| to model. 148 // 149 // NOTE: possible states for a gallery: 150 // K N F (K = Known, N = New, F = Forgotten) 151 // +---+---+---+ 152 // | Y | N | N | 153 // +---+---+---+ 154 // | N | Y | N | 155 // +---+---+---+ 156 // | Y | N | Y | 157 // +---+---+---+ 158 void SavePermissions(); 159 160 // Updates the model and view when |preferences_| changes. Some of the 161 // possible changes includes a gallery getting blacklisted, or a new 162 // auto detected gallery becoming available. 163 void UpdateGalleriesOnPreferencesEvent(); 164 165 // Updates the model and view when a device is attached or detached. 166 void UpdateGalleriesOnDeviceEvent(const std::string& device_id); 167 168 GalleryDialogId GetDialogId(MediaGalleryPrefId pref_id); 169 MediaGalleryPrefId GetPrefId(GalleryDialogId id) const; 170 171 Profile* GetProfile(); 172 173 // The web contents from which the request originated. 174 content::WebContents* web_contents_; 175 176 // This is just a reference, but it's assumed that it won't become invalid 177 // while the dialog is showing. 178 const extensions::Extension* extension_; 179 180 // Mapping between pref ids and dialog ids. 181 DialogIdMap id_map_; 182 183 // This map excludes those galleries which have been blacklisted; it only 184 // counts active known galleries. 185 GalleryPermissionsMap known_galleries_; 186 187 // Galleries in |known_galleries_| that the user have toggled. 188 ToggledGalleryMap toggled_galleries_; 189 190 // The current set of permitted galleries (according to prefs). 191 MediaGalleryPrefIdSet pref_permitted_galleries_; 192 193 // Map of new galleries the user added, but have not saved. This list should 194 // never overlap with |known_galleries_|. 195 GalleryPermissionsMap new_galleries_; 196 197 // Galleries in |known_galleries_| that the user has forgotten. 198 std::set<GalleryDialogId> forgotten_galleries_; 199 200 // Callback to run when the dialog closes. 201 base::Closure on_finish_; 202 203 // The model that tracks galleries and extensions' permissions. 204 // This is the authoritative source for gallery information. 205 MediaGalleriesPreferences* preferences_; 206 207 // The view that's showing. 208 scoped_ptr<MediaGalleriesDialog> dialog_; 209 210 scoped_refptr<ui::SelectFileDialog> select_folder_dialog_; 211 212 scoped_ptr<MediaGalleryContextMenu> context_menu_; 213 214 // Creates the dialog. Only changed for unit tests. 215 CreateDialogCallback create_dialog_callback_; 216 217 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPermissionController); 218 }; 219 220 #endif // CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PERMISSION_CONTROLLER_H_ 221