| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/favicon/favicon_utils.h" |
| |
| #include "chrome/browser/favicon/favicon_service_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search/search.h" |
| #include "chrome/common/url_constants.h" |
| #include "components/favicon/content/content_favicon_driver.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/common/favicon_url.h" |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/gfx/image/image_skia_operations.h" |
| |
| namespace favicon { |
| |
| namespace { |
| |
| // Desaturate favicon HSL shift values. |
| const double kDesaturateHue = -1.0; |
| const double kDesaturateSaturation = 0.0; |
| const double kDesaturateLightness = 0.6; |
| } |
| |
| void CreateContentFaviconDriverForWebContents( |
| content::WebContents* web_contents) { |
| DCHECK(web_contents); |
| if (ContentFaviconDriver::FromWebContents(web_contents)) |
| return; |
| |
| Profile* original_profile = |
| Profile::FromBrowserContext(web_contents->GetBrowserContext()) |
| ->GetOriginalProfile(); |
| return ContentFaviconDriver::CreateForWebContents( |
| web_contents, |
| FaviconServiceFactory::GetForProfile(original_profile, |
| ServiceAccessType::IMPLICIT_ACCESS)); |
| } |
| |
| bool ShouldDisplayFavicon(content::WebContents* web_contents) { |
| // No favicon on interstitials. This check must be done first since |
| // interstitial navigations don't commit and always have a pending entry. |
| if (web_contents->ShowingInterstitialPage()) |
| return false; |
| |
| // Always display a throbber during pending loads. |
| const content::NavigationController& controller = |
| web_contents->GetController(); |
| if (controller.GetLastCommittedEntry() && controller.GetPendingEntry()) |
| return true; |
| |
| GURL url = web_contents->GetURL(); |
| if (url.SchemeIs(content::kChromeUIScheme) && |
| url.host_piece() == chrome::kChromeUINewTabHost) { |
| return false; |
| } |
| |
| // No favicon on Instant New Tab Pages. |
| if (search::IsInstantNTP(web_contents)) |
| return false; |
| |
| return true; |
| } |
| |
| gfx::Image TabFaviconFromWebContents(content::WebContents* contents) { |
| DCHECK(contents); |
| |
| favicon::FaviconDriver* favicon_driver = |
| favicon::ContentFaviconDriver::FromWebContents(contents); |
| gfx::Image favicon = favicon_driver->GetFavicon(); |
| |
| // Desaturate the favicon if the navigation entry contains a network error. |
| if (!contents->IsLoadingToDifferentDocument()) { |
| const content::NavigationController& controller = contents->GetController(); |
| |
| content::NavigationEntry* entry = controller.GetLastCommittedEntry(); |
| if (entry && (entry->GetPageType() == content::PAGE_TYPE_ERROR)) { |
| color_utils::HSL shift = {kDesaturateHue, kDesaturateSaturation, |
| kDesaturateLightness}; |
| return gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( |
| *favicon.ToImageSkia(), shift)); |
| } |
| } |
| |
| return favicon; |
| } |
| |
| } // namespace favicon |