diff options
Diffstat (limited to 'chrome/browser')
6 files changed, 62 insertions, 458 deletions
diff --git a/chrome/browser/favicon/favicon_handler_unittest.cc b/chrome/browser/favicon/favicon_handler_unittest.cc index 5a70ff4..e01f585 100644 --- a/chrome/browser/favicon/favicon_handler_unittest.cc +++ b/chrome/browser/favicon/favicon_handler_unittest.cc @@ -183,6 +183,35 @@ class TestFaviconDriver : public favicon::FaviconDriver { ~TestFaviconDriver() override {} + // favicon::FaviconDriver implementation. + void FetchFavicon(const GURL& url) override { + ADD_FAILURE() << "TestFaviconDriver::FetchFavicon() " + << "should never be called in tests."; + } + + void SaveFavicon() override { + ADD_FAILURE() << "TestFaviconDriver::SaveFavicon() " + << "should never be called in tests."; + } + + gfx::Image GetFavicon() const override { + ADD_FAILURE() << "TestFaviconDriver::GetFavicon() " + << "should never be called in tests."; + return gfx::Image(); + } + + bool FaviconIsValid() const override { + ADD_FAILURE() << "TestFaviconDriver::FaviconIsValid() " + << "should never be called in tests."; + return false; + } + + bool HasPendingTasksForTest() override { + ADD_FAILURE() << "TestFaviconDriver::HasPendingTasksForTest() " + << "should never be called in tests."; + return false; + } + int StartDownload(const GURL& url, int max_bitmap_size) override { ADD_FAILURE() << "TestFaviconDriver::StartDownload() " << "should never be called in tests."; @@ -231,8 +260,6 @@ class TestFaviconDriver : public favicon::FaviconDriver { SetActiveFaviconImage(image); } - void NotifyFaviconUpdated(bool icon_url_changed) override {} - size_t num_active_favicon() const { return num_active_favicon_; } size_t num_favicon_available() const { return num_favicon_available_; } void ResetNumActiveFavicon() { num_active_favicon_ = 0; } diff --git a/chrome/browser/favicon/favicon_tab_helper.cc b/chrome/browser/favicon/favicon_tab_helper.cc index e5e9334..177e7ba 100644 --- a/chrome/browser/favicon/favicon_tab_helper.cc +++ b/chrome/browser/favicon/favicon_tab_helper.cc @@ -4,73 +4,13 @@ #include "chrome/browser/favicon/favicon_tab_helper.h" -#include "base/command_line.h" -#include "base/metrics/field_trial.h" -#include "base/strings/string_util.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/search.h" -#include "chrome/common/chrome_constants.h" #include "chrome/common/url_constants.h" -#include "components/bookmarks/browser/bookmark_model.h" -#include "components/favicon/content/favicon_url_util.h" -#include "components/favicon/core/favicon_driver_observer.h" -#include "components/favicon/core/favicon_handler.h" -#include "components/favicon/core/favicon_service.h" -#include "components/favicon_base/favicon_types.h" -#include "components/history/core/browser/history_service.h" -#include "content/public/browser/favicon_status.h" -#include "content/public/browser/invalidate_type.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_details.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_delegate.h" #include "content/public/common/favicon_url.h" -#include "ui/base/ui_base_switches.h" -#include "ui/gfx/codec/png_codec.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/image/image_skia_rep.h" - -using content::FaviconStatus; -using content::NavigationController; -using content::NavigationEntry; -using content::WebContents; - -DEFINE_WEB_CONTENTS_USER_DATA_KEY(FaviconTabHelper); - -namespace { - -// Returns whether icon NTP is enabled by experiment. -// TODO(huangs): Remove all 3 copies of this routine once Icon NTP launches. -bool IsIconNTPEnabled() { - // Note: It's important to query the field trial state first, to ensure that - // UMA reports the correct group. - const std::string group_name = base::FieldTrialList::FindFullName("IconNTP"); - using base::CommandLine; - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableIconNtp)) - return false; - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableIconNtp)) - return true; - - return StartsWithASCII(group_name, "Enabled", true); -} - -#if defined(OS_ANDROID) || defined(OS_IOS) -const bool kDownloadLargestIcon = true; -const bool kEnableTouchIcon = true; -#else -const bool kDownloadLargestIcon = false; -const bool kEnableTouchIcon = false; -#endif - -} // namespace // static void FaviconTabHelper::CreateForWebContents( @@ -93,277 +33,41 @@ void FaviconTabHelper::CreateForWebContents( BookmarkModelFactory::GetForProfileIfExists(original_profile))); } -FaviconTabHelper::FaviconTabHelper(WebContents* web_contents, - favicon::FaviconService* favicon_service, - history::HistoryService* history_service, - bookmarks::BookmarkModel* bookmark_model) - : content::WebContentsObserver(web_contents), - favicon_service_(favicon_service), - history_service_(history_service), - bookmark_model_(bookmark_model) { - favicon_handler_.reset(new favicon::FaviconHandler( - favicon_service_, this, favicon::FaviconHandler::FAVICON, - kDownloadLargestIcon)); - if (kEnableTouchIcon) { - touch_icon_handler_.reset(new favicon::FaviconHandler( - favicon_service_, this, favicon::FaviconHandler::TOUCH, - kDownloadLargestIcon)); - } - if (IsIconNTPEnabled()) { - large_icon_handler_.reset(new favicon::FaviconHandler( - favicon_service_, this, favicon::FaviconHandler::LARGE, true)); - } -} - -FaviconTabHelper::~FaviconTabHelper() { -} - -void FaviconTabHelper::FetchFavicon(const GURL& url) { - favicon_handler_->FetchFavicon(url); - if (touch_icon_handler_.get()) - touch_icon_handler_->FetchFavicon(url); - if (large_icon_handler_.get()) - large_icon_handler_->FetchFavicon(url); -} - -gfx::Image FaviconTabHelper::GetFavicon() const { - // Like GetTitle(), we also want to use the favicon for the last committed - // entry rather than a pending navigation entry. - const NavigationController& controller = web_contents()->GetController(); - NavigationEntry* entry = controller.GetTransientEntry(); - if (entry) - return entry->GetFavicon().image; - - entry = controller.GetLastCommittedEntry(); - if (entry) - return entry->GetFavicon().image; - return gfx::Image(); -} - -bool FaviconTabHelper::FaviconIsValid() const { - const NavigationController& controller = web_contents()->GetController(); - NavigationEntry* entry = controller.GetTransientEntry(); - if (entry) - return entry->GetFavicon().valid; - - entry = controller.GetLastCommittedEntry(); - if (entry) - return entry->GetFavicon().valid; - - return false; +// static +FaviconTabHelper* FaviconTabHelper::FromWebContents( + content::WebContents* web_contents) { + return static_cast<FaviconTabHelper*>( + favicon::ContentFaviconDriver::FromWebContents(web_contents)); } -bool FaviconTabHelper::ShouldDisplayFavicon() { +// static +bool FaviconTabHelper::ShouldDisplayFavicon( + content::WebContents* web_contents) { // Always display a throbber during pending loads. - const NavigationController& controller = web_contents()->GetController(); + const content::NavigationController& controller = + web_contents->GetController(); if (controller.GetLastCommittedEntry() && controller.GetPendingEntry()) return true; - GURL url = web_contents()->GetURL(); + GURL url = web_contents->GetURL(); if (url.SchemeIs(content::kChromeUIScheme) && url.host() == chrome::kChromeUINewTabHost) { return false; } // No favicon on Instant New Tab Pages. - if (chrome::IsInstantNTP(web_contents())) + if (chrome::IsInstantNTP(web_contents)) return false; return true; } -void FaviconTabHelper::SaveFavicon() { - GURL active_url = GetActiveURL(); - if (active_url.is_empty()) - return; - - // Make sure the page is in history, otherwise adding the favicon does - // nothing. - if (!history_service_) - return; - history_service_->AddPageNoVisitForBookmark(active_url, GetActiveTitle()); - - if (!favicon_service_) - return; - if (!GetActiveFaviconValidity()) - return; - GURL favicon_url = GetActiveFaviconURL(); - if (favicon_url.is_empty()) - return; - gfx::Image image = GetActiveFaviconImage(); - if (image.IsEmpty()) - return; - favicon_service_->SetFavicons(active_url, favicon_url, favicon_base::FAVICON, - image); -} - -void FaviconTabHelper::AddObserver(favicon::FaviconDriverObserver* observer) { - observer_list_.AddObserver(observer); -} - -void FaviconTabHelper::RemoveObserver( - favicon::FaviconDriverObserver* observer) { - observer_list_.RemoveObserver(observer); -} - -int FaviconTabHelper::StartDownload(const GURL& url, int max_image_size) { - if (favicon_service_ && favicon_service_->WasUnableToDownloadFavicon(url)) { - DVLOG(1) << "Skip Failed FavIcon: " << url; - return 0; - } - - bool bypass_cache = (bypass_cache_page_url_ == GetActiveURL()); - bypass_cache_page_url_ = GURL(); - - return web_contents()->DownloadImage( - url, true, max_image_size, bypass_cache, - base::Bind(&FaviconTabHelper::DidDownloadFavicon, - base::Unretained(this))); -} - -bool FaviconTabHelper::IsOffTheRecord() { - DCHECK(web_contents()); - return web_contents()->GetBrowserContext()->IsOffTheRecord(); -} - -bool FaviconTabHelper::IsBookmarked(const GURL& url) { - return bookmark_model_ && bookmark_model_->IsBookmarked(url); -} - -GURL FaviconTabHelper::GetActiveURL() { - NavigationEntry* entry = web_contents()->GetController().GetActiveEntry(); - return entry ? entry->GetURL() : GURL(); -} - -base::string16 FaviconTabHelper::GetActiveTitle() { - NavigationEntry* entry = web_contents()->GetController().GetActiveEntry(); - return entry ? entry->GetTitle() : base::string16(); -} - -bool FaviconTabHelper::GetActiveFaviconValidity() { - return GetFaviconStatus().valid; -} - -void FaviconTabHelper::SetActiveFaviconValidity(bool valid) { - GetFaviconStatus().valid = valid; -} - -GURL FaviconTabHelper::GetActiveFaviconURL() { - return GetFaviconStatus().url; -} - -void FaviconTabHelper::SetActiveFaviconURL(const GURL& url) { - GetFaviconStatus().url = url; -} - -gfx::Image FaviconTabHelper::GetActiveFaviconImage() { - return GetFaviconStatus().image; -} - -void FaviconTabHelper::SetActiveFaviconImage(const gfx::Image& image) { - GetFaviconStatus().image = image; -} - -void FaviconTabHelper::OnFaviconAvailable(const gfx::Image& image, - const GURL& icon_url, - bool is_active_favicon) { - if (is_active_favicon) { - bool icon_url_changed = GetActiveFaviconURL() != icon_url; - // No matter what happens, we need to mark the favicon as being set. - SetActiveFaviconValidity(true); - SetActiveFaviconURL(icon_url); - - if (image.IsEmpty()) - return; - - SetActiveFaviconImage(image); - NotifyFaviconUpdated(icon_url_changed); - } - if (!image.IsEmpty()) { - FOR_EACH_OBSERVER(favicon::FaviconDriverObserver, observer_list_, - OnFaviconAvailable(image)); - } -} - -void FaviconTabHelper::NotifyFaviconUpdated(bool icon_url_changed) { - FOR_EACH_OBSERVER(favicon::FaviconDriverObserver, observer_list_, - OnFaviconUpdated(this, icon_url_changed)); - web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); -} - -void FaviconTabHelper::DidDownloadFavicon( - int id, - int http_status_code, - const GURL& image_url, - const std::vector<SkBitmap>& bitmaps, - const std::vector<gfx::Size>& original_bitmap_sizes) { - if (bitmaps.empty() && http_status_code == 404) { - DVLOG(1) << "Failed to Download Favicon:" << image_url; - if (favicon_service_) - favicon_service_->UnableToDownloadFavicon(image_url); - } - - favicon_handler_->OnDidDownloadFavicon(id, image_url, bitmaps, - original_bitmap_sizes); - if (touch_icon_handler_.get()) { - touch_icon_handler_->OnDidDownloadFavicon(id, image_url, bitmaps, - original_bitmap_sizes); - } - if (large_icon_handler_.get()) { - large_icon_handler_->OnDidDownloadFavicon(id, image_url, bitmaps, - original_bitmap_sizes); - } -} - -content::FaviconStatus& FaviconTabHelper::GetFaviconStatus() { - DCHECK(web_contents()->GetController().GetActiveEntry()); - return web_contents()->GetController().GetActiveEntry()->GetFavicon(); -} - -void FaviconTabHelper::DidStartNavigationToPendingEntry( - const GURL& url, - NavigationController::ReloadType reload_type) { - if (reload_type == NavigationController::NO_RELOAD || IsOffTheRecord()) - return; - - bypass_cache_page_url_ = url; - - if (favicon_service_) { - favicon_service_->SetFaviconOutOfDateForPage(url); - if (reload_type == NavigationController::RELOAD_IGNORING_CACHE) - favicon_service_->ClearUnableToDownloadFavicons(); - } -} - -void FaviconTabHelper::DidNavigateMainFrame( - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) { - favicon_urls_.clear(); - - // Wait till the user navigates to a new URL to start checking the cache - // again. The cache may be ignored for non-reload navigations (e.g. - // history.replace() in-page navigation). This is allowed to increase the - // likelihood that "reloading a page ignoring the cache" redownloads the - // favicon. In particular, a page may do an in-page navigation before - // FaviconHandler has the time to determine that the favicon needs to be - // redownloaded. - GURL url = details.entry->GetURL(); - if (url != bypass_cache_page_url_) - bypass_cache_page_url_ = GURL(); - - // Get the favicon, either from history or request it from the net. - FetchFavicon(url); -} - -void FaviconTabHelper::DidUpdateFaviconURL( - const std::vector<content::FaviconURL>& candidates) { - DCHECK(!candidates.empty()); - favicon_urls_ = candidates; - std::vector<favicon::FaviconURL> favicon_urls = - favicon::FaviconURLsFromContentFaviconURLs(candidates); - favicon_handler_->OnUpdateFaviconURL(favicon_urls); - if (touch_icon_handler_.get()) - touch_icon_handler_->OnUpdateFaviconURL(favicon_urls); - if (large_icon_handler_.get()) - large_icon_handler_->OnUpdateFaviconURL(favicon_urls); +FaviconTabHelper::FaviconTabHelper(content::WebContents* web_contents, + favicon::FaviconService* favicon_service, + history::HistoryService* history_service, + bookmarks::BookmarkModel* bookmark_model) + : favicon::ContentFaviconDriver(web_contents, + favicon_service, + history_service, + bookmark_model) { } diff --git a/chrome/browser/favicon/favicon_tab_helper.h b/chrome/browser/favicon/favicon_tab_helper.h index 537ee40..e907090 100644 --- a/chrome/browser/favicon/favicon_tab_helper.h +++ b/chrome/browser/favicon/favicon_tab_helper.h @@ -5,115 +5,23 @@ #ifndef CHROME_BROWSER_FAVICON_FAVICON_TAB_HELPER_H_ #define CHROME_BROWSER_FAVICON_FAVICON_TAB_HELPER_H_ -#include <vector> +#include "base/macros.h" +#include "components/favicon/content/content_favicon_driver.h" -#include "base/basictypes.h" -#include "base/callback.h" -#include "base/observer_list.h" -#include "components/favicon/core/favicon_driver.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "content/public/common/favicon_url.h" - -class GURL; -class SkBitmap; - -namespace gfx { -class Image; -} - -namespace bookmarks { -class BookmarkModel; -} - -namespace content { -struct FaviconStatus; -} - -namespace favicon { -class FaviconDriverObserver; -class FaviconHandler; -class FaviconService; -} - -namespace history { -class HistoryService; -} - -// FaviconTabHelper works with favicon::FaviconHandlers to fetch the favicons. -// -// FetchFavicon fetches the given page's icons. It requests the icons from the -// history backend. If the icon is not available or expired, the icon will be -// downloaded and saved in the history backend. -// -class FaviconTabHelper : public content::WebContentsObserver, - public favicon::FaviconDriver, - public content::WebContentsUserData<FaviconTabHelper> { +// FaviconTabHelper provides helper factory for ContentFaviconDriver. +class FaviconTabHelper : public favicon::ContentFaviconDriver { public: - ~FaviconTabHelper() override; - static void CreateForWebContents(content::WebContents* web_contents); - // Initiates loading the favicon for the specified url. - void FetchFavicon(const GURL& url); - - // Returns the favicon for this tab, or IDR_DEFAULT_FAVICON if the tab does - // not have a favicon. The default implementation uses the current navigation - // entry. This will return an empty bitmap if there are no navigation - // entries, which should rarely happen. - gfx::Image GetFavicon() const; - - // Returns true if we have the favicon for the page. - bool FaviconIsValid() const; + // TODO(sdefresne): remove this method once all clients have been ported to + // use ContentFaviconDriver::FromWebContents() instead. + static FaviconTabHelper* FromWebContents(content::WebContents* web_contents); // Returns whether the favicon should be displayed. If this returns false, no // space is provided for the favicon, and the favicon is never displayed. - bool ShouldDisplayFavicon(); - - // Returns the current tab's favicon urls. If this is empty, - // DidUpdateFaviconURL has not yet been called for the current navigation. - const std::vector<content::FaviconURL>& favicon_urls() const { - return favicon_urls_; - } - - // content::WebContentsObserver override. Must be public, because also - // called from PrerenderContents. - void DidUpdateFaviconURL( - const std::vector<content::FaviconURL>& candidates) override; - - // Saves the favicon for the current page. - void SaveFavicon(); - - void AddObserver(favicon::FaviconDriverObserver* observer); - void RemoveObserver(favicon::FaviconDriverObserver* observer); - - // favicon::FaviconDriver methods. - int StartDownload(const GURL& url, int max_bitmap_size) override; - bool IsOffTheRecord() override; - bool IsBookmarked(const GURL& url) override; - GURL GetActiveURL() override; - base::string16 GetActiveTitle() override; - bool GetActiveFaviconValidity() override; - void SetActiveFaviconValidity(bool valid) override; - GURL GetActiveFaviconURL() override; - void SetActiveFaviconURL(const GURL& url) override; - gfx::Image GetActiveFaviconImage() override; - void SetActiveFaviconImage(const gfx::Image& image) override; - void OnFaviconAvailable(const gfx::Image& image, - const GURL& url, - bool is_active_favicon) override; - void NotifyFaviconUpdated(bool icon_url_changed) override; - - // Favicon download callback. - void DidDownloadFavicon( - int id, - int http_status_code, - const GURL& image_url, - const std::vector<SkBitmap>& bitmaps, - const std::vector<gfx::Size>& original_bitmap_sizes); + static bool ShouldDisplayFavicon(content::WebContents* web_contents); private: - friend class content::WebContentsUserData<FaviconTabHelper>; friend class FaviconTabHelperTest; // Creates a new FaviconTabHelper bound to |web_contents|. Initialize @@ -124,37 +32,6 @@ class FaviconTabHelper : public content::WebContentsObserver, history::HistoryService* history_service, bookmarks::BookmarkModel* bookmark_model); - // content::WebContentsObserver overrides. - void DidStartNavigationToPendingEntry( - const GURL& url, - content::NavigationController::ReloadType reload_type) override; - void DidNavigateMainFrame( - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) override; - - // Helper method that returns the active navigation entry's favicon. - content::FaviconStatus& GetFaviconStatus(); - - // KeyedService used by FaviconTabHelper. They may be null during testing, but - // if they are defined, they must outlive the FaviconTabHelper. - favicon::FaviconService* favicon_service_; - history::HistoryService* history_service_; - bookmarks::BookmarkModel* bookmark_model_; - - std::vector<content::FaviconURL> favicon_urls_; - - // Bypass cache when downloading favicons for this page URL. - GURL bypass_cache_page_url_; - - // FaviconHandlers used to download the different kind of favicons. Both - // |touch_icon_handler_| and |large_icon_handler_| may be null depending - // on the platform or variations. - scoped_ptr<favicon::FaviconHandler> favicon_handler_; - scoped_ptr<favicon::FaviconHandler> touch_icon_handler_; - scoped_ptr<favicon::FaviconHandler> large_icon_handler_; - - ObserverList<favicon::FaviconDriverObserver> observer_list_; - DISALLOW_COPY_AND_ASSIGN(FaviconTabHelper); }; diff --git a/chrome/browser/favicon/favicon_tab_helper_browsertest.cc b/chrome/browser/favicon/favicon_tab_helper_browsertest.cc index 8722b5b..567d825 100644 --- a/chrome/browser/favicon/favicon_tab_helper_browsertest.cc +++ b/chrome/browser/favicon/favicon_tab_helper_browsertest.cc @@ -187,11 +187,8 @@ class FaviconTabHelperTest : public InProcessBrowserTest, // FaviconTabHelperPendingTaskChecker: bool HasPendingTasks() override { - favicon::FaviconHandler* favicon_handler = - FaviconTabHelper::FromWebContents(web_contents()) - ->favicon_handler_.get(); - return !favicon_handler->download_requests_.empty() || - favicon_handler->cancelable_task_tracker_.HasTrackedTasks(); + return FaviconTabHelper::FromWebContents(web_contents()) + ->HasPendingTasksForTest(); } private: diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm index c13b362..8dde6a25 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm @@ -1554,10 +1554,8 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) { NSInteger index = [self indexFromModelIndex:modelIndex]; TabController* tabController = [tabArray_ objectAtIndex:index]; - FaviconTabHelper* favicon_tab_helper = - FaviconTabHelper::FromWebContents(contents); bool oldHasIcon = [tabController iconView] != nil; - bool newHasIcon = favicon_tab_helper->ShouldDisplayFavicon() || + bool newHasIcon = FaviconTabHelper::ShouldDisplayFavicon(contents) || tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. TabLoadingState oldState = [tabController loadingState]; diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc index ee646d4..23a17e9 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc @@ -509,7 +509,8 @@ void BrowserTabStripController::SetTabRendererDataFromModel( data->crashed_status = contents->GetCrashedStatus(); data->incognito = contents->GetBrowserContext()->IsOffTheRecord(); data->mini = model_->IsMiniTab(model_index); - data->show_icon = data->mini || favicon_tab_helper->ShouldDisplayFavicon(); + data->show_icon = + data->mini || FaviconTabHelper::ShouldDisplayFavicon(contents); data->blocked = model_->IsTabBlocked(model_index); data->app = extensions::TabHelper::FromWebContents(contents)->is_app(); data->media_state = chrome::GetTabMediaStateForContents(contents); |