diff options
author | pkotwicz <pkotwicz@chromium.org> | 2015-11-23 09:35:46 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-23 17:36:41 +0000 |
commit | 7e8e893275dd310e13ae77de88ebec260d61994a (patch) | |
tree | 46e89ba9c6429e06e4bd86ca5934b5188f175152 | |
parent | e102ab8c09f75131bd87d86830078219a0f94b0b (diff) | |
download | chromium_src-7e8e893275dd310e13ae77de88ebec260d61994a.zip chromium_src-7e8e893275dd310e13ae77de88ebec260d61994a.tar.gz chromium_src-7e8e893275dd310e13ae77de88ebec260d61994a.tar.bz2 |
Refactor FaviconDriver::OnFaviconAvailable()
This CL:
- Removes weird OnFaviconAvailable() behavior if gfx::Image is empty.
- Merges: FaviconDriver::SetActiveFaviconValidity()
FaviconDriver::SetActiveFaviconURL()
FaviconDriver::SetActiveFaviconImage()
- Merges FaviconDriverObserver::OnFaviconAvailable() and
FaviconDriverObserver::OnFaviconUpdated().
BUG=542057
Review URL: https://codereview.chromium.org/1407353012
Cr-Commit-Position: refs/heads/master@{#361132}
21 files changed, 325 insertions, 454 deletions
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc index 2d0e15b..ab262c6 100644 --- a/chrome/browser/android/tab_android.cc +++ b/chrome/browser/android/tab_android.cc @@ -388,7 +388,16 @@ void TabAndroid::Observe(int type, } } -void TabAndroid::OnFaviconAvailable(const gfx::Image& image) { +void TabAndroid::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) { + if (notification_icon_type != NON_TOUCH_LARGEST && + notification_icon_type != TOUCH_LARGEST) { + return; + } + SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).sk_bitmap(); if (favicon.empty()) return; @@ -398,10 +407,6 @@ void TabAndroid::OnFaviconAvailable(const gfx::Image& image) { gfx::ConvertToJavaBitmap(&favicon).obj()); } -void TabAndroid::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) { -} - void TabAndroid::Destroy(JNIEnv* env, jobject obj) { delete this; } diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h index ccf65d0..c54c647 100644 --- a/chrome/browser/android/tab_android.h +++ b/chrome/browser/android/tab_android.h @@ -149,9 +149,11 @@ class TabAndroid : public CoreTabHelperDelegate, const content::NotificationDetails& details) override; // Overridden from favicon::FaviconDriverObserver: - void OnFaviconAvailable(const gfx::Image& image) override; void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) override; + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override; // Methods called from Java via JNI ----------------------------------------- diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc index 5cc840f..dfa812b 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc @@ -546,12 +546,13 @@ void TabsEventRouter::OnZoomChanged( EventRouter::USER_GESTURE_UNKNOWN); } -void TabsEventRouter::OnFaviconAvailable(const gfx::Image& image) { -} - -void TabsEventRouter::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) { - if (icon_url_changed) { +void TabsEventRouter::OnFaviconUpdated( + favicon::FaviconDriver* favicon_driver, + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) { + if (notification_icon_type == NON_TOUCH_16_DIP && icon_url_changed) { favicon::ContentFaviconDriver* content_favicon_driver = static_cast<favicon::ContentFaviconDriver*>(favicon_driver); FaviconUrlUpdated(content_favicon_driver->web_contents()); diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.h b/chrome/browser/extensions/api/tabs/tabs_event_router.h index e285b31..c78463d 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.h +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.h @@ -81,9 +81,11 @@ class TabsEventRouter : public TabStripModelObserver, const ui_zoom::ZoomController::ZoomChangedEventData& data) override; // favicon::FaviconDriverObserver: - void OnFaviconAvailable(const gfx::Image& image) override; void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) override; + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override; private: // "Synthetic" event. Called from TabInsertedAt if new tab is detected. diff --git a/chrome/browser/favicon/content_favicon_driver_browsertest.cc b/chrome/browser/favicon/content_favicon_driver_browsertest.cc index 9c9767b..0807918 100644 --- a/chrome/browser/favicon/content_favicon_driver_browsertest.cc +++ b/chrome/browser/favicon/content_favicon_driver_browsertest.cc @@ -142,9 +142,11 @@ class PendingTaskWaiter : public content::NotificationObserver, } // favicon::Favicon - void OnFaviconAvailable(const gfx::Image& image) override {} void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) override { + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override { OnNotification(); } diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 19fdb15..c736cc6 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc @@ -167,9 +167,11 @@ class FaviconUpdateWatcher : public favicon::FaviconDriverObserver { } private: - void OnFaviconAvailable(const gfx::Image& image) override {} void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) override { + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override { seen_ = true; if (!running_) return; diff --git a/chrome/browser/task_management/providers/web_contents/renderer_task.cc b/chrome/browser/task_management/providers/web_contents/renderer_task.cc index ca30ac7..6b48475 100644 --- a/chrome/browser/task_management/providers/web_contents/renderer_task.cc +++ b/chrome/browser/task_management/providers/web_contents/renderer_task.cc @@ -146,12 +146,13 @@ blink::WebCache::ResourceTypeStats RendererTask::GetWebCacheStats() const { return webcache_stats_; } -void RendererTask::OnFaviconAvailable(const gfx::Image& image) { -} - void RendererTask::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) { - UpdateFavicon(); + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) { + if (notification_icon_type == NON_TOUCH_16_DIP) + UpdateFavicon(); } // static diff --git a/chrome/browser/task_management/providers/web_contents/renderer_task.h b/chrome/browser/task_management/providers/web_contents/renderer_task.h index 3ab9fae..d28770a 100644 --- a/chrome/browser/task_management/providers/web_contents/renderer_task.h +++ b/chrome/browser/task_management/providers/web_contents/renderer_task.h @@ -53,9 +53,11 @@ class RendererTask : public Task, blink::WebCache::ResourceTypeStats GetWebCacheStats() const override; // favicon::FaviconDriverObserver: - void OnFaviconAvailable(const gfx::Image& image) override; - void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - bool icon_url_changed) override; + void OnFaviconUpdated(favicon::FaviconDriver* driver, + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override; protected: // Returns the title of the given |web_contents|. diff --git a/chrome/browser/task_management/providers/web_contents/tab_contents_tag_browsertest.cc b/chrome/browser/task_management/providers/web_contents/tab_contents_tag_browsertest.cc index 796b2a6..7dfa845 100644 --- a/chrome/browser/task_management/providers/web_contents/tab_contents_tag_browsertest.cc +++ b/chrome/browser/task_management/providers/web_contents/tab_contents_tag_browsertest.cc @@ -15,6 +15,8 @@ #include "components/favicon/content/content_favicon_driver.h" #include "components/favicon/core/favicon_driver.h" #include "components/favicon/core/favicon_driver_observer.h" +#include "content/public/browser/favicon_status.h" +#include "content/public/browser/navigation_entry.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/page_transition_types.h" @@ -72,7 +74,7 @@ class FaviconWaiter : public favicon::FaviconDriverObserver { } void WaitForFaviconWithURL(const GURL& url) { - if (driver_->GetActiveFaviconURL() == url) { + if (GetCurrentFaviconURL() == url) { driver_->RemoveObserver(this); return; } @@ -84,11 +86,20 @@ class FaviconWaiter : public favicon::FaviconDriverObserver { } private: - void OnFaviconAvailable(const gfx::Image& image) override {} + GURL GetCurrentFaviconURL() { + const content::NavigationController& controller = + driver_->web_contents()->GetController(); + content::NavigationEntry* entry = controller.GetLastCommittedEntry(); + return entry ? entry->GetFavicon().url : GURL(); + } - void OnFaviconUpdated(favicon::FaviconDriver* driver, - bool icon_url_changed) override { - if (driver_->GetActiveFaviconURL() == target_favicon_url_) { + void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override { + if (notification_icon_type == NON_TOUCH_16_DIP && + icon_url == target_favicon_url_) { driver_->RemoveObserver(this); if (!quit_closure_.is_null()) diff --git a/components/favicon/content/content_favicon_driver.cc b/components/favicon/content/content_favicon_driver.cc index 8cf9066..3ce6942 100644 --- a/components/favicon/content/content_favicon_driver.cc +++ b/components/favicon/content/content_favicon_driver.cc @@ -113,27 +113,6 @@ GURL ContentFaviconDriver::GetActiveURL() { return entry ? entry->GetURL() : GURL(); } -void ContentFaviconDriver::SetActiveFaviconValidity(bool valid) { - GetFaviconStatus().valid = valid; -} - -GURL ContentFaviconDriver::GetActiveFaviconURL() { - return GetFaviconStatus().url; -} - -void ContentFaviconDriver::SetActiveFaviconURL(const GURL& url) { - GetFaviconStatus().url = url; -} - -void ContentFaviconDriver::SetActiveFaviconImage(const gfx::Image& image) { - GetFaviconStatus().image = image; -} - -content::FaviconStatus& ContentFaviconDriver::GetFaviconStatus() { - DCHECK(web_contents()->GetController().GetLastCommittedEntry()); - return web_contents()->GetController().GetLastCommittedEntry()->GetFavicon(); -} - ContentFaviconDriver::ContentFaviconDriver( content::WebContents* web_contents, FaviconService* favicon_service, @@ -146,9 +125,25 @@ ContentFaviconDriver::ContentFaviconDriver( ContentFaviconDriver::~ContentFaviconDriver() { } -void ContentFaviconDriver::NotifyFaviconUpdated(bool icon_url_changed) { - FaviconDriverImpl::NotifyFaviconUpdated(icon_url_changed); - web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); +void ContentFaviconDriver::OnFaviconUpdated( + const GURL& page_url, + FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) { + content::NavigationEntry* entry = + web_contents()->GetController().GetLastCommittedEntry(); + DCHECK(entry && entry->GetURL() == page_url); + + if (notification_icon_type == FaviconDriverObserver::NON_TOUCH_16_DIP) { + entry->GetFavicon().valid = true; + entry->GetFavicon().url = icon_url; + entry->GetFavicon().image = image; + web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); + } + + NotifyFaviconUpdatedObservers(notification_icon_type, icon_url, + icon_url_changed, image); } void ContentFaviconDriver::DidUpdateFaviconURL( diff --git a/components/favicon/content/content_favicon_driver.h b/components/favicon/content/content_favicon_driver.h index 1af8bb1..305f51a 100644 --- a/components/favicon/content/content_favicon_driver.h +++ b/components/favicon/content/content_favicon_driver.h @@ -47,10 +47,6 @@ class ContentFaviconDriver int StartDownload(const GURL& url, int max_bitmap_size) override; bool IsOffTheRecord() override; GURL GetActiveURL() override; - void SetActiveFaviconValidity(bool valid) override; - GURL GetActiveFaviconURL() override; - void SetActiveFaviconURL(const GURL& url) override; - void SetActiveFaviconImage(const gfx::Image& image) override; protected: ContentFaviconDriver(content::WebContents* web_contents, @@ -63,7 +59,12 @@ class ContentFaviconDriver friend class content::WebContentsUserData<ContentFaviconDriver>; // FaviconDriver implementation. - void NotifyFaviconUpdated(bool icon_url_changed) override; + void OnFaviconUpdated( + const GURL& page_url, + FaviconDriverObserver::NotificationIconType icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override; // content::WebContentsObserver implementation. void DidUpdateFaviconURL( @@ -75,9 +76,6 @@ class ContentFaviconDriver const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) override; - // Returns the active navigation entry's favicon. - content::FaviconStatus& GetFaviconStatus(); - GURL bypass_cache_page_url_; std::vector<content::FaviconURL> favicon_urls_; diff --git a/components/favicon/core/favicon_driver.cc b/components/favicon/core/favicon_driver.cc index 0063229..e94034e 100644 --- a/components/favicon/core/favicon_driver.cc +++ b/components/favicon/core/favicon_driver.cc @@ -4,8 +4,6 @@ #include "components/favicon/core/favicon_driver.h" -#include "components/favicon/core/favicon_driver_observer.h" - namespace favicon { void FaviconDriver::AddObserver(FaviconDriverObserver* observer) { @@ -22,14 +20,14 @@ FaviconDriver::FaviconDriver() { FaviconDriver::~FaviconDriver() { } -void FaviconDriver::NotifyFaviconAvailable(const gfx::Image& image) { - FOR_EACH_OBSERVER(FaviconDriverObserver, observer_list_, - OnFaviconAvailable(image)); -} - -void FaviconDriver::NotifyFaviconUpdated(bool icon_url_changed) { +void FaviconDriver::NotifyFaviconUpdatedObservers( + FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) { FOR_EACH_OBSERVER(FaviconDriverObserver, observer_list_, - OnFaviconUpdated(this, icon_url_changed)); + OnFaviconUpdated(this, notification_icon_type, icon_url, + icon_url_changed, image)); } } // namespace favicon diff --git a/components/favicon/core/favicon_driver.h b/components/favicon/core/favicon_driver.h index 0c2747e..4cceb5a 100644 --- a/components/favicon/core/favicon_driver.h +++ b/components/favicon/core/favicon_driver.h @@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/observer_list.h" #include "base/strings/string16.h" +#include "components/favicon/core/favicon_driver_observer.h" class GURL; @@ -17,8 +18,6 @@ class Image; namespace favicon { -class FaviconDriverObserver; - // Interface that allows favicon core code to obtain information about the // current page. This is partially implemented by FaviconDriverImpl, and // concrete implementation should be based on that class instead of directly @@ -61,27 +60,14 @@ class FaviconDriver { // otherwise. virtual GURL GetActiveURL() = 0; - // Sets whether the page's favicon is valid (if false, the default favicon is - // being used). - virtual void SetActiveFaviconValidity(bool valid) = 0; - - // Returns the URL of the current page's favicon. - virtual GURL GetActiveFaviconURL() = 0; - - // Sets the URL of the favicon's bitmap. - virtual void SetActiveFaviconURL(const GURL& url) = 0; - - // Sets the bitmap of the current page's favicon. - virtual void SetActiveFaviconImage(const gfx::Image& image) = 0; - - // Notifies the driver a favicon image is available. |image| is not - // necessarily 16x16. |icon_url| is the url the image is from. If - // |is_active_favicon| is true the image corresponds to the favicon - // (possibly empty) of the page. - virtual void OnFaviconAvailable(const GURL& page_url, - const GURL& icon_url, - const gfx::Image& image, - bool is_active_favicon) = 0; + // Notifies the driver that the favicon image has been updated. + // See comment for FaviconDriverObserver::OnFaviconUpdated() for more details. + virtual void OnFaviconUpdated( + const GURL& page_url, + FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) = 0; // Returns whether the driver is waiting for a download to complete or for // data from the FaviconService. Reserved for testing. @@ -91,14 +77,13 @@ class FaviconDriver { FaviconDriver(); virtual ~FaviconDriver(); - // Informs FaviconDriverObservers that favicon |image| has been retrieved from - // either website or cached storage. - void NotifyFaviconAvailable(const gfx::Image& image); + // Notifies FaviconDriverObservers that the favicon image has been updated. + void NotifyFaviconUpdatedObservers( + FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image); - // Informs FaviconDriverObservers that favicon has changed for the current - // page. |icon_url_changed| is true if the favicon URL has also changed since - // the last call. - virtual void NotifyFaviconUpdated(bool icon_url_changed); private: base::ObserverList<FaviconDriverObserver> observer_list_; diff --git a/components/favicon/core/favicon_driver_impl.cc b/components/favicon/core/favicon_driver_impl.cc index dca52df..2da8f46 100644 --- a/components/favicon/core/favicon_driver_impl.cc +++ b/components/favicon/core/favicon_driver_impl.cc @@ -48,11 +48,12 @@ FaviconDriverImpl::FaviconDriverImpl(FaviconService* favicon_service, history_service_(history_service), bookmark_model_(bookmark_model) { favicon_handler_.reset(new FaviconHandler( - favicon_service_, this, kEnableTouchIcon ? FaviconHandler::LARGEST_FAVICON - : FaviconHandler::FAVICON)); + favicon_service_, this, kEnableTouchIcon + ? FaviconDriverObserver::NON_TOUCH_LARGEST + : FaviconDriverObserver::NON_TOUCH_16_DIP)); if (kEnableTouchIcon || IsIconNTPEnabled()) { touch_icon_handler_.reset(new FaviconHandler( - favicon_service_, this, FaviconHandler::LARGEST_TOUCH)); + favicon_service_, this, FaviconDriverObserver::TOUCH_LARGEST)); } } @@ -89,33 +90,6 @@ bool FaviconDriverImpl::IsBookmarked(const GURL& url) { return bookmark_model_ && bookmark_model_->IsBookmarked(url); } -void FaviconDriverImpl::OnFaviconAvailable(const GURL& page_url, - const GURL& icon_url, - const gfx::Image& image, - bool is_active_favicon) { - // Check whether the active URL has changed since FetchFavicon() was called. - // On iOS only, the active URL can change between calls to FetchFavicon(). - // For instance, FetchFavicon() is not synchronously called when the active - // URL changes as a result of CRWSessionController::goToEntry(). - if (page_url != GetActiveURL()) - return; - - 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()) - NotifyFaviconAvailable(image); -} - bool FaviconDriverImpl::HasPendingTasksForTest() { if (favicon_handler_->HasPendingTasksForTest()) return true; diff --git a/components/favicon/core/favicon_driver_impl.h b/components/favicon/core/favicon_driver_impl.h index f1ef6a1..54e8d3a 100644 --- a/components/favicon/core/favicon_driver_impl.h +++ b/components/favicon/core/favicon_driver_impl.h @@ -53,10 +53,6 @@ class FaviconDriverImpl : public FaviconDriver { // FaviconDriver implementation. void FetchFavicon(const GURL& url) override; bool IsBookmarked(const GURL& url) override; - void OnFaviconAvailable(const GURL& page_url, - const GURL& icon_url, - const gfx::Image& image, - bool is_active_favicon) override; bool HasPendingTasksForTest() override; protected: diff --git a/components/favicon/core/favicon_driver_observer.h b/components/favicon/core/favicon_driver_observer.h index eb3fd48..ce80877 100644 --- a/components/favicon/core/favicon_driver_observer.h +++ b/components/favicon/core/favicon_driver_observer.h @@ -11,6 +11,8 @@ namespace gfx { class Image; } +class GURL; + namespace favicon { class FaviconDriver; @@ -19,17 +21,47 @@ class FaviconDriver; // FaviconDriver. class FaviconDriverObserver { public: + // The type of the icon in the OnFaviconUpdated() notification. + enum NotificationIconType { + // Multi-resolution 16x16 (gfx::kFaviconSize) device independant pixel + // favicon of type favicon_base::FAVICON. If the page does not provide a + // 16x16 DIP icon, the icon is generated by resizing another icon. + NON_TOUCH_16_DIP, + // Largest icon specified by the page which is of type + // favicon_base::FAVICON. + NON_TOUCH_LARGEST, + // Largest icon specified by the page which is of type + // favicon_base::TOUCH_ICON or of type favicon_base::TOUCH_PRECOMPOSED_ICON. + TOUCH_LARGEST + }; + FaviconDriverObserver() {} virtual ~FaviconDriverObserver() {} - // Called when favicon |image| is retrieved from either web site or cached - // storage. - virtual void OnFaviconAvailable(const gfx::Image& image) = 0; - - // Called when favicon has changed for the current page. |icon_url_changed| is - // true if the favicon URL has also changed. + // Called when either: + // 1) Chrome determines the best icon for the page for + // |notification_icon_type|. + // Not called if the site does not provide a custom icon and the best icon + // for the page is the default one provided by Chrome. + // 2) The site changes its icon via Javascript. + // |icon_url_changed| is false if OnFaviconAvailable() was already called for + // |notification_icon_type| for the current page URL and |icon_url| is the + // same as for the previous notification for |notification_icon_type|. + // Example: + // Page: www.google.com + // Icon: www.google.com/favicon.ico + // Data for www.google.com/favicon.ico in the database has expired. + // i) OnFaviconUpdated() is called with |icon_url_changed| == true to notify + // that a favicon was found in the history database. + // ii) As the history data has expired, the icon at www.google.com/favicon.ico + // is redownloaded and stored into the database. OnFaviconUpdated() is + // called with |icon_url_changed| == false to notify that the icon in the + // history database MAY have changed visually. virtual void OnFaviconUpdated(FaviconDriver* favicon_driver, - bool icon_url_changed) = 0; + NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) = 0; private: DISALLOW_COPY_AND_ASSIGN(FaviconDriverObserver); diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc index 1207a495..bb33137 100644 --- a/components/favicon/core/favicon_handler.cc +++ b/components/favicon/core/favicon_handler.cc @@ -210,15 +210,18 @@ FaviconHandler::FaviconCandidate::FaviconCandidate( //////////////////////////////////////////////////////////////////////////////// -FaviconHandler::FaviconHandler(FaviconService* service, - FaviconDriver* driver, - Type handler_type) - : got_favicon_from_history_(false), +FaviconHandler::FaviconHandler( + FaviconService* service, + FaviconDriver* driver, + FaviconDriverObserver::NotificationIconType handler_type) + : handler_type_(handler_type), + got_favicon_from_history_(false), initial_history_result_expired_or_incomplete_(false), redownload_icons_(false), icon_types_(FaviconHandler::GetIconTypesFromHandlerType(handler_type)), - download_largest_icon_(handler_type == LARGEST_FAVICON || - handler_type == LARGEST_TOUCH), + download_largest_icon_( + handler_type == FaviconDriverObserver::NON_TOUCH_LARGEST || + handler_type == FaviconDriverObserver::TOUCH_LARGEST), notification_icon_type_(favicon_base::INVALID_ICON), service_(service), driver_(driver), @@ -231,12 +234,12 @@ FaviconHandler::~FaviconHandler() { // static int FaviconHandler::GetIconTypesFromHandlerType( - FaviconHandler::Type handler_type) { + FaviconDriverObserver::NotificationIconType handler_type) { switch (handler_type) { - case FAVICON: - case LARGEST_FAVICON: + case FaviconDriverObserver::NON_TOUCH_16_DIP: + case FaviconDriverObserver::NON_TOUCH_LARGEST: return favicon_base::FAVICON; - case LARGEST_TOUCH: + case FaviconDriverObserver::TOUCH_LARGEST: return favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON; } return 0; @@ -320,10 +323,10 @@ void FaviconHandler::SetFavicon(const GURL& icon_url, if (ShouldSaveFavicon()) SetHistoryFavicons(url_, icon_url, icon_type, image); - NotifyFaviconAvailable(icon_url, icon_type, image); + NotifyFaviconUpdated(icon_url, icon_type, image); } -void FaviconHandler::NotifyFaviconAvailable( +void FaviconHandler::NotifyFaviconUpdated( const std::vector<favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { if (favicon_bitmap_results.empty()) @@ -338,19 +341,21 @@ void FaviconHandler::NotifyFaviconAvailable( // from. const GURL icon_url = favicon_bitmap_results[0].icon_url; favicon_base::IconType icon_type = favicon_bitmap_results[0].icon_type; - NotifyFaviconAvailable(icon_url, icon_type, resized_image); + NotifyFaviconUpdated(icon_url, icon_type, resized_image); } -void FaviconHandler::NotifyFaviconAvailable(const GURL& icon_url, - favicon_base::IconType icon_type, - const gfx::Image& image) { +void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url, + favicon_base::IconType icon_type, + const gfx::Image& image) { + if (image.IsEmpty()) + return; + gfx::Image image_with_adjusted_colorspace = image; favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); - bool is_active_favicon = !download_largest_icon_; - - driver_->OnFaviconAvailable( - url_, icon_url, image_with_adjusted_colorspace, is_active_favicon); + driver_->OnFaviconUpdated(url_, handler_type_, icon_url, + icon_url != notification_icon_url_, + image_with_adjusted_colorspace); notification_icon_url_ = icon_url; notification_icon_type_ = icon_type; @@ -589,8 +594,7 @@ void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( // doesn't have an icon. Set the favicon now, and if the favicon turns out // to be expired (or the wrong url) we'll fetch later on. This way the // user doesn't see a flash of the default favicon. - - NotifyFaviconAvailable(favicon_bitmap_results); + NotifyFaviconUpdated(favicon_bitmap_results); } if (current_candidate()) @@ -640,7 +644,7 @@ void FaviconHandler::OnFaviconData(const std::vector< // the observers even if the favicon is expired or incomplete (incorrect // size) because temporarily showing the user an expired favicon or // streched favicon is preferable to showing the user the default favicon. - NotifyFaviconAvailable(favicon_bitmap_results); + NotifyFaviconUpdated(favicon_bitmap_results); } if (!current_candidate() || diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h index a65d19b..b423919 100644 --- a/components/favicon/core/favicon_handler.h +++ b/components/favicon/core/favicon_handler.h @@ -12,6 +12,7 @@ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/task/cancelable_task_tracker.h" +#include "components/favicon/core/favicon_driver_observer.h" #include "components/favicon/core/favicon_url.h" #include "components/favicon_base/favicon_callback.h" #include "ui/gfx/favicon_size.h" @@ -78,29 +79,14 @@ class TestFaviconHandler; class FaviconHandler { public: - enum Type { - // Selects the icon URL of type favicon_base::FAVICON with bitmaps whose - // edge sizes most closely match "16 * favicon_base::GetFaviconScales()". - // When favicon_base::GetFaviconScales() returns multiple scales, the ideal - // match is a .ico file. - FAVICON, - - // Selects the icon URL of type favicon_base::FAVICON with the largest - // bitmap. - LARGEST_FAVICON, - - // Selects the icon URL of type favicon_base::TOUCH_ICON or - // favicon_base::TOUCH_PRECOMPOSED_ICON with the largest bitmap. - LARGEST_TOUCH - }; - FaviconHandler(FaviconService* service, FaviconDriver* driver, - Type handler_type); + FaviconDriverObserver::NotificationIconType handler_type); virtual ~FaviconHandler(); // Returns the bit mask of favicon_base::IconType based on the handler's type. - static int GetIconTypesFromHandlerType(Type icon_type); + static int GetIconTypesFromHandlerType( + FaviconDriverObserver::NotificationIconType handler_type); // Initiates loading the favicon for the specified url. void FetchFavicon(const GURL& url); @@ -234,14 +220,17 @@ class FaviconHandler { const gfx::Image& image, favicon_base::IconType icon_type); - // Notifies |driver_| favicon available. See - // FaviconDriver::NotifyFaviconAvailable() for |is_active_favicon| in detail. - void NotifyFaviconAvailable( + // Notifies |driver_| that FaviconHandler found an icon which matches the + // |handler_type_| criteria. NotifyFaviconUpdated() can be called multiple + // times for the same page if: + // - a better match is found for |handler_type_| (e.g. newer bitmap data) + // - Javascript changes the page's icon URLs. + void NotifyFaviconUpdated( const std::vector<favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results); - void NotifyFaviconAvailable(const GURL& icon_url, - favicon_base::IconType icon_type, - const gfx::Image& image); + void NotifyFaviconUpdated(const GURL& icon_url, + favicon_base::IconType icon_type, + const gfx::Image& image); // Return the current candidate if any. favicon::FaviconURL* current_candidate() { @@ -259,6 +248,8 @@ class FaviconHandler { // Used for FaviconService requests. base::CancelableTaskTracker cancelable_task_tracker_; + FaviconDriverObserver::NotificationIconType handler_type_; + // URL of the page we're requesting the favicon for. GURL url_; diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc index ddd7159..b0cb87c 100644 --- a/components/favicon/core/favicon_handler_unittest.cc +++ b/components/favicon/core/favicon_handler_unittest.cc @@ -186,10 +186,7 @@ class HistoryRequestHandler { class TestFaviconDriver : public FaviconDriver { public: TestFaviconDriver() - : favicon_validity_(false), - num_active_favicon_(0), - num_favicon_available_(0), - update_active_favicon_(false) {} + : num_notifications_(0u) {} ~TestFaviconDriver() override {} @@ -227,70 +224,34 @@ class TestFaviconDriver : public FaviconDriver { bool IsBookmarked(const GURL& url) override { return false; } - GURL GetActiveURL() override { return url_; } - - bool GetActiveFaviconValidity() { return favicon_validity_; } - - void SetActiveFaviconValidity(bool favicon_validity) override { - favicon_validity_ = favicon_validity; - } - - GURL GetActiveFaviconURL() override { return favicon_url_; } - - void SetActiveFaviconURL(const GURL& favicon_url) override { - favicon_url_ = favicon_url; + GURL GetActiveURL() override { + ADD_FAILURE() << "TestFaviconDriver::GetActiveURL() " + << "should never be called in tests."; + return GURL(); } - gfx::Image GetActiveFaviconImage() { return image_; } - - void SetActiveFaviconImage(const gfx::Image& image) override { + void OnFaviconUpdated( + const GURL& page_url, + FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override { + ++num_notifications_; + icon_url_ = icon_url; image_ = image; } - void OnFaviconAvailable(const GURL& page_url, - const GURL& icon_url, - const gfx::Image& image, - bool update_active_favicon) override { - ++num_favicon_available_; - available_image_ = image; - available_icon_url_ = icon_url; - update_active_favicon_ = update_active_favicon; - if (!update_active_favicon) - return; - - ++num_active_favicon_; - SetActiveFaviconURL(icon_url); - SetActiveFaviconValidity(true); - SetActiveFaviconImage(image); - } - - 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; } - void ResetNumFaviconAvailable() { num_favicon_available_ = 0; } - - void SetActiveURL(GURL url) { url_ = url; } - - const gfx::Image& available_favicon() { return available_image_; } + const GURL& icon_url() const { return icon_url_; } - const GURL& available_icon_url() { return available_icon_url_; } + const gfx::Image& image() const { return image_; } - bool update_active_favicon() { return update_active_favicon_; } + size_t num_notifications() const { return num_notifications_; } + void ResetNumNotifications() { num_notifications_ = 0; } private: - GURL favicon_url_; - GURL url_; + GURL icon_url_; gfx::Image image_; - bool favicon_validity_; - - // The number of times that NotifyFaviconAvailable() has been called with - // |is_active_favicon| is true. - size_t num_active_favicon_; - // The number of times that NotifyFaviconAvailable() has been called. - size_t num_favicon_available_; - gfx::Image available_image_; - GURL available_icon_url_; - bool update_active_favicon_; + size_t num_notifications_; DISALLOW_COPY_AND_ASSIGN(TestFaviconDriver); }; @@ -304,12 +265,10 @@ class TestFaviconHandler : public FaviconHandler { return FaviconHandler::GetMaximalIconSize(icon_type); } - TestFaviconHandler(const GURL& page_url, - TestFaviconDriver* driver, - Type type) - : FaviconHandler(nullptr, driver, type), + TestFaviconHandler(TestFaviconDriver* driver, + FaviconDriverObserver::NotificationIconType handler_type) + : FaviconHandler(nullptr, driver, handler_type), download_id_(0) { - driver->SetActiveURL(page_url); download_handler_.reset(new DownloadHandler(this)); } @@ -469,6 +428,8 @@ class FaviconHandlerTest : public testing::Test { const GURL& page_url, const std::vector<FaviconURL>& candidate_icons, const int* candidate_icon_sizes) { + size_t old_num_notifications = favicon_driver->num_notifications(); + UpdateFaviconURL( favicon_driver, favicon_handler, page_url, candidate_icons); EXPECT_EQ(candidate_icons.size(), favicon_handler->image_urls().size()); @@ -487,7 +448,7 @@ class FaviconHandlerTest : public testing::Test { download_handler->Reset(); - if (favicon_driver->num_active_favicon()) + if (favicon_driver->num_notifications() > old_num_notifications) return; } } @@ -496,7 +457,7 @@ class FaviconHandlerTest : public testing::Test { TestFaviconHandler* favicon_handler, const GURL& page_url, const std::vector<FaviconURL>& candidate_icons) { - favicon_driver->ResetNumActiveFavicon(); + favicon_driver->ResetNumNotifications(); favicon_handler->FetchFavicon(page_url); favicon_handler->history_handler()->InvokeCallback(); @@ -528,7 +489,7 @@ TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { const GURL icon_url("http://www.google.com/favicon"); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON); + TestFaviconHandler helper(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); helper.FetchFavicon(page_url); HistoryRequestHandler* history_handler = helper.history_handler(); @@ -543,8 +504,8 @@ TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { // Send history response. history_handler->InvokeCallback(); // Verify FaviconHandler status - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); + EXPECT_EQ(1u, driver.num_notifications()); + EXPECT_EQ(icon_url, driver.icon_url()); // Simulates update favicon url. std::vector<FaviconURL> urls; @@ -567,7 +528,7 @@ TEST_F(FaviconHandlerTest, DownloadFavicon) { const GURL icon_url("http://www.google.com/favicon"); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON); + TestFaviconHandler helper(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); helper.FetchFavicon(page_url); HistoryRequestHandler* history_handler = helper.history_handler(); @@ -585,8 +546,8 @@ TEST_F(FaviconHandlerTest, DownloadFavicon) { // Send history response. history_handler->InvokeCallback(); // Verify FaviconHandler status - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); + EXPECT_EQ(1u, driver.num_notifications()); + EXPECT_EQ(icon_url, driver.icon_url()); // Simulates update favicon url. std::vector<FaviconURL> urls; @@ -622,10 +583,10 @@ TEST_F(FaviconHandlerTest, DownloadFavicon) { EXPECT_EQ(page_url, history_handler->page_url_); // Verify NavigationEntry. - EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty()); - EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width()); + EXPECT_EQ(2u, driver.num_notifications()); + EXPECT_EQ(icon_url, driver.icon_url()); + EXPECT_FALSE(driver.image().IsEmpty()); + EXPECT_EQ(gfx::kFaviconSize, driver.image().Width()); } TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) { @@ -634,7 +595,7 @@ TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) { const GURL new_icon_url("http://www.google.com/new_favicon"); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON); + TestFaviconHandler helper(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); helper.FetchFavicon(page_url); HistoryRequestHandler* history_handler = helper.history_handler(); @@ -650,8 +611,8 @@ TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) { // Send history response. history_handler->InvokeCallback(); // Verify FaviconHandler status. - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); + EXPECT_EQ(1u, driver.num_notifications()); + EXPECT_EQ(icon_url, driver.icon_url()); // Reset the history_handler to verify whether new icon is requested from // history. @@ -702,10 +663,10 @@ TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) { EXPECT_EQ(page_url, history_handler->page_url_); // Verify NavigationEntry. - EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL()); - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty()); - EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width()); + EXPECT_EQ(2u, driver.num_notifications()); + EXPECT_EQ(new_icon_url, driver.icon_url()); + EXPECT_FALSE(driver.image().IsEmpty()); + EXPECT_EQ(gfx::kFaviconSize, driver.image().Width()); } TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { @@ -713,7 +674,7 @@ TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { const GURL icon_url("http://www.google.com/favicon"); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON); + TestFaviconHandler helper(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); helper.FetchFavicon(page_url); HistoryRequestHandler* history_handler = helper.history_handler(); @@ -737,8 +698,8 @@ TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { // Send history response. history_handler->InvokeCallback(); // The NavigationEntry should not be set yet as the history data is invalid. - EXPECT_FALSE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(GURL(), driver.GetActiveFaviconURL()); + EXPECT_EQ(0u, driver.num_notifications()); + EXPECT_EQ(GURL(), driver.icon_url()); // Reset the history_handler to verify whether new icon is requested from // history. @@ -771,10 +732,10 @@ TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { EXPECT_EQ(page_url, history_handler->page_url_); // Verify NavigationEntry. - EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty()); - EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width()); + EXPECT_EQ(1u, driver.num_notifications()); + EXPECT_EQ(icon_url, driver.icon_url()); + EXPECT_FALSE(driver.image().IsEmpty()); + EXPECT_EQ(gfx::kFaviconSize, driver.image().Width()); } TEST_F(FaviconHandlerTest, UpdateFavicon) { @@ -783,7 +744,7 @@ TEST_F(FaviconHandlerTest, UpdateFavicon) { const GURL new_icon_url("http://www.google.com/new_favicon"); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON); + TestFaviconHandler helper(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); helper.FetchFavicon(page_url); HistoryRequestHandler* history_handler = helper.history_handler(); @@ -798,8 +759,8 @@ TEST_F(FaviconHandlerTest, UpdateFavicon) { // Send history response. history_handler->InvokeCallback(); // Verify FaviconHandler status. - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); + EXPECT_EQ(1u, driver.num_notifications()); + EXPECT_EQ(icon_url, driver.icon_url()); // Reset the history_handler to verify whether new icon is requested from // history. @@ -832,9 +793,9 @@ TEST_F(FaviconHandlerTest, UpdateFavicon) { EXPECT_FALSE(helper.download_handler()->HasDownload()); // Verify the favicon status. - EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL()); - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty()); + EXPECT_EQ(2u, driver.num_notifications()); + EXPECT_EQ(new_icon_url, driver.icon_url()); + EXPECT_FALSE(driver.image().IsEmpty()); } TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) { @@ -843,7 +804,7 @@ TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) { const GURL new_icon_url("http://www.google.com/new_favicon"); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::LARGEST_TOUCH); + TestFaviconHandler helper(&driver, FaviconDriverObserver::TOUCH_LARGEST); std::set<GURL> fail_downloads; fail_downloads.insert(icon_url); helper.download_handler()->FailDownloadForIconURLs(fail_downloads); @@ -862,8 +823,8 @@ TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) { // Send history response. history_handler->InvokeCallback(); // Verify FaviconHandler status. - EXPECT_FALSE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(GURL(), driver.GetActiveFaviconURL()); + EXPECT_EQ(0u, driver.num_notifications()); + EXPECT_EQ(GURL(), driver.icon_url()); // Reset the history_handler to verify whether new icon is requested from // history. @@ -958,7 +919,7 @@ TEST_F(FaviconHandlerTest, UpdateDuringDownloading) { const GURL new_icon_url("http://www.google.com/new_favicon"); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::LARGEST_TOUCH); + TestFaviconHandler helper(&driver, FaviconDriverObserver::TOUCH_LARGEST); helper.FetchFavicon(page_url); HistoryRequestHandler* history_handler = helper.history_handler(); @@ -974,8 +935,8 @@ TEST_F(FaviconHandlerTest, UpdateDuringDownloading) { // Send history response. history_handler->InvokeCallback(); // Verify FaviconHandler status. - EXPECT_FALSE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(GURL(), driver.GetActiveFaviconURL()); + EXPECT_EQ(0u, driver.num_notifications()); + EXPECT_EQ(GURL(), driver.icon_url()); // Reset the history_handler to verify whether new icon is requested from // history. @@ -1080,7 +1041,7 @@ TEST_F(FaviconHandlerTest, UpdateSameIconURLs) { std::vector<gfx::Size>())); TestFaviconDriver driver; - TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON); + TestFaviconHandler helper(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); // Initiate a request for favicon data for |page_url|. History does not know // about the page URL or the icon URLs. @@ -1126,7 +1087,7 @@ TEST_F(FaviconHandlerTest, const GURL kIconURL2("http://wwww.page_which_animates_favicon.com/frame2.png"); TestFaviconDriver driver; - TestFaviconHandler helper(kPageURL, &driver, FaviconHandler::FAVICON); + TestFaviconHandler helper(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); // Initial state: // - The database does not know about |kPageURL|. @@ -1147,13 +1108,9 @@ TEST_F(FaviconHandlerTest, // FaviconHandler should request from history and download |kIconURL1| and // |kIconURL2|. |kIconURL1| is the better match. A - // FaviconDriver::OnFaviconAvailable() notification should be sent for + // FaviconDriver::OnFaviconUpdated() notification should be sent for // |kIconURL1|. - - // Clear the favicon validity so that we can use it to detect whether - // OnFaviconAvailable() is invoked. - driver.SetActiveFaviconValidity(false); - + ASSERT_EQ(0u, driver.num_notifications()); ASSERT_TRUE(helper.history_handler()); SetFaviconRawBitmapResult(kIconURL1, favicon_base::FAVICON, @@ -1179,8 +1136,8 @@ TEST_F(FaviconHandlerTest, helper.download_handler()->InvokeCallback(); helper.download_handler()->Reset(); - ASSERT_TRUE(driver.GetActiveFaviconValidity()); - ASSERT_EQ(kIconURL1, driver.GetActiveFaviconURL()); + ASSERT_LT(0u, driver.num_notifications()); + ASSERT_EQ(kIconURL1, driver.icon_url()); // Clear the history handler because SetHistoryFavicons() sets it. helper.set_history_handler(nullptr); @@ -1193,10 +1150,9 @@ TEST_F(FaviconHandlerTest, std::vector<gfx::Size>()))); // FaviconHandler should request from history and download |kIconURL2|. A - // FaviconDriver::OnFaviconAvailable() notification should be sent for + // FaviconDriver::OnFaviconUpdated() notification should be sent for // |kIconURL2|. - driver.SetActiveFaviconValidity(false); - + driver.ResetNumNotifications(); ASSERT_TRUE(helper.history_handler()); SetFaviconRawBitmapResult(kIconURL2, favicon_base::FAVICON, @@ -1207,8 +1163,8 @@ TEST_F(FaviconHandlerTest, ASSERT_TRUE(helper.download_handler()->HasDownload()); helper.download_handler()->InvokeCallback(); helper.download_handler()->Reset(); - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_EQ(kIconURL2, driver.GetActiveFaviconURL()); + ASSERT_LT(0u, driver.num_notifications()); + EXPECT_EQ(kIconURL2, driver.icon_url()); } // Test the favicon which is selected when the web page provides several @@ -1244,7 +1200,8 @@ TEST_F(FaviconHandlerTest, MultipleFavicons) { // 1) Test that if there are several single resolution favicons to choose from // that the largest exact match is chosen. TestFaviconDriver driver1; - TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON); + TestFaviconHandler handler1(&driver1, + FaviconDriverObserver::NON_TOUCH_16_DIP); const int kSizes1[] = { 16, 24, 32, 48, 256 }; std::vector<FaviconURL> urls1(kSourceIconURLs, @@ -1253,60 +1210,59 @@ TEST_F(FaviconHandlerTest, MultipleFavicons) { &driver1, &handler1, kPageURL, urls1, kSizes1); EXPECT_EQ(nullptr, handler1.current_candidate()); - EXPECT_TRUE(driver1.GetActiveFaviconValidity()); - EXPECT_FALSE(driver1.GetActiveFaviconImage().IsEmpty()); - EXPECT_EQ(gfx::kFaviconSize, driver1.GetActiveFaviconImage().Width()); + EXPECT_EQ(1u, driver1.num_notifications()); + EXPECT_FALSE(driver1.image().IsEmpty()); + EXPECT_EQ(gfx::kFaviconSize, driver1.image().Width()); size_t expected_index = 2u; EXPECT_EQ(32, kSizes1[expected_index]); - EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, - driver1.GetActiveFaviconURL()); + EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, driver1.icon_url()); // 2) Test that if there are several single resolution favicons to choose // from, the exact match is preferred even if it results in upsampling. TestFaviconDriver driver2; - TestFaviconHandler handler2(kPageURL, &driver2, FaviconHandler::FAVICON); + TestFaviconHandler handler2(&driver2, + FaviconDriverObserver::NON_TOUCH_16_DIP); const int kSizes2[] = { 16, 24, 48, 256 }; std::vector<FaviconURL> urls2(kSourceIconURLs, kSourceIconURLs + arraysize(kSizes2)); DownloadTillDoneIgnoringHistory( &driver2, &handler2, kPageURL, urls2, kSizes2); - EXPECT_TRUE(driver2.GetActiveFaviconValidity()); + EXPECT_EQ(1u, driver2.num_notifications()); expected_index = 0u; EXPECT_EQ(16, kSizes2[expected_index]); - EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, - driver2.GetActiveFaviconURL()); + EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, driver2.icon_url()); // 3) Test that favicons which need to be upsampled a little or downsampled // a little are preferred over huge favicons. TestFaviconDriver driver3; - TestFaviconHandler handler3(kPageURL, &driver3, FaviconHandler::FAVICON); + TestFaviconHandler handler3(&driver3, + FaviconDriverObserver::NON_TOUCH_16_DIP); const int kSizes3[] = { 256, 48 }; std::vector<FaviconURL> urls3(kSourceIconURLs, kSourceIconURLs + arraysize(kSizes3)); DownloadTillDoneIgnoringHistory( &driver3, &handler3, kPageURL, urls3, kSizes3); - EXPECT_TRUE(driver3.GetActiveFaviconValidity()); + EXPECT_EQ(1u, driver3.num_notifications()); expected_index = 1u; EXPECT_EQ(48, kSizes3[expected_index]); - EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, - driver3.GetActiveFaviconURL()); + EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, driver3.icon_url()); TestFaviconDriver driver4; - TestFaviconHandler handler4(kPageURL, &driver4, FaviconHandler::FAVICON); + TestFaviconHandler handler4(&driver4, + FaviconDriverObserver::NON_TOUCH_16_DIP); const int kSizes4[] = { 17, 256 }; std::vector<FaviconURL> urls4(kSourceIconURLs, kSourceIconURLs + arraysize(kSizes4)); DownloadTillDoneIgnoringHistory( &driver4, &handler4, kPageURL, urls4, kSizes4); - EXPECT_TRUE(driver4.GetActiveFaviconValidity()); + EXPECT_EQ(1u, driver4.num_notifications()); expected_index = 0u; EXPECT_EQ(17, kSizes4[expected_index]); - EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, - driver4.GetActiveFaviconURL()); + EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, driver4.icon_url()); } // Test that the best favicon is selected when: @@ -1329,7 +1285,7 @@ TEST_F(FaviconHandlerTest, MultipleFavicons404) { }; TestFaviconDriver driver; - TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON); + TestFaviconHandler handler(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); DownloadHandler* download_handler = handler.download_handler(); std::set<GURL> k404URLs; @@ -1353,12 +1309,11 @@ TEST_F(FaviconHandlerTest, MultipleFavicons404) { &driver, &handler, kPageURL, urls2, kSizes2); EXPECT_EQ(nullptr, handler.current_candidate()); - EXPECT_TRUE(driver.GetActiveFaviconValidity()); - EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty()); + EXPECT_EQ(1u, driver.num_notifications()); + EXPECT_FALSE(driver.image().IsEmpty()); int expected_index = 2u; EXPECT_EQ(16, kSizes2[expected_index]); - EXPECT_EQ(kFaviconURLs[expected_index].icon_url, - driver.GetActiveFaviconURL()); + EXPECT_EQ(kFaviconURLs[expected_index].icon_url, driver.icon_url()); } // Test that no favicon is selected when: @@ -1379,7 +1334,7 @@ TEST_F(FaviconHandlerTest, MultipleFaviconsAll404) { }; TestFaviconDriver driver; - TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON); + TestFaviconHandler handler(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); DownloadHandler* download_handler = handler.download_handler(); std::set<GURL> k404URLs; @@ -1405,8 +1360,8 @@ TEST_F(FaviconHandlerTest, MultipleFaviconsAll404) { DownloadTillDoneIgnoringHistory(&driver, &handler, kPageURL, urls, kSizes); EXPECT_EQ(nullptr, handler.current_candidate()); - EXPECT_FALSE(driver.GetActiveFaviconValidity()); - EXPECT_TRUE(driver.GetActiveFaviconImage().IsEmpty()); + EXPECT_EQ(0u, driver.num_notifications()); + EXPECT_TRUE(driver.image().IsEmpty()); } // Test that no favicon is selected when the page's only icon uses an invalid @@ -1420,7 +1375,7 @@ TEST_F(FaviconHandlerTest, FaviconInvalidURL) { std::vector<gfx::Size>()); TestFaviconDriver driver; - TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON); + TestFaviconHandler handler(&driver, FaviconDriverObserver::NON_TOUCH_16_DIP); UpdateFaviconURL(&driver, &handler, kPageURL, std::vector<FaviconURL>(1u, favicon_url)); EXPECT_EQ(0u, handler.image_urls().size()); @@ -1452,8 +1407,8 @@ TEST_F(FaviconHandlerTest, TestSortFavicon) { std::vector<gfx::Size>())}; TestFaviconDriver driver1; - TestFaviconHandler handler1(kPageURL, &driver1, - FaviconHandler::LARGEST_FAVICON); + TestFaviconHandler handler1(&driver1, + FaviconDriverObserver::NON_TOUCH_LARGEST); std::vector<FaviconURL> urls1(kSourceIconURLs, kSourceIconURLs + arraysize(kSourceIconURLs)); UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1); @@ -1515,8 +1470,8 @@ TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) { std::vector<gfx::Size>())}; TestFaviconDriver driver1; - TestFaviconHandler handler1(kPageURL, &driver1, - FaviconHandler::LARGEST_FAVICON); + TestFaviconHandler handler1(&driver1, + FaviconDriverObserver::NON_TOUCH_LARGEST); std::set<GURL> fail_icon_urls; for (size_t i = 0; i < arraysize(kSourceIconURLs); ++i) { @@ -1583,8 +1538,8 @@ TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) { GURL("http://www.google.com/c"), favicon_base::FAVICON, two_icons)}; TestFaviconDriver driver1; - TestFaviconHandler handler1(kPageURL, &driver1, - FaviconHandler::LARGEST_FAVICON); + TestFaviconHandler handler1(&driver1, + FaviconDriverObserver::NON_TOUCH_LARGEST); std::vector<FaviconURL> urls1(kSourceIconURLs, kSourceIconURLs + arraysize(kSourceIconURLs)); UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1); @@ -1626,10 +1581,9 @@ TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) { EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b], handler1.history_handler()->size_); // Verify NotifyFaviconAvailable(). - EXPECT_FALSE(driver1.update_active_favicon()); - EXPECT_EQ(kSourceIconURLs[i].icon_url, driver1.available_icon_url()); - EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b], - driver1.available_favicon().Size()); + EXPECT_EQ(1u, driver1.num_notifications()); + EXPECT_EQ(kSourceIconURLs[i].icon_url, driver1.icon_url()); + EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b], driver1.image().Size()); } TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) { @@ -1650,8 +1604,8 @@ TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) { GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2)}; TestFaviconDriver driver1; - TestFaviconHandler handler1(kPageURL, &driver1, - FaviconHandler::LARGEST_FAVICON); + TestFaviconHandler handler1(&driver1, + FaviconDriverObserver::NON_TOUCH_LARGEST); std::vector<FaviconURL> urls1(kSourceIconURLs, kSourceIconURLs + arraysize(kSourceIconURLs)); UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1); @@ -1711,8 +1665,8 @@ TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) { std::vector<gfx::Size>())}; TestFaviconDriver driver1; - TestFaviconHandler handler1(kPageURL, &driver1, - FaviconHandler::LARGEST_FAVICON); + TestFaviconHandler handler1(&driver1, + FaviconDriverObserver::NON_TOUCH_LARGEST); std::vector<FaviconURL> urls1(kSourceIconURLs, kSourceIconURLs + arraysize(kSourceIconURLs)); UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1); @@ -1762,86 +1716,5 @@ TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) { handler1.history_handler()->size_); } -class FaviconHandlerActiveFaviconValidityParamTest : - public FaviconHandlerTest, - public ::testing::WithParamInterface<bool> { - public: - FaviconHandlerActiveFaviconValidityParamTest() {} - - ~FaviconHandlerActiveFaviconValidityParamTest() override {} - - bool GetActiveFaviconValiditySetting() { - return GetParam(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FaviconHandlerActiveFaviconValidityParamTest); -}; - -TEST_P(FaviconHandlerActiveFaviconValidityParamTest, - TestDownloadLargestIconDoesNotImpactActiveFaviconValidity) { - const GURL page_url("http://www.google.com"); - - std::vector<gfx::Size> one_icon; - one_icon.push_back(gfx::Size(15, 15)); - - const GURL old_favicon_url("http://www.google.com/old"); - const GURL new_favicon_url("http://www.google.com/b"); - const FaviconURL source_icon_urls[] = { - FaviconURL(new_favicon_url, favicon_base::FAVICON, one_icon)}; - TestFaviconDriver driver1; - TestFaviconHandler handler1(page_url, &driver1, - FaviconHandler::LARGEST_FAVICON); - std::vector<FaviconURL> urls1(source_icon_urls, - source_icon_urls + arraysize(source_icon_urls)); - UpdateFaviconURL(&driver1, &handler1, page_url, urls1); - - HistoryRequestHandler* history_handler = handler1.history_handler(); - - // Simulate the active favicon is updated, this shouldn't happen in real - // use case, but we want to verify the behavior below is not impacted by - // accident. - driver1.SetActiveFaviconValidity(GetActiveFaviconValiditySetting()); - // Simulate the get favicon from history, but favicon URL didn't match. - SetFaviconRawBitmapResult(old_favicon_url, - &history_handler->history_results_); - history_handler->InvokeCallback(); - // Since we downloaded largest icon, and don't want to set active favicon - // NotifyFaviconAvaliable() should be called with is_active_favicon as false. - EXPECT_EQ(old_favicon_url, driver1.available_icon_url()); - EXPECT_FALSE(driver1.update_active_favicon()); - EXPECT_EQ(1u, driver1.num_favicon_available()); - - // We are trying to get favicon from history again. - history_handler = handler1.history_handler(); - EXPECT_EQ(new_favicon_url, history_handler->icon_url_); - // Simulate the get expired favicon from history. - history_handler->history_results_.clear(); - SetFaviconRawBitmapResult(new_favicon_url, favicon_base::FAVICON, true, - &history_handler->history_results_); - history_handler->InvokeCallback(); - // Since we downloaded largest icon, and don't want to set active favicon - // NotifyFaviconAvaliable() should be called with is_active_favicon as false. - EXPECT_EQ(new_favicon_url, driver1.available_icon_url()); - EXPECT_FALSE(driver1.update_active_favicon()); - EXPECT_EQ(2u, driver1.num_favicon_available()); - - // We are trying to download favicon. - DownloadHandler* download_handler = handler1.download_handler(); - EXPECT_TRUE(download_handler->HasDownload()); - EXPECT_EQ(new_favicon_url, download_handler->GetImageUrl()); - // Simulate the download succeed. - download_handler->InvokeCallback(); - // Since we downloaded largest icon, and don't want to set active favicon - // NotifyFaviconAvaliable() should be called with is_active_favicon as false. - EXPECT_EQ(new_favicon_url, driver1.available_icon_url()); - EXPECT_FALSE(driver1.update_active_favicon()); - EXPECT_EQ(3u, driver1.num_favicon_available()); -} - -INSTANTIATE_TEST_CASE_P(FaviconHandlerTestActiveFaviconValidityTrueOrFalse, - FaviconHandlerActiveFaviconValidityParamTest, - ::testing::Bool()); - } // namespace } // namespace favicon diff --git a/components/favicon/ios/web_favicon_driver.cc b/components/favicon/ios/web_favicon_driver.cc index b1a8e11..0377781 100644 --- a/components/favicon/ios/web_favicon_driver.cc +++ b/components/favicon/ios/web_favicon_driver.cc @@ -72,25 +72,23 @@ GURL WebFaviconDriver::GetActiveURL() { return item ? item->GetURL() : GURL(); } -void WebFaviconDriver::SetActiveFaviconValidity(bool validity) { - GetFaviconStatus().valid = validity; -} - -GURL WebFaviconDriver::GetActiveFaviconURL() { - return GetFaviconStatus().url; -} - -void WebFaviconDriver::SetActiveFaviconURL(const GURL& url) { - GetFaviconStatus().url = url; -} - -void WebFaviconDriver::SetActiveFaviconImage(const gfx::Image& image) { - GetFaviconStatus().image = image; -} +void WebFaviconDriver::OnFaviconUpdated( + const GURL& page_url, + FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) { + // Check whether the active URL has changed since FetchFavicon() was called. + // On iOS, the active URL can change between calls to FetchFavicon(). For + // instance, FetchFavicon() is not synchronously called when the active URL + // changes as a result of CRWSessionController::goToEntry(). + web::NavigationItem* item = + web_state()->GetNavigationManager()->GetVisibleItem(); + if (!item || item->GetURL() != page_url) + return; -web::FaviconStatus& WebFaviconDriver::GetFaviconStatus() { - DCHECK(web_state()->GetNavigationManager()->GetVisibleItem()); - return web_state()->GetNavigationManager()->GetVisibleItem()->GetFavicon(); + NotifyFaviconUpdatedObservers(notification_icon_type, icon_url, + icon_url_changed, image); } WebFaviconDriver::WebFaviconDriver(web::WebState* web_state, diff --git a/components/favicon/ios/web_favicon_driver.h b/components/favicon/ios/web_favicon_driver.h index 1e17e49..55e2945 100644 --- a/components/favicon/ios/web_favicon_driver.h +++ b/components/favicon/ios/web_favicon_driver.h @@ -35,10 +35,12 @@ class WebFaviconDriver : public web::WebStateObserver, int StartDownload(const GURL& url, int max_bitmap_size) override; bool IsOffTheRecord() override; GURL GetActiveURL() override; - void SetActiveFaviconValidity(bool valid) override; - GURL GetActiveFaviconURL() override; - void SetActiveFaviconURL(const GURL& url) override; - void SetActiveFaviconImage(const gfx::Image& image) override; + void OnFaviconUpdated( + const GURL& page_url, + FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL& icon_url, + bool icon_url_changed, + const gfx::Image& image) override; private: friend class web::WebStateUserData<WebFaviconDriver>; @@ -53,9 +55,6 @@ class WebFaviconDriver : public web::WebStateObserver, void FaviconUrlUpdated( const std::vector<web::FaviconURL>& candidates) override; - // Returns the active navigation entry's favicon. - web::FaviconStatus& GetFaviconStatus(); - // The URL passed to FetchFavicon(). GURL fetch_favicon_url_; |