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 #ifndef COMPONENTS_ENHANCED_BOOKMARKS_BOOKMARK_IMAGE_SERVICE_H_ 5 #define COMPONENTS_ENHANCED_BOOKMARKS_BOOKMARK_IMAGE_SERVICE_H_ 6 7 #include "base/files/file_path.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/singleton.h" 10 #include "components/bookmarks/browser/bookmark_model_observer.h" 11 #include "components/enhanced_bookmarks/image_store.h" 12 #include "components/keyed_service/core/keyed_service.h" 13 #include "net/url_request/url_request.h" 14 #include "url/gurl.h" 15 16 namespace base { 17 class SingleThreadTaskRunner; 18 } 19 class BookmarkNode; 20 21 namespace enhanced_bookmarks { 22 23 class EnhancedBookmarkModel; 24 25 // The BookmarkImageService stores salient images for bookmarks. 26 class BookmarkImageService : public KeyedService, 27 public BookmarkModelObserver, 28 public base::NonThreadSafe { 29 public: 30 BookmarkImageService(const base::FilePath& path, 31 EnhancedBookmarkModel* enhanced_bookmark_model, 32 scoped_refptr<base::SequencedWorkerPool> pool); 33 BookmarkImageService(scoped_ptr<ImageStore> store, 34 EnhancedBookmarkModel* enhanced_bookmark_model, 35 scoped_refptr<base::SequencedWorkerPool> pool); 36 37 virtual ~BookmarkImageService(); 38 39 typedef base::Callback<void(const gfx::Image&, const GURL& url)> Callback; 40 41 // KeyedService: 42 virtual void Shutdown() OVERRIDE; 43 44 // Returns a salient image for a URL. This may trigger a network request for 45 // the image if the image was not retrieved before and if a bookmark node has 46 // a URL for this salient image available. The image (which may be empty) is 47 // sent via the callback. The callback may be called synchronously if it is 48 // possible. The callback is always triggered on the main thread. 49 void SalientImageForUrl(const GURL& page_url, Callback callback); 50 51 // BookmarkModelObserver methods. 52 virtual void BookmarkNodeRemoved(BookmarkModel* model, 53 const BookmarkNode* parent, 54 int old_index, 55 const BookmarkNode* node, 56 const std::set<GURL>& removed_urls) OVERRIDE; 57 virtual void BookmarkModelLoaded(BookmarkModel* model, 58 bool ids_reassigned) OVERRIDE; 59 virtual void BookmarkNodeMoved(BookmarkModel* model, 60 const BookmarkNode* old_parent, 61 int old_index, 62 const BookmarkNode* new_parent, 63 int new_index) OVERRIDE; 64 virtual void BookmarkNodeAdded(BookmarkModel* model, 65 const BookmarkNode* parent, 66 int index) OVERRIDE; 67 virtual void OnWillChangeBookmarkNode(BookmarkModel* model, 68 const BookmarkNode* node) OVERRIDE; 69 virtual void BookmarkNodeChanged(BookmarkModel* model, 70 const BookmarkNode* node) OVERRIDE; 71 virtual void BookmarkNodeFaviconChanged(BookmarkModel* model, 72 const BookmarkNode* node) OVERRIDE; 73 virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, 74 const BookmarkNode* node) OVERRIDE; 75 virtual void BookmarkAllUserNodesRemoved( 76 BookmarkModel* model, 77 const std::set<GURL>& removed_urls) OVERRIDE; 78 79 protected: 80 // Returns true if the image for the page_url is currently being fetched. 81 bool IsPageUrlInProgress(const GURL& page_url); 82 83 // Once an image has been retrieved, store the image and notify all the 84 // consumers that were waiting on it. 85 void ProcessNewImage(const GURL& page_url, 86 bool update_bookmarks, 87 const gfx::Image& image, 88 const GURL& image_url); 89 90 // Sets a new image for a bookmark. If the given page_url is bookmarked and 91 // the image is retrieved from the image_url, then the image is locally 92 // stored. If update_bookmark is true the URL is also added to the bookmark. 93 // This is the only method subclass needs to implement. 94 virtual void RetrieveSalientImage( 95 const GURL& page_url, 96 const GURL& image_url, 97 const std::string& referrer, 98 net::URLRequest::ReferrerPolicy referrer_policy, 99 bool update_bookmark) = 0; 100 101 // Retrieves a salient image for a given page_url by downloading the image in 102 // one of the bookmark. 103 virtual void RetrieveSalientImageForPageUrl(const GURL& page_url); 104 105 // PageUrls currently in the progress of being retrieved. 106 std::set<GURL> in_progress_page_urls_; 107 108 // Cached pointer to the bookmark model. 109 EnhancedBookmarkModel* enhanced_bookmark_model_; 110 111 private: 112 // Same as SalientImageForUrl(const GURL&, Callback) but can prevent the 113 // network request if fetch_from_bookmark is false. 114 void SalientImageForUrl(const GURL& page_url, 115 bool fetch_from_bookmark, 116 Callback stack_callback); 117 118 // Processes the requests that have been waiting on an image. 119 void ProcessRequests(const GURL& page_url, 120 const gfx::Image& image, 121 const GURL& image_url); 122 123 // Once an image is retrieved this method updates the store with it. 124 void StoreImage(const gfx::Image& image, 125 const GURL& image_url, 126 const GURL& page_url); 127 128 // Called when retrieving an image from the image store fails, to trigger 129 // retrieving the image from the url stored in the bookmark (if any). 130 void FetchCallback(const GURL& page_url, 131 Callback original_callback, 132 const gfx::Image& image, 133 const GURL& image_url); 134 135 // Remove the image stored for this bookmark (if it exists). Called when a 136 // bookmark is deleted. 137 void RemoveImageForUrl(const GURL& url); 138 139 // Moves an image from one url to another. 140 void ChangeImageURL(const GURL& from, const GURL& to); 141 142 // Removes all the entries in the image service. 143 void ClearAll(); 144 145 // The image store can only be accessed from the blocking pool. 146 // RetrieveImageFromStore starts a request to retrieve the image and returns 147 // the result via a callback. RetrieveImageFromStore must be called on the 148 // main thread and the callback will be called on the main thread as well. The 149 // callback will always be called. The returned image is nil if the image is 150 // not present in the store. 151 void RetrieveImageFromStore(const GURL& page_url, 152 BookmarkImageService::Callback callback); 153 154 // Maps a pageUrl to an image. 155 scoped_ptr<ImageStore> store_; 156 157 // All the callbacks waiting for a particular image. 158 std::map<const GURL, std::vector<Callback> > callbacks_; 159 160 // When a bookmark is changed, two messages are received on the 161 // bookmarkModelObserver, one with the old state, one with the new. The url 162 // before the change is saved in this instance variable. 163 GURL previous_url_; 164 165 // The worker pool to enqueue the store requests onto. 166 scoped_refptr<base::SequencedWorkerPool> pool_; 167 DISALLOW_COPY_AND_ASSIGN(BookmarkImageService); 168 }; 169 170 } // namespace enhanced_bookmarks 171 172 #endif // COMPONENTS_ENHANCED_BOOKMARKS_BOOKMARK_IMAGE_SERVICE_H_ 173