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_GALLERY_WATCH_MANAGER_H_ 6 #define CHROME_BROWSER_MEDIA_GALLERIES_GALLERY_WATCH_MANAGER_H_ 7 8 #include <map> 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/callback_forward.h" 13 #include "base/files/file_path.h" 14 #include "base/files/file_path_watcher.h" 15 #include "base/memory/linked_ptr.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/time/time.h" 19 #include "chrome/browser/media_galleries/media_galleries_preferences.h" 20 #include "components/storage_monitor/removable_storage_observer.h" 21 22 class GalleryWatchManagerObserver; 23 24 namespace content { 25 class BrowserContext; 26 } 27 28 namespace extensions { 29 class Extension; 30 } 31 32 // The GalleryWatchManager is owned by MediaFileSystemRegistry, which is global. 33 // This class manages all watches on media galleries, regardless of profile. 34 // It tracks outstanding watch requests and creates one FilePathWatcher per 35 // watched directory. This class lives and is called on the UI thread. 36 class GalleryWatchManager 37 : public MediaGalleriesPreferences::GalleryChangeObserver, 38 public storage_monitor::RemovableStorageObserver { 39 public: 40 // On success, |error| is empty. 41 typedef base::Callback<void(const std::string& /* error */)> ResultCallback; 42 43 static const char kInvalidGalleryIDError[]; 44 static const char kNoPermissionError[]; 45 static const char kCouldNotWatchGalleryError[]; 46 47 GalleryWatchManager(); 48 virtual ~GalleryWatchManager(); 49 50 // Add or remove observer of change events - this is the only way to 51 // get the result of the file watches. There can only be one observer per 52 // browser context. 53 void AddObserver(content::BrowserContext* browser_context, 54 GalleryWatchManagerObserver* observer); 55 void RemoveObserver(content::BrowserContext* browser_context); 56 57 // Must be called when |browser_context| is shut down. 58 void ShutdownBrowserContext(content::BrowserContext* browser_context); 59 60 // Add a watch for |gallery_id|. 61 void AddWatch(content::BrowserContext* browser_context, 62 const extensions::Extension* extension, 63 MediaGalleryPrefId gallery_id, 64 const ResultCallback& callback); 65 66 // Remove the watch for |gallery_id|. It is valid to call this method on 67 // non-existent watches. 68 void RemoveWatch(content::BrowserContext* browser_context, 69 const std::string& extension_id, 70 MediaGalleryPrefId gallery_id); 71 72 // Remove all the watches for |extension_id|. 73 void RemoveAllWatches(content::BrowserContext* browser_context, 74 const std::string& extension_id); 75 76 // Return the set of galleries being watched for |extension_id|. 77 MediaGalleryPrefIdSet GetWatchSet(content::BrowserContext* browser_context, 78 const std::string& extension_id); 79 80 private: 81 class FileWatchManager; 82 83 // Used to track the gallery watches connected to a specific path. 84 struct WatchOwner { 85 WatchOwner(content::BrowserContext* browser_context, 86 const std::string& extension_id, 87 MediaGalleryPrefId gallery_id); 88 89 content::BrowserContext* browser_context; 90 const std::string extension_id; 91 MediaGalleryPrefId gallery_id; 92 93 // Needed to support storage in STL set, as well as usage as map key. 94 bool operator<(const WatchOwner& other) const; 95 }; 96 97 struct NotificationInfo { 98 NotificationInfo(); 99 ~NotificationInfo(); 100 101 std::set<WatchOwner> owners; 102 base::Time last_notify_time; 103 bool delayed_notification_pending; 104 }; 105 106 typedef std::map<WatchOwner, base::FilePath> WatchesMap; 107 typedef std::map<base::FilePath, NotificationInfo> WatchedPaths; 108 typedef std::map<content::BrowserContext*, GalleryWatchManagerObserver*> 109 ObserverMap; 110 111 // Stop the FilePathWatcher for |path|. Updates |watched_paths_| but not 112 // |registered_watches_|. 113 void DeactivateFileWatch(const WatchOwner& owner, const base::FilePath& path); 114 115 // Called by FilePathWatcher on the UI thread to respond to a request to 116 // watch the path. 117 void OnFileWatchActivated(const WatchOwner& owner, 118 const base::FilePath& path, 119 const ResultCallback& callback, 120 bool success); 121 122 // Called by FilePathWatcher on the UI thread on a change event for |path|. 123 void OnFilePathChanged(const base::FilePath& path, bool error); 124 125 // MediaGalleriesPreferences::GalleryChangeObserver implementation. 126 virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref, 127 const std::string& extension_id, 128 MediaGalleryPrefId pref_id) OVERRIDE; 129 virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref, 130 MediaGalleryPrefId pref_id) OVERRIDE; 131 132 // storage_monitor::RemovableStorageObserver implementation. 133 virtual void OnRemovableStorageDetached( 134 const storage_monitor::StorageInfo& info) OVERRIDE; 135 136 // True if the we are already observing the storage monitor. 137 bool storage_monitor_observed_; 138 139 // MediaGalleriesPreferences we are currently observing. 140 std::set<MediaGalleriesPreferences*> observed_preferences_; 141 142 // All registered watches, keyed by WatchOwner. 143 WatchesMap watches_; 144 145 // Reverse mapping of watched paths to the set of owning WatchOwners. 146 WatchedPaths watched_paths_; 147 148 // Things that want to hear about gallery changes. 149 ObserverMap observers_; 150 151 // Helper that does the watches on the FILE thread. 152 scoped_ptr<FileWatchManager> watch_manager_; 153 154 base::WeakPtrFactory<GalleryWatchManager> weak_factory_; 155 156 DISALLOW_COPY_AND_ASSIGN(GalleryWatchManager); 157 }; 158 159 #endif // CHROME_BROWSER_MEDIA_GALLERIES_GALLERY_WATCH_MANAGER_H_ 160