Commit 19825f69 authored by Eugene But's avatar Eugene But Committed by Commit Bot

Call WebStateObserver::FaviconUrlUpdated for same-document navigations.

WebStateImpl will cache favicon urls in OnFaviconUrlUpdated and will
call WebStateObserver::FaviconUrlUpdated in OnNavigationFinished for
same document navigations.

Also removed favicon urls caching in WebFaviconDriver introduced in
crrev.com/c/695761. This CL is not exactly a revert of
crrev.com/c/695761, because deprecated NavigationItemCommitted is
replaced with DidFinishNavigation. NavigationItemCommitted is not
called for push/replace state same-document navigaiton, which may
cause other bugs for favicons caching.


Bug: 789581
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I42922ab4d7812380787e350713640efe4d599680
Reviewed-on: https://chromium-review.googlesource.com/797072Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Commit-Queue: Eugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521876}
parent 0a41408c
...@@ -60,8 +60,6 @@ class WebFaviconDriver : public web::WebStateObserver, ...@@ -60,8 +60,6 @@ class WebFaviconDriver : public web::WebStateObserver,
history::HistoryService* history_service); history::HistoryService* history_service);
// web::WebStateObserver implementation. // web::WebStateObserver implementation.
void DidStartNavigation(web::WebState* web_state,
web::NavigationContext* navigation_context) override;
void DidFinishNavigation(web::WebState* web_state, void DidFinishNavigation(web::WebState* web_state,
web::NavigationContext* navigation_context) override; web::NavigationContext* navigation_context) override;
void FaviconUrlUpdated( void FaviconUrlUpdated(
...@@ -76,9 +74,6 @@ class WebFaviconDriver : public web::WebStateObserver, ...@@ -76,9 +74,6 @@ class WebFaviconDriver : public web::WebStateObserver,
// Image Fetcher used to fetch favicon. // Image Fetcher used to fetch favicon.
image_fetcher::IOSImageDataFetcherWrapper image_fetcher_; image_fetcher::IOSImageDataFetcherWrapper image_fetcher_;
// Caches the favicon URLs candidates for same-document navigations.
std::vector<favicon::FaviconURL> candidates_;
// The WebState this instance is observing. Will be null after // The WebState this instance is observing. Will be null after
// WebStateDestroyed has been called. // WebStateDestroyed has been called.
web::WebState* web_state_ = nullptr; web::WebState* web_state_ = nullptr;
......
...@@ -117,13 +117,10 @@ void WebFaviconDriver::OnFaviconUpdated( ...@@ -117,13 +117,10 @@ void WebFaviconDriver::OnFaviconUpdated(
// On iOS, the active URL can change between calls to FetchFavicon(). For // On iOS, the active URL can change between calls to FetchFavicon(). For
// instance, FetchFavicon() is not synchronously called when the active URL // instance, FetchFavicon() is not synchronously called when the active URL
// changes as a result of CRWSessionController::goToEntry(). // changes as a result of CRWSessionController::goToEntry().
if (GetActiveURL() != page_url && !page_url.is_empty()) {
return;
}
web::NavigationItem* item = web::NavigationItem* item =
web_state_->GetNavigationManager()->GetVisibleItem(); web_state_->GetNavigationManager()->GetVisibleItem();
DCHECK(item); if (!item || item->GetURL() != page_url)
return;
web::FaviconStatus& favicon_status = item->GetFavicon(); web::FaviconStatus& favicon_status = item->GetFavicon();
favicon_status.valid = true; favicon_status.valid = true;
...@@ -168,32 +165,11 @@ WebFaviconDriver::~WebFaviconDriver() { ...@@ -168,32 +165,11 @@ WebFaviconDriver::~WebFaviconDriver() {
DCHECK(!web_state_); DCHECK(!web_state_);
} }
void WebFaviconDriver::DidStartNavigation(
web::WebState* web_state,
web::NavigationContext* navigation_context) {
DCHECK_EQ(web_state_, web_state);
SetFaviconOutOfDateForPage(navigation_context->GetUrl(),
/*force_reload=*/false);
}
void WebFaviconDriver::DidFinishNavigation( void WebFaviconDriver::DidFinishNavigation(
web::WebState* web_state, web::WebState* web_state,
web::NavigationContext* navigation_context) { web::NavigationContext* navigation_context) {
DCHECK_EQ(web_state_, web_state); FetchFavicon(web_state->GetLastCommittedURL(),
if (navigation_context->GetError())
return;
// Fetch the favicon for the new URL.
FetchFavicon(navigation_context->GetUrl(),
navigation_context->IsSameDocument()); navigation_context->IsSameDocument());
if (navigation_context->IsSameDocument()) {
if (!candidates_.empty()) {
FaviconUrlUpdatedInternal(candidates_);
}
} else {
candidates_.clear();
}
} }
void WebFaviconDriver::FaviconUrlUpdated( void WebFaviconDriver::FaviconUrlUpdated(
...@@ -201,8 +177,8 @@ void WebFaviconDriver::FaviconUrlUpdated( ...@@ -201,8 +177,8 @@ void WebFaviconDriver::FaviconUrlUpdated(
const std::vector<web::FaviconURL>& candidates) { const std::vector<web::FaviconURL>& candidates) {
DCHECK_EQ(web_state_, web_state); DCHECK_EQ(web_state_, web_state);
DCHECK(!candidates.empty()); DCHECK(!candidates.empty());
candidates_ = FaviconURLsFromWebFaviconURLs(candidates); OnUpdateCandidates(GetActiveURL(), FaviconURLsFromWebFaviconURLs(candidates),
FaviconUrlUpdatedInternal(candidates_); GURL());
} }
void WebFaviconDriver::WebStateDestroyed(web::WebState* web_state) { void WebFaviconDriver::WebStateDestroyed(web::WebState* web_state) {
...@@ -211,9 +187,4 @@ void WebFaviconDriver::WebStateDestroyed(web::WebState* web_state) { ...@@ -211,9 +187,4 @@ void WebFaviconDriver::WebStateDestroyed(web::WebState* web_state) {
web_state_ = nullptr; web_state_ = nullptr;
} }
void WebFaviconDriver::FaviconUrlUpdatedInternal(
const std::vector<favicon::FaviconURL>& candidates) {
OnUpdateCandidates(GetActiveURL(), candidates, GURL());
}
} // namespace favicon } // namespace favicon
...@@ -79,7 +79,9 @@ class WebStateImpl : public WebState, public NavigationManagerDelegate { ...@@ -79,7 +79,9 @@ class WebStateImpl : public WebState, public NavigationManagerDelegate {
// Notifies the observers that a navigation has started. // Notifies the observers that a navigation has started.
void OnNavigationStarted(web::NavigationContext* context); void OnNavigationStarted(web::NavigationContext* context);
// Notifies the observers that a navigation has finished. // Notifies the observers that a navigation has finished. For same-document
// navigations notifies the observers about favicon URLs update using
// candidates received in OnFaviconUrlUpdated.
void OnNavigationFinished(web::NavigationContext* context); void OnNavigationFinished(web::NavigationContext* context);
// Called when page title was changed. // Called when page title was changed.
...@@ -378,6 +380,12 @@ class WebStateImpl : public WebState, public NavigationManagerDelegate { ...@@ -378,6 +380,12 @@ class WebStateImpl : public WebState, public NavigationManagerDelegate {
// history into WKWebView when web usage is re-enabled. // history into WKWebView when web usage is re-enabled.
base::scoped_nsobject<CRWSessionStorage> cached_session_storage_; base::scoped_nsobject<CRWSessionStorage> cached_session_storage_;
// Favicons URLs received in OnFaviconUrlUpdated.
// WebStateObserver:FaviconUrlUpdated must be called for same-document
// navigations, so this cache will be used to avoid running expensive favicon
// fetching JavaScript.
std::vector<web::FaviconURL> cached_favicon_urls_;
DISALLOW_COPY_AND_ASSIGN(WebStateImpl); DISALLOW_COPY_AND_ASSIGN(WebStateImpl);
}; };
......
...@@ -261,6 +261,7 @@ void WebStateImpl::OnFormActivityRegistered(const FormActivityParams& params) { ...@@ -261,6 +261,7 @@ void WebStateImpl::OnFormActivityRegistered(const FormActivityParams& params) {
void WebStateImpl::OnFaviconUrlUpdated( void WebStateImpl::OnFaviconUrlUpdated(
const std::vector<FaviconURL>& candidates) { const std::vector<FaviconURL>& candidates) {
cached_favicon_urls_ = candidates;
for (auto& observer : observers_) for (auto& observer : observers_)
observer.FaviconUrlUpdated(this, candidates); observer.FaviconUrlUpdated(this, candidates);
} }
...@@ -736,6 +737,19 @@ void WebStateImpl::OnNavigationStarted(web::NavigationContext* context) { ...@@ -736,6 +737,19 @@ void WebStateImpl::OnNavigationStarted(web::NavigationContext* context) {
void WebStateImpl::OnNavigationFinished(web::NavigationContext* context) { void WebStateImpl::OnNavigationFinished(web::NavigationContext* context) {
for (auto& observer : observers_) for (auto& observer : observers_)
observer.DidFinishNavigation(this, context); observer.DidFinishNavigation(this, context);
// Update cached_favicon_urls_.
if (!context->IsSameDocument()) {
// Favicons are not valid after document change. Favicon URLs will be
// refetched by CRWWebController and passed to OnFaviconUrlUpdated.
cached_favicon_urls_.clear();
} else if (!cached_favicon_urls_.empty()) {
// For same-document navigations favicon urls will not be refetched and
// WebStateObserver:FaviconUrlUpdated must use the cached results.
for (auto& observer : observers_) {
observer.FaviconUrlUpdated(this, cached_favicon_urls_);
}
}
} }
#pragma mark - NavigationManagerDelegate implementation #pragma mark - NavigationManagerDelegate implementation
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#import "base/test/ios/wait_util.h" #import "base/test/ios/wait_util.h"
#import "ios/web/public/java_script_dialog_presenter.h" #import "ios/web/public/java_script_dialog_presenter.h"
#include "ios/web/public/load_committed_details.h" #include "ios/web/public/load_committed_details.h"
#import "ios/web/public/test/fakes/fake_navigation_context.h"
#include "ios/web/public/test/fakes/test_browser_state.h" #include "ios/web/public/test/fakes/test_browser_state.h"
#import "ios/web/public/test/fakes/test_web_state_delegate.h" #import "ios/web/public/test/fakes/test_web_state_delegate.h"
#import "ios/web/public/test/fakes/test_web_state_observer.h" #import "ios/web/public/test/fakes/test_web_state_observer.h"
...@@ -772,4 +773,53 @@ TEST_F(WebStateImplTest, CreatedWithOpener) { ...@@ -772,4 +773,53 @@ TEST_F(WebStateImplTest, CreatedWithOpener) {
EXPECT_TRUE(web_state_with_opener->HasOpener()); EXPECT_TRUE(web_state_with_opener->HasOpener());
} }
// Tests that WebStateObserver::FaviconUrlUpdated is called for same-document
// navigations.
TEST_F(WebStateImplTest, FaviconUpdateForSameDocumentNavigations) {
auto observer = std::make_unique<TestWebStateObserver>(web_state_.get());
// No callback if icons has not been fetched yet.
FakeNavigationContext context;
context.SetIsSameDocument(true);
web_state_->OnNavigationFinished(&context);
EXPECT_FALSE(observer->update_favicon_url_candidates_info());
// Callback is called when icons were fetched.
observer = base::MakeUnique<TestWebStateObserver>(web_state_.get());
web::FaviconURL favicon_url(GURL("https://chromium.test/"),
web::FaviconURL::IconType::kTouchIcon,
{gfx::Size(5, 6)});
web_state_->OnFaviconUrlUpdated({favicon_url});
EXPECT_TRUE(observer->update_favicon_url_candidates_info());
// Callback is now called after same-document navigation.
observer = std::make_unique<TestWebStateObserver>(web_state_.get());
web_state_->OnNavigationFinished(&context);
ASSERT_TRUE(observer->update_favicon_url_candidates_info());
ASSERT_EQ(1U,
observer->update_favicon_url_candidates_info()->candidates.size());
const web::FaviconURL& actual_favicon_url =
observer->update_favicon_url_candidates_info()->candidates[0];
EXPECT_EQ(favicon_url.icon_url, actual_favicon_url.icon_url);
EXPECT_EQ(favicon_url.icon_type, actual_favicon_url.icon_type);
ASSERT_EQ(favicon_url.icon_sizes.size(),
actual_favicon_url.icon_sizes.size());
EXPECT_EQ(favicon_url.icon_sizes[0].width(),
actual_favicon_url.icon_sizes[0].width());
EXPECT_EQ(favicon_url.icon_sizes[0].height(),
actual_favicon_url.icon_sizes[0].height());
// Document change navigation does not call callback.
observer = std::make_unique<TestWebStateObserver>(web_state_.get());
context.SetIsSameDocument(false);
web_state_->OnNavigationFinished(&context);
EXPECT_FALSE(observer->update_favicon_url_candidates_info());
// Previous candidates were invalidated by the document change. No callback
// if icons has not been fetched yet.
context.SetIsSameDocument(true);
web_state_->OnNavigationFinished(&context);
EXPECT_FALSE(observer->update_favicon_url_candidates_info());
}
} // namespace web } // namespace web
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment