OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/favicon/favicon_handler.h" | 5 #include "chrome/browser/favicon/favicon_handler.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <vector> | 10 #include <vector> |
(...skipping 17 matching lines...) Expand all Loading... |
28 using content::FaviconURL; | 28 using content::FaviconURL; |
29 using content::NavigationEntry; | 29 using content::NavigationEntry; |
30 | 30 |
31 namespace { | 31 namespace { |
32 | 32 |
33 // Size (along each axis) of a touch icon. This currently corresponds to | 33 // Size (along each axis) of a touch icon. This currently corresponds to |
34 // the apple touch icon for iPad. | 34 // the apple touch icon for iPad. |
35 const int kTouchIconSize = 144; | 35 const int kTouchIconSize = 144; |
36 | 36 |
37 // Returns chrome::IconType the given icon_type corresponds to. | 37 // Returns chrome::IconType the given icon_type corresponds to. |
38 chrome::IconType ToHistoryIconType(FaviconURL::IconType icon_type) { | 38 chrome::IconType ToChromeIconType(FaviconURL::IconType icon_type) { |
39 switch (icon_type) { | 39 switch (icon_type) { |
40 case FaviconURL::FAVICON: | 40 case FaviconURL::FAVICON: |
41 return chrome::FAVICON; | 41 return chrome::FAVICON; |
42 case FaviconURL::TOUCH_ICON: | 42 case FaviconURL::TOUCH_ICON: |
43 return chrome::TOUCH_ICON; | 43 return chrome::TOUCH_ICON; |
44 case FaviconURL::TOUCH_PRECOMPOSED_ICON: | 44 case FaviconURL::TOUCH_PRECOMPOSED_ICON: |
45 return chrome::TOUCH_PRECOMPOSED_ICON; | 45 return chrome::TOUCH_PRECOMPOSED_ICON; |
46 case FaviconURL::INVALID_ICON: | 46 case FaviconURL::INVALID_ICON: |
47 return chrome::INVALID_ICON; | 47 return chrome::INVALID_ICON; |
48 } | 48 } |
(...skipping 18 matching lines...) Expand all Loading... |
67 return 0; | 67 return 0; |
68 } | 68 } |
69 NOTREACHED(); | 69 NOTREACHED(); |
70 return 0; | 70 return 0; |
71 } | 71 } |
72 | 72 |
73 bool DoUrlAndIconMatch(const FaviconURL& favicon_url, | 73 bool DoUrlAndIconMatch(const FaviconURL& favicon_url, |
74 const GURL& url, | 74 const GURL& url, |
75 chrome::IconType icon_type) { | 75 chrome::IconType icon_type) { |
76 return favicon_url.icon_url == url && | 76 return favicon_url.icon_url == url && |
77 favicon_url.icon_type == static_cast<FaviconURL::IconType>(icon_type); | 77 ToChromeIconType(favicon_url.icon_type) == icon_type; |
78 } | 78 } |
79 | 79 |
80 // Returns true if all of the icon URLs and icon types in |bitmap_results| are | 80 // Returns true if all of the icon URLs and icon types in |bitmap_results| are |
81 // identical and if they match the icon URL and icon type in |favicon_url|. | 81 // identical and if they match the icon URL and icon type in |favicon_url|. |
82 // Returns false if |bitmap_results| is empty. | 82 // Returns false if |bitmap_results| is empty. |
83 bool DoUrlsAndIconsMatch( | 83 bool DoUrlsAndIconsMatch( |
84 const FaviconURL& favicon_url, | 84 const FaviconURL& favicon_url, |
85 const std::vector<chrome::FaviconBitmapResult>& bitmap_results) { | 85 const std::vector<chrome::FaviconBitmapResult>& bitmap_results) { |
86 if (bitmap_results.empty()) | 86 if (bitmap_results.empty()) |
87 return false; | 87 return false; |
88 | 88 |
89 chrome::IconType icon_type = ToHistoryIconType(favicon_url.icon_type); | 89 const chrome::IconType icon_type = ToChromeIconType(favicon_url.icon_type); |
90 | 90 |
91 for (size_t i = 0; i < bitmap_results.size(); ++i) { | 91 for (size_t i = 0; i < bitmap_results.size(); ++i) { |
92 if (favicon_url.icon_url != bitmap_results[i].icon_url || | 92 if (favicon_url.icon_url != bitmap_results[i].icon_url || |
93 icon_type != bitmap_results[i].icon_type) { | 93 icon_type != bitmap_results[i].icon_type) { |
94 return false; | 94 return false; |
95 } | 95 } |
96 } | 96 } |
97 return true; | 97 return true; |
98 } | 98 } |
99 | 99 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 favicon_sizes.end(), gfx::Size(edge_size_in_pixel, edge_size_in_pixel)); | 153 favicon_sizes.end(), gfx::Size(edge_size_in_pixel, edge_size_in_pixel)); |
154 if (it == favicon_sizes.end()) | 154 if (it == favicon_sizes.end()) |
155 return true; | 155 return true; |
156 } | 156 } |
157 return false; | 157 return false; |
158 } | 158 } |
159 | 159 |
160 // Returns true if at least one of |bitmap_results| is valid. | 160 // Returns true if at least one of |bitmap_results| is valid. |
161 bool HasValidResult( | 161 bool HasValidResult( |
162 const std::vector<chrome::FaviconBitmapResult>& bitmap_results) { | 162 const std::vector<chrome::FaviconBitmapResult>& bitmap_results) { |
163 std::vector<chrome::FaviconBitmapResult>::const_iterator it = | 163 return std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid) != |
164 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid); | 164 bitmap_results.end(); |
165 return it != bitmap_results.end(); | |
166 } | 165 } |
167 | 166 |
168 } // namespace | 167 } // namespace |
169 | 168 |
170 //////////////////////////////////////////////////////////////////////////////// | 169 //////////////////////////////////////////////////////////////////////////////// |
171 | 170 |
172 FaviconHandler::DownloadRequest::DownloadRequest() | 171 FaviconHandler::DownloadRequest::DownloadRequest() |
173 : icon_type(chrome::INVALID_ICON) { | 172 : icon_type(chrome::INVALID_ICON) { |
174 } | 173 } |
175 | 174 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 | 230 |
232 url_ = url; | 231 url_ = url; |
233 | 232 |
234 favicon_expired_or_incomplete_ = got_favicon_from_history_ = false; | 233 favicon_expired_or_incomplete_ = got_favicon_from_history_ = false; |
235 image_urls_.clear(); | 234 image_urls_.clear(); |
236 | 235 |
237 // Request the favicon from the history service. In parallel to this the | 236 // Request the favicon from the history service. In parallel to this the |
238 // renderer is going to notify us (well WebContents) when the favicon url is | 237 // renderer is going to notify us (well WebContents) when the favicon url is |
239 // available. | 238 // available. |
240 if (GetFaviconService()) { | 239 if (GetFaviconService()) { |
241 GetFaviconForURL( | 240 GetFaviconForURLFromFaviconService( |
242 url_, | 241 url_, |
243 icon_types_, | 242 icon_types_, |
244 base::Bind(&FaviconHandler::OnFaviconDataForInitialURL, | 243 base::Bind( |
245 base::Unretained(this)), | 244 &FaviconHandler::OnFaviconDataForInitialURLFromFaviconService, |
| 245 base::Unretained(this)), |
246 &cancelable_task_tracker_); | 246 &cancelable_task_tracker_); |
247 } | 247 } |
248 } | 248 } |
249 | 249 |
250 FaviconService* FaviconHandler::GetFaviconService() { | 250 FaviconService* FaviconHandler::GetFaviconService() { |
251 return FaviconServiceFactory::GetForProfile( | 251 return FaviconServiceFactory::GetForProfile( |
252 profile_, Profile::EXPLICIT_ACCESS); | 252 profile_, Profile::EXPLICIT_ACCESS); |
253 } | 253 } |
254 | 254 |
255 bool FaviconHandler::UpdateFaviconCandidate(const GURL& url, | 255 bool FaviconHandler::UpdateFaviconCandidate(const GURL& url, |
256 const GURL& image_url, | 256 const GURL& image_url, |
257 const gfx::Image& image, | 257 const gfx::Image& image, |
258 float score, | 258 float score, |
259 chrome::IconType icon_type) { | 259 chrome::IconType icon_type) { |
260 bool update_candidate = false; | 260 const bool exact_match = score == 1 || preferred_icon_size() == 0; |
261 bool exact_match = score == 1; | 261 if (exact_match || |
262 if (preferred_icon_size() == 0) { | 262 best_favicon_candidate_.icon_type == chrome::INVALID_ICON || |
263 // No preferred size, use this icon. | 263 score > best_favicon_candidate_.score) { |
264 update_candidate = true; | 264 best_favicon_candidate_ = FaviconCandidate( |
265 exact_match = true; | |
266 } else if (favicon_candidate_.icon_type == chrome::INVALID_ICON) { | |
267 // No current candidate, use this. | |
268 update_candidate = true; | |
269 } else { | |
270 if (exact_match) { | |
271 // Exact match, use this. | |
272 update_candidate = true; | |
273 } else { | |
274 // Compare against current candidate. | |
275 if (score > favicon_candidate_.score) | |
276 update_candidate = true; | |
277 } | |
278 } | |
279 if (update_candidate) { | |
280 favicon_candidate_ = FaviconCandidate( | |
281 url, image_url, image, score, icon_type); | 265 url, image_url, image, score, icon_type); |
282 } | 266 } |
283 return exact_match; | 267 return exact_match; |
284 } | 268 } |
285 | 269 |
286 void FaviconHandler::SetFavicon( | 270 void FaviconHandler::SetFavicon( |
287 const GURL& url, | 271 const GURL& url, |
288 const GURL& icon_url, | 272 const GURL& icon_url, |
289 const gfx::Image& image, | 273 const gfx::Image& image, |
290 chrome::IconType icon_type) { | 274 chrome::IconType icon_type) { |
291 if (GetFaviconService() && ShouldSaveFavicon(url)) | 275 if (GetFaviconService() && ShouldSaveFavicon(url)) |
292 SetHistoryFavicons(url, icon_url, icon_type, image); | 276 SetHistoryFavicons(url, icon_url, icon_type, image); |
293 | 277 |
294 if (UrlMatches(url, url_) && icon_type == chrome::FAVICON) { | 278 if (UrlMatches(url, url_) && icon_type == chrome::FAVICON) { |
295 NavigationEntry* entry = GetEntry(); | 279 NavigationEntry* entry = GetEntry(); |
296 if (entry) | 280 if (entry) |
297 UpdateFavicon(entry, icon_url, image); | 281 SetFaviconOnNavigationEntry(entry, icon_url, image); |
298 } | 282 } |
299 } | 283 } |
300 | 284 |
301 void FaviconHandler::UpdateFavicon(NavigationEntry* entry, | 285 void FaviconHandler::SetFaviconOnNavigationEntry( |
| 286 NavigationEntry* entry, |
302 const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { | 287 const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { |
303 gfx::Image resized_image = FaviconUtil::SelectFaviconFramesFromPNGs( | 288 gfx::Image resized_image = FaviconUtil::SelectFaviconFramesFromPNGs( |
304 favicon_bitmap_results, | 289 favicon_bitmap_results, |
305 FaviconUtil::GetFaviconScaleFactors(), | 290 FaviconUtil::GetFaviconScaleFactors(), |
306 preferred_icon_size()); | 291 preferred_icon_size()); |
307 // The history service sends back results for a single icon URL, so it does | 292 // The history service sends back results for a single icon URL, so it does |
308 // not matter which result we get the |icon_url| from. | 293 // not matter which result we get the |icon_url| from. |
309 const GURL icon_url = favicon_bitmap_results.empty() ? | 294 const GURL icon_url = favicon_bitmap_results.empty() ? |
310 GURL() : favicon_bitmap_results[0].icon_url; | 295 GURL() : favicon_bitmap_results[0].icon_url; |
311 UpdateFavicon(entry, icon_url, resized_image); | 296 SetFaviconOnNavigationEntry(entry, icon_url, resized_image); |
312 } | 297 } |
313 | 298 |
314 void FaviconHandler::UpdateFavicon(NavigationEntry* entry, | 299 void FaviconHandler::SetFaviconOnNavigationEntry( |
315 const GURL& icon_url, | 300 NavigationEntry* entry, |
316 const gfx::Image& image) { | 301 const GURL& icon_url, |
| 302 const gfx::Image& image) { |
317 // No matter what happens, we need to mark the favicon as being set. | 303 // No matter what happens, we need to mark the favicon as being set. |
318 entry->GetFavicon().valid = true; | 304 entry->GetFavicon().valid = true; |
319 | 305 |
320 bool icon_url_changed = (entry->GetFavicon().url != icon_url); | 306 bool icon_url_changed = (entry->GetFavicon().url != icon_url); |
321 entry->GetFavicon().url = icon_url; | 307 entry->GetFavicon().url = icon_url; |
322 | 308 |
323 if (image.IsEmpty()) | 309 if (image.IsEmpty()) |
324 return; | 310 return; |
325 | 311 |
326 gfx::Image image_with_adjusted_colorspace = image; | 312 gfx::Image image_with_adjusted_colorspace = image; |
327 FaviconUtil::SetFaviconColorSpace(&image_with_adjusted_colorspace); | 313 FaviconUtil::SetFaviconColorSpace(&image_with_adjusted_colorspace); |
328 | 314 |
329 entry->GetFavicon().image = image_with_adjusted_colorspace; | 315 entry->GetFavicon().image = image_with_adjusted_colorspace; |
330 NotifyFaviconUpdated(icon_url_changed); | 316 NotifyFaviconUpdated(icon_url_changed); |
331 } | 317 } |
332 | 318 |
333 void FaviconHandler::OnUpdateFaviconURL( | 319 void FaviconHandler::OnUpdateFaviconURL( |
334 int32 page_id, | 320 int32 page_id, |
335 const std::vector<FaviconURL>& candidates) { | 321 const std::vector<FaviconURL>& candidates) { |
336 | |
337 image_urls_.clear(); | 322 image_urls_.clear(); |
338 favicon_candidate_ = FaviconCandidate(); | 323 best_favicon_candidate_ = FaviconCandidate(); |
339 for (std::vector<FaviconURL>::const_iterator i = candidates.begin(); | 324 for (std::vector<FaviconURL>::const_iterator i = candidates.begin(); |
340 i != candidates.end(); ++i) { | 325 i != candidates.end(); ++i) { |
341 if (!i->icon_url.is_empty() && (i->icon_type & icon_types_)) | 326 if (!i->icon_url.is_empty() && (i->icon_type & icon_types_)) |
342 image_urls_.push_back(*i); | 327 image_urls_.push_back(*i); |
343 } | 328 } |
344 | 329 |
345 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 330 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
346 // This appears to be what FF does as well. | 331 // This appears to be what FF does as well. |
347 if (image_urls_.empty()) | 332 if (image_urls_.empty()) |
348 return; | 333 return; |
349 | 334 |
350 if (!GetFaviconService()) | 335 if (!GetFaviconService()) |
351 return; | 336 return; |
352 | 337 |
353 ProcessCurrentUrl(); | 338 ProcessCurrentUrl(); |
354 } | 339 } |
355 | 340 |
356 void FaviconHandler::ProcessCurrentUrl() { | 341 void FaviconHandler::ProcessCurrentUrl() { |
357 DCHECK(!image_urls_.empty()); | 342 DCHECK(!image_urls_.empty()); |
358 | 343 |
359 NavigationEntry* entry = GetEntry(); | 344 NavigationEntry* entry = GetEntry(); |
360 if (!entry) | 345 if (!entry) |
361 return; | 346 return; |
362 | 347 |
363 // For FAVICON. | |
364 if (current_candidate()->icon_type == FaviconURL::FAVICON) { | 348 if (current_candidate()->icon_type == FaviconURL::FAVICON) { |
365 if (!favicon_expired_or_incomplete_ && entry->GetFavicon().valid && | 349 if (!favicon_expired_or_incomplete_ && entry->GetFavicon().valid && |
366 DoUrlAndIconMatch(*current_candidate(), entry->GetFavicon().url, | 350 DoUrlAndIconMatch(*current_candidate(), entry->GetFavicon().url, |
367 chrome::FAVICON)) | 351 chrome::FAVICON)) |
368 return; | 352 return; |
369 } else if (!favicon_expired_or_incomplete_ && got_favicon_from_history_ && | 353 } else if (!favicon_expired_or_incomplete_ && got_favicon_from_history_ && |
370 HasValidResult(history_results_) && | 354 HasValidResult(history_results_) && |
371 DoUrlsAndIconsMatch(*current_candidate(), history_results_)) { | 355 DoUrlsAndIconsMatch(*current_candidate(), history_results_)) { |
372 return; | 356 return; |
373 } | 357 } |
374 | 358 |
375 if (got_favicon_from_history_) | 359 if (got_favicon_from_history_) |
376 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url, | 360 DownloadFaviconOrAskFaviconService( |
377 ToHistoryIconType(current_candidate()->icon_type)); | 361 entry->GetURL(), current_candidate()->icon_url, |
| 362 ToChromeIconType(current_candidate()->icon_type)); |
378 } | 363 } |
379 | 364 |
380 void FaviconHandler::OnDidDownloadFavicon( | 365 void FaviconHandler::OnDidDownloadFavicon( |
381 int id, | 366 int id, |
382 const GURL& image_url, | 367 const GURL& image_url, |
383 const std::vector<SkBitmap>& bitmaps, | 368 const std::vector<SkBitmap>& bitmaps, |
384 const std::vector<gfx::Size>& original_bitmap_sizes) { | 369 const std::vector<gfx::Size>& original_bitmap_sizes) { |
385 DownloadRequests::iterator i = download_requests_.find(id); | 370 DownloadRequests::iterator i = download_requests_.find(id); |
386 if (i == download_requests_.end()) { | 371 if (i == download_requests_.end()) { |
387 // Currently WebContents notifies us of ANY downloads so that it is | 372 // Currently WebContents notifies us of ANY downloads so that it is |
(...skipping 16 matching lines...) Expand all Loading... |
404 // during the downloading. | 389 // during the downloading. |
405 bool request_next_icon = true; | 390 bool request_next_icon = true; |
406 if (!bitmaps.empty()) { | 391 if (!bitmaps.empty()) { |
407 request_next_icon = !UpdateFaviconCandidate( | 392 request_next_icon = !UpdateFaviconCandidate( |
408 i->second.url, image_url, image, score, i->second.icon_type); | 393 i->second.url, image_url, image, score, i->second.icon_type); |
409 } | 394 } |
410 if (request_next_icon && GetEntry() && image_urls_.size() > 1) { | 395 if (request_next_icon && GetEntry() && image_urls_.size() > 1) { |
411 // Remove the first member of image_urls_ and process the remaining. | 396 // Remove the first member of image_urls_ and process the remaining. |
412 image_urls_.pop_front(); | 397 image_urls_.pop_front(); |
413 ProcessCurrentUrl(); | 398 ProcessCurrentUrl(); |
414 } else if (favicon_candidate_.icon_type != chrome::INVALID_ICON) { | 399 } else if (best_favicon_candidate_.icon_type != chrome::INVALID_ICON) { |
415 // No more icons to request, set the favicon from the candidate. | 400 // No more icons to request, set the favicon from the candidate. |
416 SetFavicon(favicon_candidate_.url, | 401 SetFavicon(best_favicon_candidate_.url, |
417 favicon_candidate_.image_url, | 402 best_favicon_candidate_.image_url, |
418 favicon_candidate_.image, | 403 best_favicon_candidate_.image, |
419 favicon_candidate_.icon_type); | 404 best_favicon_candidate_.icon_type); |
420 // Reset candidate. | 405 // Reset candidate. |
421 image_urls_.clear(); | 406 image_urls_.clear(); |
422 favicon_candidate_ = FaviconCandidate(); | 407 best_favicon_candidate_ = FaviconCandidate(); |
423 } | 408 } |
424 } | 409 } |
425 download_requests_.erase(i); | 410 download_requests_.erase(i); |
426 } | 411 } |
427 | 412 |
428 NavigationEntry* FaviconHandler::GetEntry() { | 413 NavigationEntry* FaviconHandler::GetEntry() { |
429 NavigationEntry* entry = delegate_->GetActiveEntry(); | 414 NavigationEntry* entry = delegate_->GetActiveEntry(); |
430 if (entry && UrlMatches(entry->GetURL(), url_)) | 415 if (entry && UrlMatches(entry->GetURL(), url_)) |
431 return entry; | 416 return entry; |
432 | 417 |
(...skipping 18 matching lines...) Expand all Loading... |
451 const FaviconService::FaviconResultsCallback& callback, | 436 const FaviconService::FaviconResultsCallback& callback, |
452 base::CancelableTaskTracker* tracker) { | 437 base::CancelableTaskTracker* tracker) { |
453 // TODO(pkotwicz): pass in all of |image_urls_| to | 438 // TODO(pkotwicz): pass in all of |image_urls_| to |
454 // UpdateFaviconMappingsAndFetch(). | 439 // UpdateFaviconMappingsAndFetch(). |
455 std::vector<GURL> icon_urls; | 440 std::vector<GURL> icon_urls; |
456 icon_urls.push_back(icon_url); | 441 icon_urls.push_back(icon_url); |
457 GetFaviconService()->UpdateFaviconMappingsAndFetch( | 442 GetFaviconService()->UpdateFaviconMappingsAndFetch( |
458 page_url, icon_urls, icon_type, preferred_icon_size(), callback, tracker); | 443 page_url, icon_urls, icon_type, preferred_icon_size(), callback, tracker); |
459 } | 444 } |
460 | 445 |
461 void FaviconHandler::GetFavicon( | 446 void FaviconHandler::GetFaviconFromFaviconService( |
462 const GURL& icon_url, | 447 const GURL& icon_url, |
463 chrome::IconType icon_type, | 448 chrome::IconType icon_type, |
464 const FaviconService::FaviconResultsCallback& callback, | 449 const FaviconService::FaviconResultsCallback& callback, |
465 base::CancelableTaskTracker* tracker) { | 450 base::CancelableTaskTracker* tracker) { |
466 GetFaviconService()->GetFavicon( | 451 GetFaviconService()->GetFavicon( |
467 icon_url, icon_type, preferred_icon_size(), callback, tracker); | 452 icon_url, icon_type, preferred_icon_size(), callback, tracker); |
468 } | 453 } |
469 | 454 |
470 void FaviconHandler::GetFaviconForURL( | 455 void FaviconHandler::GetFaviconForURLFromFaviconService( |
471 const GURL& page_url, | 456 const GURL& page_url, |
472 int icon_types, | 457 int icon_types, |
473 const FaviconService::FaviconResultsCallback& callback, | 458 const FaviconService::FaviconResultsCallback& callback, |
474 base::CancelableTaskTracker* tracker) { | 459 base::CancelableTaskTracker* tracker) { |
475 GetFaviconService()->GetFaviconForURL( | 460 GetFaviconService()->GetFaviconForURL( |
476 FaviconService::FaviconForURLParams(page_url, icon_types, | 461 FaviconService::FaviconForURLParams(page_url, icon_types, |
477 preferred_icon_size()), | 462 preferred_icon_size()), |
478 callback, | 463 callback, |
479 tracker); | 464 tracker); |
480 } | 465 } |
(...skipping 12 matching lines...) Expand all Loading... |
493 // Otherwise store the favicon if the page is bookmarked. | 478 // Otherwise store the favicon if the page is bookmarked. |
494 BookmarkService* bookmark_service = | 479 BookmarkService* bookmark_service = |
495 BookmarkService::FromBrowserContext(profile_); | 480 BookmarkService::FromBrowserContext(profile_); |
496 return bookmark_service && bookmark_service->IsBookmarked(url); | 481 return bookmark_service && bookmark_service->IsBookmarked(url); |
497 } | 482 } |
498 | 483 |
499 void FaviconHandler::NotifyFaviconUpdated(bool icon_url_changed) { | 484 void FaviconHandler::NotifyFaviconUpdated(bool icon_url_changed) { |
500 delegate_->NotifyFaviconUpdated(icon_url_changed); | 485 delegate_->NotifyFaviconUpdated(icon_url_changed); |
501 } | 486 } |
502 | 487 |
503 void FaviconHandler::OnFaviconDataForInitialURL( | 488 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
504 const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { | 489 const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { |
505 NavigationEntry* entry = GetEntry(); | 490 NavigationEntry* entry = GetEntry(); |
506 if (!entry) | 491 if (!entry) |
507 return; | 492 return; |
508 | 493 |
509 got_favicon_from_history_ = true; | 494 got_favicon_from_history_ = true; |
510 history_results_ = favicon_bitmap_results; | 495 history_results_ = favicon_bitmap_results; |
511 | 496 |
512 bool has_results = !favicon_bitmap_results.empty(); | 497 bool has_results = !favicon_bitmap_results.empty(); |
513 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult( | 498 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult( |
514 preferred_icon_size(), favicon_bitmap_results); | 499 preferred_icon_size(), favicon_bitmap_results); |
515 | 500 |
516 if (has_results && icon_types_ == chrome::FAVICON && | 501 if (has_results && icon_types_ == chrome::FAVICON && |
517 !entry->GetFavicon().valid && | 502 !entry->GetFavicon().valid && |
518 (!current_candidate() || | 503 (!current_candidate() || |
519 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { | 504 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { |
520 if (HasValidResult(favicon_bitmap_results)) { | 505 if (HasValidResult(favicon_bitmap_results)) { |
521 // The db knows the favicon (although it may be out of date) and the entry | 506 // The db knows the favicon (although it may be out of date) and the entry |
522 // doesn't have an icon. Set the favicon now, and if the favicon turns out | 507 // doesn't have an icon. Set the favicon now, and if the favicon turns out |
523 // to be expired (or the wrong url) we'll fetch later on. This way the | 508 // to be expired (or the wrong url) we'll fetch later on. This way the |
524 // user doesn't see a flash of the default favicon. | 509 // user doesn't see a flash of the default favicon. |
525 UpdateFavicon(entry, favicon_bitmap_results); | 510 SetFaviconOnNavigationEntry(entry, favicon_bitmap_results); |
526 } else { | 511 } else { |
527 // If |favicon_bitmap_results| does not have any valid results, treat the | 512 // If |favicon_bitmap_results| does not have any valid results, treat the |
528 // favicon as if it's expired. | 513 // favicon as if it's expired. |
529 // TODO(pkotwicz): Do something better. | 514 // TODO(pkotwicz): Do something better. |
530 favicon_expired_or_incomplete_ = true; | 515 favicon_expired_or_incomplete_ = true; |
531 } | 516 } |
532 } | 517 } |
533 | 518 |
534 if (has_results && !favicon_expired_or_incomplete_) { | 519 if (has_results && !favicon_expired_or_incomplete_) { |
535 if (current_candidate() && | 520 if (current_candidate() && |
536 !DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)) { | 521 !DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)) { |
537 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will | 522 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will |
538 // update the mapping for this url and download the favicon if we don't | 523 // update the mapping for this url and download the favicon if we don't |
539 // already have it. | 524 // already have it. |
540 DownloadFaviconOrAskHistory(entry->GetURL(), | 525 DownloadFaviconOrAskFaviconService( |
541 current_candidate()->icon_url, | 526 entry->GetURL(), current_candidate()->icon_url, |
542 static_cast<chrome::IconType>(current_candidate()->icon_type)); | 527 ToChromeIconType(current_candidate()->icon_type)); |
543 } | 528 } |
544 } else if (current_candidate()) { | 529 } else if (current_candidate()) { |
545 // We know the official url for the favicon, by either don't have the | 530 // We know the official url for the favicon, but either don't have the |
546 // favicon or its expired. Continue on to DownloadFaviconOrAskHistory to | 531 // favicon or it's expired. Continue on to DownloadFaviconOrAskHistory to |
547 // either download or check history again. | 532 // either download or check history again. |
548 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url, | 533 DownloadFaviconOrAskFaviconService( |
549 ToHistoryIconType(current_candidate()->icon_type)); | 534 entry->GetURL(), current_candidate()->icon_url, |
| 535 ToChromeIconType(current_candidate()->icon_type)); |
550 } | 536 } |
551 // else we haven't got the icon url. When we get it we'll ask the | 537 // else we haven't got the icon url. When we get it we'll ask the |
552 // renderer to download the icon. | 538 // renderer to download the icon. |
553 } | 539 } |
554 | 540 |
555 void FaviconHandler::DownloadFaviconOrAskHistory( | 541 void FaviconHandler::DownloadFaviconOrAskFaviconService( |
556 const GURL& page_url, | 542 const GURL& page_url, |
557 const GURL& icon_url, | 543 const GURL& icon_url, |
558 chrome::IconType icon_type) { | 544 chrome::IconType icon_type) { |
559 if (favicon_expired_or_incomplete_) { | 545 if (favicon_expired_or_incomplete_) { |
560 // We have the mapping, but the favicon is out of date. Download it now. | 546 // We have the mapping, but the favicon is out of date. Download it now. |
561 ScheduleDownload(page_url, icon_url, icon_type); | 547 ScheduleDownload(page_url, icon_url, icon_type); |
562 } else if (GetFaviconService()) { | 548 } else if (GetFaviconService()) { |
563 // We don't know the favicon, but we may have previously downloaded the | 549 // We don't know the favicon, but we may have previously downloaded the |
564 // favicon for another page that shares the same favicon. Ask for the | 550 // favicon for another page that shares the same favicon. Ask for the |
565 // favicon given the favicon URL. | 551 // favicon given the favicon URL. |
566 if (profile_->IsOffTheRecord()) { | 552 if (profile_->IsOffTheRecord()) { |
567 GetFavicon( | 553 GetFaviconFromFaviconService( |
568 icon_url, icon_type, | 554 icon_url, icon_type, |
569 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 555 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
570 &cancelable_task_tracker_); | 556 &cancelable_task_tracker_); |
571 } else { | 557 } else { |
572 // Ask the history service for the icon. This does two things: | 558 // Ask the history service for the icon. This does two things: |
573 // 1. Attempts to fetch the favicon data from the database. | 559 // 1. Attempts to fetch the favicon data from the database. |
574 // 2. If the favicon exists in the database, this updates the database to | 560 // 2. If the favicon exists in the database, this updates the database to |
575 // include the mapping between the page url and the favicon url. | 561 // include the mapping between the page url and the favicon url. |
576 // This is asynchronous. The history service will call back when done. | 562 // This is asynchronous. The history service will call back when done. |
577 // Issue the request and associate the current page ID with it. | |
578 UpdateFaviconMappingAndFetch( | 563 UpdateFaviconMappingAndFetch( |
579 page_url, icon_url, icon_type, | 564 page_url, icon_url, icon_type, |
580 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 565 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
581 &cancelable_task_tracker_); | 566 &cancelable_task_tracker_); |
582 } | 567 } |
583 } | 568 } |
584 } | 569 } |
585 | 570 |
586 void FaviconHandler::OnFaviconData( | 571 void FaviconHandler::OnFaviconData( |
587 const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { | 572 const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { |
588 NavigationEntry* entry = GetEntry(); | 573 NavigationEntry* entry = GetEntry(); |
589 if (!entry) | 574 if (!entry) |
590 return; | 575 return; |
591 | 576 |
592 bool has_results = !favicon_bitmap_results.empty(); | 577 bool has_results = !favicon_bitmap_results.empty(); |
593 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( | 578 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( |
594 preferred_icon_size(), favicon_bitmap_results); | 579 preferred_icon_size(), favicon_bitmap_results); |
595 | 580 |
596 if (has_results && icon_types_ == chrome::FAVICON) { | 581 if (has_results && icon_types_ == chrome::FAVICON) { |
597 if (HasValidResult(favicon_bitmap_results)) { | 582 if (HasValidResult(favicon_bitmap_results)) { |
598 // There is a favicon, set it now. If expired we'll download the current | 583 // There is a favicon, set it now. If expired we'll download the current |
599 // one again, but at least the user will get some icon instead of the | 584 // one again, but at least the user will get some icon instead of the |
600 // default and most likely the current one is fine anyway. | 585 // default and most likely the current one is fine anyway. |
601 UpdateFavicon(entry, favicon_bitmap_results); | 586 SetFaviconOnNavigationEntry(entry, favicon_bitmap_results); |
602 } | 587 } |
603 if (has_expired_or_incomplete_result) { | 588 if (has_expired_or_incomplete_result) { |
604 // The favicon is out of date. Request the current one. | 589 // The favicon is out of date. Request the current one. |
605 ScheduleDownload(entry->GetURL(), entry->GetFavicon().url, | 590 ScheduleDownload(entry->GetURL(), entry->GetFavicon().url, |
606 chrome::FAVICON); | 591 chrome::FAVICON); |
607 } | 592 } |
608 } else if (current_candidate() && | 593 } else if (current_candidate() && |
609 (!has_results || has_expired_or_incomplete_result || | 594 (!has_results || has_expired_or_incomplete_result || |
610 !(DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)))) { | 595 !(DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)))) { |
611 // We don't know the favicon, it is out of date or its type is not same as | 596 // We don't know the favicon, it is out of date or its type is not same as |
612 // one got from page. Request the current one. | 597 // one got from page. Request the current one. |
613 ScheduleDownload(entry->GetURL(), current_candidate()->icon_url, | 598 ScheduleDownload(entry->GetURL(), current_candidate()->icon_url, |
614 ToHistoryIconType(current_candidate()->icon_type)); | 599 ToChromeIconType(current_candidate()->icon_type)); |
615 } | 600 } |
616 history_results_ = favicon_bitmap_results; | 601 history_results_ = favicon_bitmap_results; |
617 } | 602 } |
618 | 603 |
619 int FaviconHandler::ScheduleDownload( | 604 int FaviconHandler::ScheduleDownload( |
620 const GURL& url, | 605 const GURL& url, |
621 const GURL& image_url, | 606 const GURL& image_url, |
622 chrome::IconType icon_type) { | 607 chrome::IconType icon_type) { |
623 // A max bitmap size is specified to avoid receiving huge bitmaps in | 608 // A max bitmap size is specified to avoid receiving huge bitmaps in |
624 // OnDidDownloadFavicon(). See FaviconHandlerDelegate::StartDownload() | 609 // OnDidDownloadFavicon(). See FaviconHandlerDelegate::StartDownload() |
625 // for more details about the max bitmap size. | 610 // for more details about the max bitmap size. |
626 const int download_id = DownloadFavicon(image_url, | 611 const int download_id = DownloadFavicon(image_url, |
627 GetMaximalIconSize(icon_type)); | 612 GetMaximalIconSize(icon_type)); |
628 if (download_id) { | 613 if (download_id) { |
629 // Download ids should be unique. | 614 // Download ids should be unique. |
630 DCHECK(download_requests_.find(download_id) == download_requests_.end()); | 615 DCHECK(download_requests_.find(download_id) == download_requests_.end()); |
631 download_requests_[download_id] = | 616 download_requests_[download_id] = |
632 DownloadRequest(url, image_url, icon_type); | 617 DownloadRequest(url, image_url, icon_type); |
633 } | 618 } |
634 | 619 |
635 return download_id; | 620 return download_id; |
636 } | 621 } |
OLD | NEW |