Home | History | Annotate | Download | only in media_galleries
      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