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

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

Issue 513793002: Bring up of ImageService. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
« no previous file with comments | « components/enhanced_bookmarks/bookmark_image_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "components/enhanced_bookmarks/bookmark_image_service.h"
5
6 #include "base/single_thread_task_runner.h"
7 #include "base/thread_task_runner_handle.h"
8 #include "base/threading/sequenced_worker_pool.h"
9 #include "components/bookmarks/browser/bookmark_model.h"
10 #include "components/bookmarks/browser/bookmark_model_observer.h"
11 #include "components/enhanced_bookmarks/enhanced_bookmark_utils.h"
12 #include "components/enhanced_bookmarks/metadata_accessor.h"
13 #include "components/enhanced_bookmarks/persistent_image_store.h"
14
15 namespace {
16
17 const char kSequenceToken[] = "BookmarkImagesSequenceToken";
18
19 void ConstructPersistentImageStore(PersistentImageStore* store,
20 const base::FilePath& path) {
21 DCHECK(store);
22 new (store) PersistentImageStore(path);
23 }
24
25 void DeleteImageStore(ImageStore* store) {
26 DCHECK(store);
27 delete store;
28 }
29
30 void RetrieveImageFromStoreRelay(
31 ImageStore* store,
32 const GURL& page_url,
33 enhanced_bookmarks::BookmarkImageService::Callback callback,
34 scoped_refptr<base::SingleThreadTaskRunner> origin_loop) {
35 std::pair<gfx::Image, GURL> image_data = store->Get(page_url);
36 origin_loop->PostTask(
37 FROM_HERE, base::Bind(callback, image_data.first, image_data.second));
38 }
39
40 } // namespace
41
42 namespace enhanced_bookmarks {
43 BookmarkImageService::BookmarkImageService(
44 scoped_ptr<ImageStore> store,
45 BookmarkModel* bookmark_model,
46 scoped_refptr<base::SequencedWorkerPool> pool)
47 : bookmark_model_(bookmark_model), store_(store.Pass()), pool_(pool) {
48 DCHECK(CalledOnValidThread());
49 bookmark_model_->AddObserver(this);
50 }
51
52 BookmarkImageService::BookmarkImageService(
53 const base::FilePath& path,
54 BookmarkModel* bookmark_model,
55 scoped_refptr<base::SequencedWorkerPool> pool)
56 : bookmark_model_(bookmark_model), pool_(pool) {
57 DCHECK(CalledOnValidThread());
58 // PersistentImageStore has to be constructed in the thread it will be used,
59 // so we are posting the construction to the thread. However, we first
60 // allocate memory and keep here. The reason is that, before
61 // PersistentImageStore construction is done, it's possible that
62 // another member function, that posts store_ to the thread, is called.
63 // Although the construction might not be finished yet, we still want to post
64 // the task since it's guaranteed to be constructed by the time it is used, by
65 // the sequential thread task pool.
66 //
67 // Other alternatives:
68 // - Using a lock or WaitableEvent for PersistentImageStore construction.
69 // But waiting on UI thread is discouraged.
70 // - Posting the current BookmarkImageService instance instead of store_.
71 // But this will require using a weak pointer and can potentially block
72 // destroying BookmarkImageService.
73 PersistentImageStore* store =
74 (PersistentImageStore*)::operator new(sizeof(PersistentImageStore));
75 store_.reset(store);
76 pool_->PostNamedSequencedWorkerTask(
77 kSequenceToken,
78 FROM_HERE,
79 base::Bind(&ConstructPersistentImageStore, store, path));
80 }
81
82 BookmarkImageService::~BookmarkImageService() {
83 DCHECK(CalledOnValidThread());
84 bookmark_model_->RemoveObserver(this);
85 pool_->PostNamedSequencedWorkerTask(
86 kSequenceToken,
87 FROM_HERE,
88 base::Bind(&DeleteImageStore, store_.release()));
89 }
90
91 void BookmarkImageService::SalientImageForUrl(const GURL& page_url,
92 Callback callback) {
93 DCHECK(CalledOnValidThread());
94 SalientImageForUrl(page_url, true, callback);
95 }
96
97 void BookmarkImageService::RetrieveImageFromStore(
98 const GURL& page_url,
99 BookmarkImageService::Callback callback) {
100 DCHECK(CalledOnValidThread());
101 pool_->PostSequencedWorkerTaskWithShutdownBehavior(
102 pool_->GetNamedSequenceToken(kSequenceToken),
103 FROM_HERE,
104 base::Bind(&RetrieveImageFromStoreRelay,
105 base::Unretained(store_.get()),
106 page_url,
107 callback,
108 base::ThreadTaskRunnerHandle::Get()),
109 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
110 }
111
112 void BookmarkImageService::RetrieveSalientImageForPageUrl(
113 const GURL& page_url) {
114 DCHECK(CalledOnValidThread());
115 if (IsPageUrlInProgress(page_url))
116 return; // A request for this URL is already in progress.
117
118 in_progress_page_urls_.insert(page_url);
119
120 const BookmarkNode* bookmark =
121 bookmark_model_->GetMostRecentlyAddedUserNodeForURL(page_url);
122 GURL image_url;
123 if (bookmark) {
124 int width;
125 int height;
126 enhanced_bookmarks::ThumbnailImageFromBookmark(
127 bookmark, &image_url, &width, &height);
128 }
129
130 RetrieveSalientImage(
131 page_url,
132 image_url,
133 "",
134 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
wtc 2014/08/28 23:45:50 If we're passing a hardcoded value here, does Retr
noyau (Ping after 24h) 2014/08/29 08:44:01 RetrieveSalientImage() is protected and also calle
135 false);
136 }
137
138 void BookmarkImageService::FetchCallback(const GURL& page_url,
139 Callback original_callback,
140 const gfx::Image& image,
141 const GURL& image_url) {
142 DCHECK(CalledOnValidThread());
143 if (!image.IsEmpty() || !image_url.is_empty()) {
144 // Either the image was in the store or there is no image in the store, but
145 // an URL for an image is present, indicating that a previous attempt to
146 // download the image failed. Just return the image.
147 original_callback.Run(image, image_url);
148 } else {
149 // There is no image in the store, and no previous attempts to retrieve
150 // one. Start a request to retrieve a salient image if there is an image
151 // url set on a bookmark, and then enqueue the request for the image to
152 // be triggered when the retrieval is finished.
153 RetrieveSalientImageForPageUrl(page_url);
154 SalientImageForUrl(page_url, false, original_callback);
155 }
156 }
157
158 void BookmarkImageService::SalientImageForUrl(const GURL& page_url,
159 bool fetch_from_bookmark,
160 Callback callback) {
161 DCHECK(CalledOnValidThread());
162
163 // If the request is done while the image is currently being retrieved, just
164 // store the appropriate callbacks to call once the image is retrieved.
165 if (IsPageUrlInProgress(page_url)) {
166 callbacks_[page_url].push_back(callback);
167 return;
168 }
169
170 if (!fetch_from_bookmark) {
171 RetrieveImageFromStore(page_url, callback);
172 } else {
173 RetrieveImageFromStore(page_url,
174 base::Bind(&BookmarkImageService::FetchCallback,
175 base::Unretained(this),
176 page_url,
177 callback));
178 }
179 }
180
181 void BookmarkImageService::ProcessNewImage(const GURL& page_url,
182 bool update_bookmarks,
183 const gfx::Image& image,
184 const GURL& image_url) {
185 DCHECK(CalledOnValidThread());
186 StoreImage(image, image_url, page_url);
187 in_progress_page_urls_.erase(page_url);
188 ProcessRequests(page_url, image, image_url);
189 if (update_bookmarks && image_url.is_valid()) {
190 const BookmarkNode* bookmark =
191 bookmark_model_->GetMostRecentlyAddedUserNodeForURL(page_url);
192 if (bookmark) {
193 const gfx::Size& size = image.Size();
194 bool result = enhanced_bookmarks::SetOriginalImageForBookmark(
195 bookmark_model_, bookmark, image_url, size.width(), size.height());
196 DCHECK(result);
197 }
198 }
199 }
200
201 bool BookmarkImageService::IsPageUrlInProgress(const GURL& page_url) {
202 DCHECK(CalledOnValidThread());
203 return in_progress_page_urls_.find(page_url) != in_progress_page_urls_.end();
204 }
205
206 void BookmarkImageService::StoreImage(const gfx::Image& image,
207 const GURL& image_url,
208 const GURL& page_url) {
209 DCHECK(CalledOnValidThread());
210 if (!image.IsEmpty()) {
211 pool_->PostNamedSequencedWorkerTask(
212 kSequenceToken,
213 FROM_HERE,
214 base::Bind(&ImageStore::Insert,
215 base::Unretained(store_.get()),
216 page_url,
217 image_url,
218 image));
219 }
220 }
221
222 void BookmarkImageService::RemoveImageForUrl(const GURL& page_url) {
223 DCHECK(CalledOnValidThread());
224 pool_->PostNamedSequencedWorkerTask(
225 kSequenceToken,
226 FROM_HERE,
227 base::Bind(&ImageStore::Erase, base::Unretained(store_.get()), page_url));
228 in_progress_page_urls_.erase(page_url);
229 ProcessRequests(page_url, gfx::Image(), GURL());
230 }
231
232 void BookmarkImageService::ChangeImageURL(const GURL& from, const GURL& to) {
233 DCHECK(CalledOnValidThread());
234 pool_->PostNamedSequencedWorkerTask(kSequenceToken,
235 FROM_HERE,
236 base::Bind(&ImageStore::ChangeImageURL,
237 base::Unretained(store_.get()),
238 from,
239 to));
240 in_progress_page_urls_.erase(from);
241 ProcessRequests(from, gfx::Image(), GURL());
242 }
243
244 void BookmarkImageService::ClearAll() {
245 DCHECK(CalledOnValidThread());
246 // Clears and executes callbacks.
247 pool_->PostNamedSequencedWorkerTask(
248 kSequenceToken,
249 FROM_HERE,
250 base::Bind(&ImageStore::ClearAll, base::Unretained(store_.get())));
251
252 for (std::map<const GURL, std::vector<Callback> >::const_iterator it =
253 callbacks_.begin();
254 it != callbacks_.end();
255 ++it) {
256 ProcessRequests(it->first, gfx::Image(), GURL());
257 }
258
259 in_progress_page_urls_.erase(in_progress_page_urls_.begin(),
260 in_progress_page_urls_.end());
261 }
262
263 void BookmarkImageService::ProcessRequests(const GURL& page_url,
264 const gfx::Image& image,
265 const GURL& image_url) {
266 DCHECK(CalledOnValidThread());
267
268 std::vector<Callback> callbacks = callbacks_[page_url];
269 for (std::vector<Callback>::const_iterator it = callbacks.begin();
270 it != callbacks.end();
271 ++it) {
272 it->Run(image, image_url);
273 }
274
275 callbacks_.erase(page_url);
276 }
277
278 // BookmarkModelObserver methods.
279
280 void BookmarkImageService::BookmarkNodeRemoved(
281 BookmarkModel* model,
282 const BookmarkNode* parent,
283 int old_index,
284 const BookmarkNode* node,
285 const std::set<GURL>& removed_urls) {
286 DCHECK(CalledOnValidThread());
287 for (std::set<GURL>::const_iterator iter = removed_urls.begin();
288 iter != removed_urls.end();
289 ++iter) {
290 RemoveImageForUrl(*iter);
291 }
292 }
293
294 void BookmarkImageService::BookmarkModelLoaded(BookmarkModel* model,
295 bool ids_reassigned) {
296 }
297
298 void BookmarkImageService::BookmarkNodeMoved(BookmarkModel* model,
299 const BookmarkNode* old_parent,
300 int old_index,
301 const BookmarkNode* new_parent,
302 int new_index) {
303 }
304
305 void BookmarkImageService::BookmarkNodeAdded(BookmarkModel* model,
306 const BookmarkNode* parent,
307 int index) {
308 }
309
310 void BookmarkImageService::OnWillChangeBookmarkNode(BookmarkModel* model,
311 const BookmarkNode* node) {
312 DCHECK(CalledOnValidThread());
313 if (node->is_url())
314 previous_url_ = node->url();
315 }
316
317 void BookmarkImageService::BookmarkNodeChanged(BookmarkModel* model,
318 const BookmarkNode* node) {
319 DCHECK(CalledOnValidThread());
320 if (node->is_url() && previous_url_ != node->url())
321 ChangeImageURL(previous_url_, node->url());
322 }
323
324 void BookmarkImageService::BookmarkNodeFaviconChanged(
325 BookmarkModel* model,
326 const BookmarkNode* node) {
327 }
328
329 void BookmarkImageService::BookmarkNodeChildrenReordered(
330 BookmarkModel* model,
331 const BookmarkNode* node) {
332 }
333
334 void BookmarkImageService::BookmarkAllUserNodesRemoved(
335 BookmarkModel* model,
336 const std::set<GURL>& removed_urls) {
337 ClearAll();
338 }
339
340 } // namespace enhanced_bookmarks
OLDNEW
« no previous file with comments | « components/enhanced_bookmarks/bookmark_image_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698