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
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_DIALOG_CONTROLLER_H_
6 #define CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_DIALOG_CONTROLLER_H_
11 #include "base/callback.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string16.h"
14 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
15 #include "components/storage_monitor/removable_storage_observer.h"
16 #include "ui/gfx/native_widget_types.h"
17 #include "ui/shell_dialogs/select_file_dialog.h"
23 namespace extensions
{
31 class MediaGalleriesDialogController
;
32 class MediaGalleryContextMenu
;
35 // Newly added galleries are not added to preferences until the dialog commits,
36 // so they do not have a pref id while the dialog is open; leading to
37 // complicated code in the dialogs. To solve this complication, the controller
38 // maps pref ids into a new space where it can also assign ids to new galleries.
39 // The new number space is only valid for the lifetime of the controller. To
40 // make it more clear where real pref ids are used and where the fake ids are
41 // used, the GalleryDialogId type is used where fake ids are needed.
42 typedef MediaGalleryPrefId GalleryDialogId
;
45 class MediaGalleriesDialog
{
47 virtual ~MediaGalleriesDialog();
49 // Tell the dialog to update its display list of galleries.
50 virtual void UpdateGalleries() = 0;
52 // Constructs a platform-specific dialog owned and controlled by |controller|.
53 static MediaGalleriesDialog
* Create(
54 MediaGalleriesDialogController
* controller
);
57 // The controller is responsible for handling the logic of the dialog and
58 // interfacing with the model (i.e., MediaGalleriesPreferences). It shows
59 // the dialog and owns itself.
60 class MediaGalleriesDialogController
61 : public ui::SelectFileDialog::Listener
,
62 public storage_monitor::RemovableStorageObserver
,
63 public MediaGalleriesPreferences::GalleryChangeObserver
{
65 struct GalleryPermission
{
66 GalleryPermission(GalleryDialogId gallery_id
,
67 const MediaGalleryPrefInfo
& pref_info
,
69 : gallery_id(gallery_id
),
73 GalleryPermission() {}
75 GalleryDialogId gallery_id
;
76 MediaGalleryPrefInfo pref_info
;
80 typedef std::vector
<GalleryPermission
> GalleryPermissionsVector
;
82 // The constructor creates a dialog controller which owns itself.
83 MediaGalleriesDialogController(content::WebContents
* web_contents
,
84 const extensions::Extension
& extension
,
85 const base::Closure
& on_finish
);
87 // The title of the dialog view.
88 base::string16
GetHeader() const;
90 // Explanatory text directly below the title.
91 base::string16
GetSubtext() const;
93 // Header for unattached devices part of the dialog.
94 base::string16
GetUnattachedLocationsHeader() const;
96 // Initial state of whether the dialog's confirmation button will be enabled.
97 bool IsAcceptAllowed() const;
99 // Get the set of permissions to attached galleries.
100 virtual GalleryPermissionsVector
AttachedPermissions() const;
102 // Get the set of permissions to unattached galleries.
103 virtual GalleryPermissionsVector
UnattachedPermissions() const;
105 // Called when the add-folder button in the dialog is clicked.
106 virtual void OnAddFolderClicked();
108 // A checkbox beside a gallery permission was checked. The full set
109 // of gallery permissions checkbox settings is sent on every checkbox toggle.
110 virtual void DidToggleGallery(GalleryDialogId gallery_id
, bool enabled
);
112 // The forget command in the context menu was selected.
113 virtual void DidForgetGallery(GalleryDialogId gallery_id
);
115 // The dialog is being deleted.
116 virtual void DialogFinished(bool accepted
);
118 virtual content::WebContents
* web_contents();
120 ui::MenuModel
* GetContextMenu(GalleryDialogId gallery_id
);
123 friend class MediaGalleriesDialogControllerTest
;
125 typedef base::Callback
<MediaGalleriesDialog
* (
126 MediaGalleriesDialogController
*)> CreateDialogCallback
;
128 // For use with tests.
129 MediaGalleriesDialogController(
130 const extensions::Extension
& extension
,
131 MediaGalleriesPreferences
* preferences
,
132 const CreateDialogCallback
& create_dialog_callback
,
133 const base::Closure
& on_finish
);
135 virtual ~MediaGalleriesDialogController();
138 // This type keeps track of media galleries already known to the prefs system.
139 typedef std::map
<GalleryDialogId
, GalleryPermission
>
140 GalleryPermissionsMap
;
146 GalleryDialogId
GetDialogId(MediaGalleryPrefId pref_id
);
149 GalleryDialogId next_dialog_id_
;
150 std::map
<GalleryDialogId
, MediaGalleryPrefId
> mapping_
;
151 DISALLOW_COPY_AND_ASSIGN(DialogIdMap
);
155 // Bottom half of constructor -- called when |preferences_| is initialized.
156 void OnPreferencesInitialized();
158 // SelectFileDialog::Listener implementation:
159 virtual void FileSelected(const base::FilePath
& path
,
161 void* params
) OVERRIDE
;
163 // RemovableStorageObserver implementation.
164 // Used to keep dialog in sync with removable device status.
165 virtual void OnRemovableStorageAttached(
166 const storage_monitor::StorageInfo
& info
) OVERRIDE
;
167 virtual void OnRemovableStorageDetached(
168 const storage_monitor::StorageInfo
& info
) OVERRIDE
;
170 // MediaGalleriesPreferences::GalleryChangeObserver implementations.
171 // Used to keep the dialog in sync when the preferences change.
172 virtual void OnPermissionAdded(MediaGalleriesPreferences
* pref
,
173 const std::string
& extension_id
,
174 MediaGalleryPrefId pref_id
) OVERRIDE
;
175 virtual void OnPermissionRemoved(MediaGalleriesPreferences
* pref
,
176 const std::string
& extension_id
,
177 MediaGalleryPrefId pref_id
) OVERRIDE
;
178 virtual void OnGalleryAdded(MediaGalleriesPreferences
* pref
,
179 MediaGalleryPrefId pref_id
) OVERRIDE
;
180 virtual void OnGalleryRemoved(MediaGalleriesPreferences
* pref
,
181 MediaGalleryPrefId pref_id
) OVERRIDE
;
182 virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences
* pref
,
183 MediaGalleryPrefId pref_id
) OVERRIDE
;
185 // Populates |known_galleries_| from |preferences_|. Subsequent calls merge
186 // into |known_galleries_| and do not change permissions for user toggled
188 void InitializePermissions();
190 // Saves state of |known_galleries_|, |new_galleries_| and
191 // |forgotten_galleries_| to model.
193 // NOTE: possible states for a gallery:
194 // K N F (K = Known, N = New, F = Forgotten)
202 void SavePermissions();
204 // Updates the model and view when |preferences_| changes. Some of the
205 // possible changes includes a gallery getting blacklisted, or a new
206 // auto detected gallery becoming available.
207 void UpdateGalleriesOnPreferencesEvent();
209 // Updates the model and view when a device is attached or detached.
210 void UpdateGalleriesOnDeviceEvent(const std::string
& device_id
);
212 // Return a sorted vector of either attached or unattached gallery
214 GalleryPermissionsVector
FillPermissions(bool attached
) const;
216 GalleryDialogId
GetDialogId(MediaGalleryPrefId pref_id
);
218 Profile
* GetProfile();
220 // The web contents from which the request originated.
221 content::WebContents
* web_contents_
;
223 // This is just a reference, but it's assumed that it won't become invalid
224 // while the dialog is showing.
225 const extensions::Extension
* extension_
;
227 // Mapping between pref ids and dialog ids.
230 // This map excludes those galleries which have been blacklisted; it only
231 // counts active known galleries.
232 GalleryPermissionsMap known_galleries_
;
234 // Galleries in |known_galleries_| that the user have toggled.
235 std::set
<GalleryDialogId
> toggled_galleries_
;
237 // Map of new galleries the user added, but have not saved. This list should
238 // never overlap with |known_galleries_|.
239 GalleryPermissionsMap new_galleries_
;
241 // Galleries in |known_galleries_| that the user has forgotten.
242 std::set
<GalleryDialogId
> forgotten_galleries_
;
244 // Callback to run when the dialog closes.
245 base::Closure on_finish_
;
247 // The model that tracks galleries and extensions' permissions.
248 // This is the authoritative source for gallery information.
249 MediaGalleriesPreferences
* preferences_
;
251 // The view that's showing.
252 scoped_ptr
<MediaGalleriesDialog
> dialog_
;
254 scoped_refptr
<ui::SelectFileDialog
> select_folder_dialog_
;
256 scoped_ptr
<MediaGalleryContextMenu
> context_menu_
;
258 // Creates the dialog. Only changed for unit tests.
259 CreateDialogCallback create_dialog_callback_
;
261 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesDialogController
);
264 #endif // CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_DIALOG_CONTROLLER_H_