Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: components/enhanced_bookmarks/bookmark_image_service.cc

Issue 875463003: ★ Record the image dominant color in the image database. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix GN Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/enhanced_bookmarks/bookmark_image_service.h" 5 #include "components/enhanced_bookmarks/bookmark_image_service.h"
6 6
7 #include "base/single_thread_task_runner.h" 7 #include "base/single_thread_task_runner.h"
8 #include "base/task_runner_util.h"
8 #include "base/thread_task_runner_handle.h" 9 #include "base/thread_task_runner_handle.h"
9 #include "base/threading/sequenced_worker_pool.h" 10 #include "base/threading/sequenced_worker_pool.h"
10 #include "components/bookmarks/browser/bookmark_model.h" 11 #include "components/bookmarks/browser/bookmark_model.h"
11 #include "components/bookmarks/browser/bookmark_model_observer.h" 12 #include "components/bookmarks/browser/bookmark_model_observer.h"
12 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h" 13 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
13 #include "components/enhanced_bookmarks/enhanced_bookmark_utils.h" 14 #include "components/enhanced_bookmarks/enhanced_bookmark_utils.h"
15 #include "components/enhanced_bookmarks/image_store_util.h"
14 #include "components/enhanced_bookmarks/persistent_image_store.h" 16 #include "components/enhanced_bookmarks/persistent_image_store.h"
15 17
16 using bookmarks::BookmarkModel; 18 using bookmarks::BookmarkModel;
17 19
18 namespace { 20 namespace {
19 21
20 const char kSequenceToken[] = "BookmarkImagesSequenceToken"; 22 const char kSequenceToken[] = "BookmarkImagesSequenceToken";
21 23
22 void ConstructPersistentImageStore(PersistentImageStore* store, 24 void ConstructPersistentImageStore(PersistentImageStore* store,
23 const base::FilePath& path) { 25 const base::FilePath& path) {
24 DCHECK(store); 26 DCHECK(store);
25 new (store) PersistentImageStore(path); 27 new (store) PersistentImageStore(path);
26 } 28 }
27 29
28 void DeleteImageStore(ImageStore* store) { 30 void DeleteImageStore(ImageStore* store) {
29 DCHECK(store); 31 DCHECK(store);
30 delete store; 32 delete store;
31 } 33 }
32 34
33 void RetrieveImageFromStoreRelay( 35 void RetrieveImageFromStoreRelay(
34 ImageStore* store, 36 ImageStore* store,
35 const GURL& page_url, 37 const GURL& page_url,
36 enhanced_bookmarks::BookmarkImageService::Callback callback, 38 enhanced_bookmarks::BookmarkImageService::ImageCallback callback,
37 scoped_refptr<base::SingleThreadTaskRunner> origin_loop) { 39 scoped_refptr<base::SingleThreadTaskRunner> origin_loop) {
38 std::pair<gfx::Image, GURL> image_data = store->Get(page_url); 40 origin_loop->PostTask(FROM_HERE, base::Bind(callback, store->Get(page_url)));
39 origin_loop->PostTask(
40 FROM_HERE, base::Bind(callback, image_data.first, image_data.second));
41 } 41 }
42 42
43 } // namespace 43 } // namespace
44 44
45 namespace enhanced_bookmarks { 45 namespace enhanced_bookmarks {
46 BookmarkImageService::BookmarkImageService( 46 BookmarkImageService::BookmarkImageService(
47 scoped_ptr<ImageStore> store, 47 scoped_ptr<ImageStore> store,
48 EnhancedBookmarkModel* enhanced_bookmark_model, 48 EnhancedBookmarkModel* enhanced_bookmark_model,
49 scoped_refptr<base::SequencedWorkerPool> pool) 49 scoped_refptr<base::SequencedWorkerPool> pool)
50 : enhanced_bookmark_model_(enhanced_bookmark_model), 50 : enhanced_bookmark_model_(enhanced_bookmark_model),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 base::Bind(&DeleteImageStore, store_.release())); 92 base::Bind(&DeleteImageStore, store_.release()));
93 } 93 }
94 94
95 void BookmarkImageService::Shutdown() { 95 void BookmarkImageService::Shutdown() {
96 DCHECK(CalledOnValidThread()); 96 DCHECK(CalledOnValidThread());
97 enhanced_bookmark_model_->bookmark_model()->RemoveObserver(this); 97 enhanced_bookmark_model_->bookmark_model()->RemoveObserver(this);
98 enhanced_bookmark_model_ = NULL; 98 enhanced_bookmark_model_ = NULL;
99 } 99 }
100 100
101 void BookmarkImageService::SalientImageForUrl(const GURL& page_url, 101 void BookmarkImageService::SalientImageForUrl(const GURL& page_url,
102 Callback callback) { 102 ImageCallback callback) {
103 DCHECK(CalledOnValidThread()); 103 DCHECK(CalledOnValidThread());
104 SalientImageForUrl(page_url, true, callback); 104 SalientImageForUrl(page_url, true, callback);
105 } 105 }
106 106
107 void BookmarkImageService::RetrieveImageFromStore( 107 void BookmarkImageService::RetrieveImageFromStore(const GURL& page_url,
108 const GURL& page_url, 108 ImageCallback callback) {
109 BookmarkImageService::Callback callback) {
110 DCHECK(CalledOnValidThread()); 109 DCHECK(CalledOnValidThread());
111 pool_->PostSequencedWorkerTaskWithShutdownBehavior( 110 pool_->PostSequencedWorkerTaskWithShutdownBehavior(
112 pool_->GetNamedSequenceToken(kSequenceToken), 111 pool_->GetNamedSequenceToken(kSequenceToken),
113 FROM_HERE, 112 FROM_HERE,
114 base::Bind(&RetrieveImageFromStoreRelay, 113 base::Bind(&RetrieveImageFromStoreRelay,
115 base::Unretained(store_.get()), 114 base::Unretained(store_.get()),
116 page_url, 115 page_url,
117 callback, 116 callback,
118 base::ThreadTaskRunnerHandle::Get()), 117 base::ThreadTaskRunnerHandle::Get()),
119 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 118 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
(...skipping 20 matching lines...) Expand all
140 139
141 RetrieveSalientImage( 140 RetrieveSalientImage(
142 page_url, 141 page_url,
143 image_url, 142 image_url,
144 "", 143 "",
145 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, 144 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
146 false); 145 false);
147 } 146 }
148 147
149 void BookmarkImageService::FetchCallback(const GURL& page_url, 148 void BookmarkImageService::FetchCallback(const GURL& page_url,
150 Callback original_callback, 149 ImageCallback original_callback,
151 const gfx::Image& image, 150 const ImageRecord& record) {
152 const GURL& image_url) {
153 DCHECK(CalledOnValidThread()); 151 DCHECK(CalledOnValidThread());
154 if (!image.IsEmpty() || !image_url.is_empty()) { 152 if (!record.image.IsEmpty() || !record.url.is_empty()) {
155 // Either the image was in the store or there is no image in the store, but 153 // Either the record was in the store or there is no image in the store, but
156 // an URL for an image is present, indicating that a previous attempt to 154 // an URL for a record is present, indicating that a previous attempt to
157 // download the image failed. Just return the image. 155 // download the image failed. Just return the record.
158 original_callback.Run(image, image_url); 156 original_callback.Run(record);
159 } else { 157 } else {
160 // There is no image in the store, and no previous attempts to retrieve 158 // There is no record in the store, and no previous attempts to retrieve
161 // one. Start a request to retrieve a salient image if there is an image 159 // one. Start a request to retrieve a salient image if there is an image
162 // url set on a bookmark, and then enqueue the request for the image to 160 // url set on a bookmark, and then enqueue the request for the record to
163 // be triggered when the retrieval is finished. 161 // be triggered when the retrieval is finished.
164 RetrieveSalientImageForPageUrl(page_url); 162 RetrieveSalientImageForPageUrl(page_url);
165 SalientImageForUrl(page_url, false, original_callback); 163 SalientImageForUrl(page_url, false, original_callback);
166 } 164 }
167 } 165 }
168 166
169 void BookmarkImageService::SalientImageForUrl(const GURL& page_url, 167 void BookmarkImageService::SalientImageForUrl(const GURL& page_url,
170 bool fetch_from_bookmark, 168 bool fetch_from_bookmark,
171 Callback callback) { 169 ImageCallback callback) {
172 DCHECK(CalledOnValidThread()); 170 DCHECK(CalledOnValidThread());
173 171
174 // If the request is done while the image is currently being retrieved, just 172 // If the request is done while the image is currently being retrieved, just
175 // store the appropriate callbacks to call once the image is retrieved. 173 // store the appropriate callbacks to call once the image is retrieved.
176 if (IsPageUrlInProgress(page_url)) { 174 if (IsPageUrlInProgress(page_url)) {
177 callbacks_[page_url].push_back(callback); 175 callbacks_[page_url].push_back(callback);
178 return; 176 return;
179 } 177 }
180 178
181 if (!fetch_from_bookmark) { 179 if (!fetch_from_bookmark) {
182 RetrieveImageFromStore(page_url, callback); 180 RetrieveImageFromStore(page_url, callback);
183 } else { 181 } else {
184 RetrieveImageFromStore(page_url, 182 RetrieveImageFromStore(page_url,
185 base::Bind(&BookmarkImageService::FetchCallback, 183 base::Bind(&BookmarkImageService::FetchCallback,
186 base::Unretained(this), 184 base::Unretained(this),
187 page_url, 185 page_url,
188 callback)); 186 callback));
189 } 187 }
190 } 188 }
191 189
192 void BookmarkImageService::ProcessNewImage(const GURL& page_url, 190 void BookmarkImageService::ProcessNewImage(const GURL& page_url,
193 bool update_bookmarks, 191 bool update_bookmarks,
194 const gfx::Image& image, 192 const gfx::Image& image,
195 const GURL& image_url) { 193 const GURL& image_url) {
196 DCHECK(CalledOnValidThread()); 194 DCHECK(CalledOnValidThread());
197 StoreImage(image, image_url, page_url); 195 PostTaskToStoreImage(image, image_url, page_url);
198 in_progress_page_urls_.erase(page_url);
199 ProcessRequests(page_url, image, image_url);
200 if (update_bookmarks && image_url.is_valid()) { 196 if (update_bookmarks && image_url.is_valid()) {
201 const BookmarkNode* bookmark = 197 const BookmarkNode* bookmark =
202 enhanced_bookmark_model_->bookmark_model() 198 enhanced_bookmark_model_->bookmark_model()
203 ->GetMostRecentlyAddedUserNodeForURL(page_url); 199 ->GetMostRecentlyAddedUserNodeForURL(page_url);
204 if (bookmark) { 200 if (bookmark) {
205 const gfx::Size& size = image.Size(); 201 const gfx::Size& size = image.Size();
206 bool result = enhanced_bookmark_model_->SetOriginalImage( 202 bool result = enhanced_bookmark_model_->SetOriginalImage(
207 bookmark, image_url, size.width(), size.height()); 203 bookmark, image_url, size.width(), size.height());
208 DCHECK(result); 204 DCHECK(result);
209 } 205 }
210 } 206 }
211 } 207 }
212 208
213 bool BookmarkImageService::IsPageUrlInProgress(const GURL& page_url) { 209 bool BookmarkImageService::IsPageUrlInProgress(const GURL& page_url) {
214 DCHECK(CalledOnValidThread()); 210 DCHECK(CalledOnValidThread());
215 return in_progress_page_urls_.find(page_url) != in_progress_page_urls_.end(); 211 return in_progress_page_urls_.find(page_url) != in_progress_page_urls_.end();
216 } 212 }
217 213
218 void BookmarkImageService::StoreImage(const gfx::Image& image, 214 ImageRecord BookmarkImageService::StoreImage(const gfx::Image& image,
219 const GURL& image_url, 215 const GURL& image_url,
220 const GURL& page_url) { 216 const GURL& page_url) {
217 ImageRecord image_info(image, image_url, SK_ColorBLACK);
218 if (!image.IsEmpty()) {
219 image_info.dominant_color = DominantColorForImage(image);
220 // TODO(lpromero): this should be saved all the time, even when there is an
221 // empty image. http://crbug.com/451450
222 pool_->PostNamedSequencedWorkerTask(
223 kSequenceToken, FROM_HERE,
224 base::Bind(&ImageStore::Insert, base::Unretained(store_.get()),
225 page_url, image_info));
226 }
227 return image_info;
228 }
229
230 void BookmarkImageService::PostTaskToStoreImage(const gfx::Image& image,
231 const GURL& image_url,
232 const GURL& page_url) {
221 DCHECK(CalledOnValidThread()); 233 DCHECK(CalledOnValidThread());
222 if (!image.IsEmpty()) { 234
223 pool_->PostNamedSequencedWorkerTask( 235 base::Callback<ImageRecord(void)> task =
224 kSequenceToken, 236 base::Bind(&BookmarkImageService::StoreImage, base::Unretained(this),
225 FROM_HERE, 237 image, image_url, page_url);
226 base::Bind(&ImageStore::Insert, 238 base::Callback<void(const ImageRecord&)> reply =
227 base::Unretained(store_.get()), 239 base::Bind(&BookmarkImageService::OnStoreImagePosted,
228 page_url, 240 base::Unretained(this), page_url);
229 image_url, 241
230 image)); 242 base::PostTaskAndReplyWithResult(pool_.get(), FROM_HERE, task, reply);
231 } 243 }
244
245 void BookmarkImageService::OnStoreImagePosted(const GURL& page_url,
246 const ImageRecord& image) {
247 DCHECK(CalledOnValidThread());
248 in_progress_page_urls_.erase(page_url);
249 ProcessRequests(page_url, image);
232 } 250 }
233 251
234 void BookmarkImageService::RemoveImageForUrl(const GURL& page_url) { 252 void BookmarkImageService::RemoveImageForUrl(const GURL& page_url) {
235 DCHECK(CalledOnValidThread()); 253 DCHECK(CalledOnValidThread());
236 pool_->PostNamedSequencedWorkerTask( 254 pool_->PostNamedSequencedWorkerTask(
237 kSequenceToken, 255 kSequenceToken,
238 FROM_HERE, 256 FROM_HERE,
239 base::Bind(&ImageStore::Erase, base::Unretained(store_.get()), page_url)); 257 base::Bind(&ImageStore::Erase, base::Unretained(store_.get()), page_url));
240 in_progress_page_urls_.erase(page_url); 258 in_progress_page_urls_.erase(page_url);
241 ProcessRequests(page_url, gfx::Image(), GURL()); 259 ProcessRequests(page_url, ImageRecord());
242 } 260 }
243 261
244 void BookmarkImageService::ChangeImageURL(const GURL& from, const GURL& to) { 262 void BookmarkImageService::ChangeImageURL(const GURL& from, const GURL& to) {
245 DCHECK(CalledOnValidThread()); 263 DCHECK(CalledOnValidThread());
246 pool_->PostNamedSequencedWorkerTask(kSequenceToken, 264 pool_->PostNamedSequencedWorkerTask(kSequenceToken,
247 FROM_HERE, 265 FROM_HERE,
248 base::Bind(&ImageStore::ChangeImageURL, 266 base::Bind(&ImageStore::ChangeImageURL,
249 base::Unretained(store_.get()), 267 base::Unretained(store_.get()),
250 from, 268 from,
251 to)); 269 to));
252 in_progress_page_urls_.erase(from); 270 in_progress_page_urls_.erase(from);
253 ProcessRequests(from, gfx::Image(), GURL()); 271 ProcessRequests(from, ImageRecord());
254 } 272 }
255 273
256 void BookmarkImageService::ClearAll() { 274 void BookmarkImageService::ClearAll() {
257 DCHECK(CalledOnValidThread()); 275 DCHECK(CalledOnValidThread());
258 // Clears and executes callbacks. 276 // Clears and executes callbacks.
259 pool_->PostNamedSequencedWorkerTask( 277 pool_->PostNamedSequencedWorkerTask(
260 kSequenceToken, 278 kSequenceToken,
261 FROM_HERE, 279 FROM_HERE,
262 base::Bind(&ImageStore::ClearAll, base::Unretained(store_.get()))); 280 base::Bind(&ImageStore::ClearAll, base::Unretained(store_.get())));
263 281
264 for (std::map<const GURL, std::vector<Callback> >::const_iterator it = 282 for (std::map<const GURL, std::vector<ImageCallback>>::const_iterator it =
265 callbacks_.begin(); 283 callbacks_.begin();
266 it != callbacks_.end(); 284 it != callbacks_.end(); ++it) {
267 ++it) { 285 ProcessRequests(it->first, ImageRecord());
268 ProcessRequests(it->first, gfx::Image(), GURL());
269 } 286 }
270 287
271 in_progress_page_urls_.erase(in_progress_page_urls_.begin(), 288 in_progress_page_urls_.erase(in_progress_page_urls_.begin(),
272 in_progress_page_urls_.end()); 289 in_progress_page_urls_.end());
273 } 290 }
274 291
275 void BookmarkImageService::ProcessRequests(const GURL& page_url, 292 void BookmarkImageService::ProcessRequests(const GURL& page_url,
276 const gfx::Image& image, 293 const ImageRecord& record) {
277 const GURL& image_url) {
278 DCHECK(CalledOnValidThread()); 294 DCHECK(CalledOnValidThread());
279 295
280 std::vector<Callback> callbacks = callbacks_[page_url]; 296 std::vector<ImageCallback> callbacks = callbacks_[page_url];
281 for (std::vector<Callback>::const_iterator it = callbacks.begin(); 297 for (std::vector<ImageCallback>::const_iterator it = callbacks.begin();
282 it != callbacks.end(); 298 it != callbacks.end(); ++it) {
283 ++it) { 299 it->Run(record);
284 it->Run(image, image_url);
285 } 300 }
286 301
287 callbacks_.erase(page_url); 302 callbacks_.erase(page_url);
288 } 303 }
289 304
290 // BookmarkModelObserver methods. 305 // BookmarkModelObserver methods.
291 306
292 void BookmarkImageService::BookmarkNodeRemoved( 307 void BookmarkImageService::BookmarkNodeRemoved(
293 BookmarkModel* model, 308 BookmarkModel* model,
294 const BookmarkNode* parent, 309 const BookmarkNode* parent,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 const BookmarkNode* node) { 358 const BookmarkNode* node) {
344 } 359 }
345 360
346 void BookmarkImageService::BookmarkAllUserNodesRemoved( 361 void BookmarkImageService::BookmarkAllUserNodesRemoved(
347 BookmarkModel* model, 362 BookmarkModel* model,
348 const std::set<GURL>& removed_urls) { 363 const std::set<GURL>& removed_urls) {
349 ClearAll(); 364 ClearAll();
350 } 365 }
351 366
352 } // namespace enhanced_bookmarks 367 } // namespace enhanced_bookmarks
OLDNEW
« no previous file with comments | « components/enhanced_bookmarks/bookmark_image_service.h ('k') | components/enhanced_bookmarks/image_record.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698