Commit 880d328f authored by mathp's avatar mathp Committed by Commit bot

[Instant] Default Search Provider change redirects to local NTP in some cases

Previously, all instant renderers would reload if a search provider changed. With this patch, some of the renderers are redirected to the local NTP in the case that both the old and new search providers are google.<tld>.

BUG=456681
TEST=BrowserInstantControllerTest*, InstantService* unit_tests

Review URL: https://codereview.chromium.org/930853005

Cr-Commit-Position: refs/heads/master@{#317180}
parent 4ca14cb4
...@@ -311,7 +311,8 @@ void TabAndroid::SwapTabContents(content::WebContents* old_contents, ...@@ -311,7 +311,8 @@ void TabAndroid::SwapTabContents(content::WebContents* old_contents,
did_finish_load); did_finish_load);
} }
void TabAndroid::DefaultSearchProviderChanged() { void TabAndroid::DefaultSearchProviderChanged(
bool google_base_url_domain_changed) {
// TODO(kmadhusu): Move this function definition to a common place and update // TODO(kmadhusu): Move this function definition to a common place and update
// BrowserInstantController::DefaultSearchProviderChanged to use the same. // BrowserInstantController::DefaultSearchProviderChanged to use the same.
if (!web_contents()) if (!web_contents())
......
...@@ -125,7 +125,8 @@ class TabAndroid : public CoreTabHelperDelegate, ...@@ -125,7 +125,8 @@ class TabAndroid : public CoreTabHelperDelegate,
bool did_finish_load) override; bool did_finish_load) override;
// Overridden from InstantServiceObserver: // Overridden from InstantServiceObserver:
void DefaultSearchProviderChanged() override; void DefaultSearchProviderChanged(
bool google_base_url_domain_changed) override;
// Overridden from SearchTabHelperDelegate: // Overridden from SearchTabHelperDelegate:
void OnWebContentsInstantSupportDisabled( void OnWebContentsInstantSupportDisabled(
......
...@@ -407,18 +407,20 @@ void InstantService::OnTemplateURLServiceChanged() { ...@@ -407,18 +407,20 @@ void InstantService::OnTemplateURLServiceChanged() {
// changed, the effective URLs might change if they reference the Google base // changed, the effective URLs might change if they reference the Google base
// URL. The TemplateURLService will notify us when the effective URL changes // URL. The TemplateURLService will notify us when the effective URL changes
// in this way but it's up to us to do the work to check both. // in this way but it's up to us to do the work to check both.
bool google_base_url_domain_changed = false;
GURL google_base_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue()); GURL google_base_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue());
if (google_base_url != previous_google_base_url_) { if (google_base_url != previous_google_base_url_) {
previous_google_base_url_ = google_base_url; previous_google_base_url_ = google_base_url;
if (template_url && template_url->HasGoogleBaseURLs( if (template_url && template_url->HasGoogleBaseURLs(
UIThreadSearchTermsData(profile_))) UIThreadSearchTermsData(profile_)))
default_search_provider_changed = true; google_base_url_domain_changed = true;
} }
if (default_search_provider_changed) { if (default_search_provider_changed || google_base_url_domain_changed) {
ResetInstantSearchPrerenderer(); ResetInstantSearchPrerenderer();
FOR_EACH_OBSERVER(InstantServiceObserver, observers_, FOR_EACH_OBSERVER(
DefaultSearchProviderChanged()); InstantServiceObserver, observers_,
DefaultSearchProviderChanged(google_base_url_domain_changed));
} }
} }
......
...@@ -11,7 +11,8 @@ void InstantServiceObserver::MostVisitedItemsChanged( ...@@ -11,7 +11,8 @@ void InstantServiceObserver::MostVisitedItemsChanged(
const std::vector<InstantMostVisitedItem>&) { const std::vector<InstantMostVisitedItem>&) {
} }
void InstantServiceObserver::DefaultSearchProviderChanged() { void InstantServiceObserver::DefaultSearchProviderChanged(
bool google_base_url_domain_changed) {
} }
void InstantServiceObserver::OmniboxStartMarginChanged( void InstantServiceObserver::OmniboxStartMarginChanged(
......
...@@ -20,8 +20,11 @@ class InstantServiceObserver { ...@@ -20,8 +20,11 @@ class InstantServiceObserver {
virtual void MostVisitedItemsChanged( virtual void MostVisitedItemsChanged(
const std::vector<InstantMostVisitedItem>&); const std::vector<InstantMostVisitedItem>&);
// Indicates that the default search provider changed. // Indicates that the default search provider changed. Parameter indicates
virtual void DefaultSearchProviderChanged(); // whether the Google base URL changed (such as when the user migrates from
// one google.<TLD> to another TLD).
virtual void DefaultSearchProviderChanged(
bool google_base_url_domain_changed);
// Indicates that the omnibox start margin has changed. // Indicates that the omnibox start margin has changed.
virtual void OmniboxStartMarginChanged(int omnibox_start_margin); virtual void OmniboxStartMarginChanged(int omnibox_start_margin);
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
class MockInstantServiceObserver : public InstantServiceObserver { class MockInstantServiceObserver : public InstantServiceObserver {
public: public:
MOCK_METHOD0(DefaultSearchProviderChanged, void()); MOCK_METHOD1(DefaultSearchProviderChanged, void(bool));
MOCK_METHOD1(OmniboxStartMarginChanged, void(int)); MOCK_METHOD1(OmniboxStartMarginChanged, void(int));
}; };
...@@ -67,29 +67,29 @@ class InstantServiceEnabledTest : public InstantServiceTest { ...@@ -67,29 +67,29 @@ class InstantServiceEnabledTest : public InstantServiceTest {
}; };
TEST_F(InstantServiceEnabledTest, DispatchDefaultSearchProviderChanged) { TEST_F(InstantServiceEnabledTest, DispatchDefaultSearchProviderChanged) {
EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) EXPECT_CALL(*instant_service_observer_.get(),
.Times(1); DefaultSearchProviderChanged(false)).Times(1);
const std::string new_base_url = "https://bar.com/"; const std::string new_base_url = "https://bar.com/";
SetUserSelectedDefaultSearchProvider(new_base_url); SetUserSelectedDefaultSearchProvider(new_base_url);
} }
TEST_F(InstantServiceTest, DontDispatchGoogleURLUpdatedForNonGoogleURLs) { TEST_F(InstantServiceTest, DontDispatchGoogleURLUpdatedForNonGoogleURLs) {
EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) EXPECT_CALL(*instant_service_observer_.get(),
.Times(1); DefaultSearchProviderChanged(false)).Times(1);
const std::string new_dsp_url = "https://bar.com/"; const std::string new_dsp_url = "https://bar.com/";
SetUserSelectedDefaultSearchProvider(new_dsp_url); SetUserSelectedDefaultSearchProvider(new_dsp_url);
testing::Mock::VerifyAndClearExpectations(instant_service_observer_.get()); testing::Mock::VerifyAndClearExpectations(instant_service_observer_.get());
EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) EXPECT_CALL(*instant_service_observer_.get(),
.Times(0); DefaultSearchProviderChanged(false)).Times(0);
const std::string new_base_url = "https://www.google.es/"; const std::string new_base_url = "https://www.google.es/";
NotifyGoogleBaseURLUpdate(new_base_url); NotifyGoogleBaseURLUpdate(new_base_url);
} }
TEST_F(InstantServiceTest, DispatchGoogleURLUpdated) { TEST_F(InstantServiceTest, DispatchGoogleURLUpdated) {
EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) EXPECT_CALL(*instant_service_observer_.get(),
.Times(1); DefaultSearchProviderChanged(true)).Times(1);
const std::string new_base_url = "https://www.google.es/"; const std::string new_base_url = "https://www.google.es/";
NotifyGoogleBaseURLUpdate(new_base_url); NotifyGoogleBaseURLUpdate(new_base_url);
...@@ -123,8 +123,8 @@ TEST_F(InstantServiceTest, InstantSearchEnabled) { ...@@ -123,8 +123,8 @@ TEST_F(InstantServiceTest, InstantSearchEnabled) {
TEST_F(InstantServiceEnabledTest, TEST_F(InstantServiceEnabledTest,
ResetInstantSearchPrerenderer_DefaultProviderChanged) { ResetInstantSearchPrerenderer_DefaultProviderChanged) {
EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) EXPECT_CALL(*instant_service_observer_.get(),
.Times(2); DefaultSearchProviderChanged(false)).Times(2);
// Set a default search provider that doesn't support Instant. // Set a default search provider that doesn't support Instant.
TemplateURLData data; TemplateURLData data;
...@@ -146,8 +146,8 @@ TEST_F(InstantServiceEnabledTest, ...@@ -146,8 +146,8 @@ TEST_F(InstantServiceEnabledTest,
TEST_F(InstantServiceEnabledTest, TEST_F(InstantServiceEnabledTest,
ResetInstantSearchPrerenderer_GoogleBaseURLUpdated) { ResetInstantSearchPrerenderer_GoogleBaseURLUpdated) {
EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) EXPECT_CALL(*instant_service_observer_.get(),
.Times(1); DefaultSearchProviderChanged(true)).Times(1);
InstantSearchPrerenderer* old_prerenderer = GetInstantSearchPrerenderer(); InstantSearchPrerenderer* old_prerenderer = GetInstantSearchPrerenderer();
EXPECT_TRUE(old_prerenderer != NULL); EXPECT_TRUE(old_prerenderer != NULL);
......
...@@ -21,10 +21,12 @@ ...@@ -21,10 +21,12 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/instant_types.h" #include "chrome/common/instant_types.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/user_metrics.h" #include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/referrer.h"
#include "ui/base/page_transition_types.h"
// Helpers -------------------------------------------------------------------- // Helpers --------------------------------------------------------------------
...@@ -140,7 +142,8 @@ void BrowserInstantController::ModelChanged( ...@@ -140,7 +142,8 @@ void BrowserInstantController::ModelChanged(
instant_.InstantSupportChanged(new_state.instant_support); instant_.InstantSupportChanged(new_state.instant_support);
} }
void BrowserInstantController::DefaultSearchProviderChanged() { void BrowserInstantController::DefaultSearchProviderChanged(
bool google_base_url_domain_changed) {
InstantService* instant_service = InstantService* instant_service =
InstantServiceFactory::GetForProfile(profile()); InstantServiceFactory::GetForProfile(profile());
if (!instant_service) if (!instant_service)
...@@ -157,17 +160,28 @@ void BrowserInstantController::DefaultSearchProviderChanged() { ...@@ -157,17 +160,28 @@ void BrowserInstantController::DefaultSearchProviderChanged() {
content::RenderProcessHost* rph = contents->GetRenderProcessHost(); content::RenderProcessHost* rph = contents->GetRenderProcessHost();
instant_service->SendSearchURLsToRenderer(rph); instant_service->SendSearchURLsToRenderer(rph);
// Reload the contents to ensure that it gets assigned to a non-priviledged
// renderer.
if (!instant_service->IsInstantProcess(rph->GetID())) if (!instant_service->IsInstantProcess(rph->GetID()))
continue; continue;
contents->GetController().Reload(false); if (google_base_url_domain_changed &&
SearchTabHelper::FromWebContents(contents)->model()->mode().is_ntp()) {
// As the reload was not triggered by the user we don't want to close any // Replace the server NTP with the local NTP.
// infobars. We have to tell the InfoBarService after the reload, otherwise content::NavigationController::LoadURLParams
// it would ignore this call when params(chrome::GetLocalInstantURL(profile()));
// WebContentsObserver::DidStartNavigationToPendingEntry is invoked. params.should_replace_current_entry = true;
InfoBarService::FromWebContents(contents)->set_ignore_next_reload(); params.referrer = content::Referrer();
params.transition_type = ui::PAGE_TRANSITION_RELOAD;
contents->GetController().LoadURLWithParams(params);
} else {
// Reload the contents to ensure that it gets assigned to a
// non-priviledged renderer.
contents->GetController().Reload(false);
// As the reload was not triggered by the user we don't want to close any
// infobars. We have to tell the InfoBarService after the reload,
// otherwise it would ignore this call when
// WebContentsObserver::DidStartNavigationToPendingEntry is invoked.
InfoBarService::FromWebContents(contents)->set_ignore_next_reload();
}
} }
} }
...@@ -53,7 +53,8 @@ class BrowserInstantController : public SearchModelObserver, ...@@ -53,7 +53,8 @@ class BrowserInstantController : public SearchModelObserver,
const SearchModel::State& new_state) override; const SearchModel::State& new_state) override;
// InstantServiceObserver: // InstantServiceObserver:
void DefaultSearchProviderChanged() override; void DefaultSearchProviderChanged(
bool google_base_url_domain_changed) override;
// Replaces the contents at tab |index| with |new_contents| and deletes the // Replaces the contents at tab |index| with |new_contents| and deletes the
// existing contents. // existing contents.
......
...@@ -36,23 +36,40 @@ class BrowserInstantControllerTest : public InstantUnitTestBase { ...@@ -36,23 +36,40 @@ class BrowserInstantControllerTest : public InstantUnitTestBase {
friend class FakeWebContentsObserver; friend class FakeWebContentsObserver;
}; };
const struct TabReloadTestCase { struct TabReloadTestCase {
const char* description; const char* description;
const char* start_url; const char* start_url;
bool start_in_instant_process; bool start_in_instant_process;
bool should_reload; bool should_reload;
bool end_in_local_ntp;
bool end_in_instant_process; bool end_in_instant_process;
} kTabReloadTestCases[] = { };
// Test cases for when Google is the initial, but not final provider.
const TabReloadTestCase kTabReloadTestCasesFinalProviderNotGoogle[] = {
{"Local Embedded NTP", chrome::kChromeSearchLocalNtpUrl,
true, true, true, true},
{"Remote Embedded NTP", "https://www.google.com/newtab",
true, true, false, false},
{"Remote Embedded SERP", "https://www.google.com/url?strk&bar=search+terms",
true, true, false, false},
{"Other NTP", "https://bar.com/newtab",
false, false, false, false}
};
// Test cases for when Google is both the initial and final provider.
const TabReloadTestCase kTabReloadTestCasesFinalProviderGoogle[] = {
{"Local Embedded NTP", chrome::kChromeSearchLocalNtpUrl, {"Local Embedded NTP", chrome::kChromeSearchLocalNtpUrl,
true, true, true}, true, true, true, true},
{"Remote Embedded NTP", "https://www.google.com/instant?strk", {"Remote Embedded NTP", "https://www.google.com/newtab",
true, true, false}, true, false, true, true},
{"Remote Embedded SERP", "https://www.google.com/url?strk&bar=search+terms", {"Remote Embedded SERP", "https://www.google.com/url?strk&bar=search+terms",
true, true, false}, true, true, false, false},
{"Other NTP", "https://bar.com/instant?strk", {"Other NTP", "https://bar.com/newtab",
false, false, false} false, false, false, false}
}; };
class FakeWebContentsObserver : public content::WebContentsObserver { class FakeWebContentsObserver : public content::WebContentsObserver {
public: public:
explicit FakeWebContentsObserver(content::WebContents* contents) explicit FakeWebContentsObserver(content::WebContents* contents)
...@@ -66,16 +83,25 @@ class FakeWebContentsObserver : public content::WebContentsObserver { ...@@ -66,16 +83,25 @@ class FakeWebContentsObserver : public content::WebContentsObserver {
content::NavigationController::ReloadType reload_type) override { content::NavigationController::ReloadType reload_type) override {
if (url_ == url) if (url_ == url)
num_reloads_++; num_reloads_++;
current_url_ = url;
} }
const GURL url() const { const GURL url() const {
return url_; return url_;
} }
const GURL current_url() const {
return contents_->GetURL();
}
int num_reloads() const { int num_reloads() const {
return num_reloads_; return num_reloads_;
} }
bool can_go_back() const {
return contents_->GetController().CanGoBack();
}
protected: protected:
friend class BrowserInstantControllerTest; friend class BrowserInstantControllerTest;
FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest, FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest,
...@@ -86,14 +112,16 @@ class FakeWebContentsObserver : public content::WebContentsObserver { ...@@ -86,14 +112,16 @@ class FakeWebContentsObserver : public content::WebContentsObserver {
private: private:
content::WebContents* contents_; content::WebContents* contents_;
const GURL& url_; const GURL& url_;
GURL current_url_;
int num_reloads_; int num_reloads_;
}; };
TEST_F(BrowserInstantControllerTest, DefaultSearchProviderChanged) { TEST_F(BrowserInstantControllerTest, DefaultSearchProviderChanged) {
size_t num_tests = arraysize(kTabReloadTestCases); size_t num_tests = arraysize(kTabReloadTestCasesFinalProviderNotGoogle);
ScopedVector<FakeWebContentsObserver> observers; ScopedVector<FakeWebContentsObserver> observers;
for (size_t i = 0; i < num_tests; ++i) { for (size_t i = 0; i < num_tests; ++i) {
const TabReloadTestCase& test = kTabReloadTestCases[i]; const TabReloadTestCase& test =
kTabReloadTestCasesFinalProviderNotGoogle[i];
AddTab(browser(), GURL(test.start_url)); AddTab(browser(), GURL(test.start_url));
content::WebContents* contents = content::WebContents* contents =
browser()->tab_strip_model()->GetActiveWebContents(); browser()->tab_strip_model()->GetActiveWebContents();
...@@ -112,27 +140,34 @@ TEST_F(BrowserInstantControllerTest, DefaultSearchProviderChanged) { ...@@ -112,27 +140,34 @@ TEST_F(BrowserInstantControllerTest, DefaultSearchProviderChanged) {
for (size_t i = 0; i < num_tests; ++i) { for (size_t i = 0; i < num_tests; ++i) {
FakeWebContentsObserver* observer = observers[i]; FakeWebContentsObserver* observer = observers[i];
const TabReloadTestCase& test = kTabReloadTestCases[i]; const TabReloadTestCase& test =
kTabReloadTestCasesFinalProviderNotGoogle[i];
if (test.should_reload) { if (test.should_reload) {
// Validate final instant state. // Validate final instant state.
EXPECT_EQ( EXPECT_EQ(
test.end_in_instant_process, test.end_in_instant_process,
chrome::ShouldAssignURLToInstantRenderer(observer->url(), profile())) chrome::ShouldAssignURLToInstantRenderer(
observer->current_url(), profile()))
<< test.description; << test.description;
} }
// Ensure only the expected tabs(contents) reloaded. // Ensure only the expected tabs(contents) reloaded.
EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads()) EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads())
<< test.description; << test.description;
if (test.end_in_local_ntp) {
EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), observer->current_url())
<< test.description;
}
} }
} }
TEST_F(BrowserInstantControllerTest, GoogleBaseURLUpdated) { TEST_F(BrowserInstantControllerTest, GoogleBaseURLUpdated) {
const size_t num_tests = arraysize(kTabReloadTestCases); const size_t num_tests = arraysize(kTabReloadTestCasesFinalProviderGoogle);
ScopedVector<FakeWebContentsObserver> observers; ScopedVector<FakeWebContentsObserver> observers;
for (size_t i = 0; i < num_tests; ++i) { for (size_t i = 0; i < num_tests; ++i) {
const TabReloadTestCase& test = kTabReloadTestCases[i]; const TabReloadTestCase& test = kTabReloadTestCasesFinalProviderGoogle[i];
AddTab(browser(), GURL(test.start_url)); AddTab(browser(), GURL(test.start_url));
content::WebContents* contents = content::WebContents* contents =
browser()->tab_strip_model()->GetActiveWebContents(); browser()->tab_strip_model()->GetActiveWebContents();
...@@ -150,20 +185,26 @@ TEST_F(BrowserInstantControllerTest, GoogleBaseURLUpdated) { ...@@ -150,20 +185,26 @@ TEST_F(BrowserInstantControllerTest, GoogleBaseURLUpdated) {
NotifyGoogleBaseURLUpdate("https://www.google.es/"); NotifyGoogleBaseURLUpdate("https://www.google.es/");
for (size_t i = 0; i < num_tests; ++i) { for (size_t i = 0; i < num_tests; ++i) {
const TabReloadTestCase& test = kTabReloadTestCases[i]; const TabReloadTestCase& test = kTabReloadTestCasesFinalProviderGoogle[i];
FakeWebContentsObserver* observer = observers[i]; FakeWebContentsObserver* observer = observers[i];
if (test.should_reload) { // Validate final instant state.
// Validate final instant state. EXPECT_EQ(
EXPECT_EQ( test.end_in_instant_process,
test.end_in_instant_process, chrome::ShouldAssignURLToInstantRenderer(
chrome::ShouldAssignURLToInstantRenderer(observer->url(), profile())) observer->current_url(), profile()))
<< test.description; << test.description;
}
// Ensure only the expected tabs(contents) reloaded. // Ensure only the expected tabs(contents) reloaded.
EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads()) EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads())
<< test.description; << test.description;
if (test.end_in_local_ntp) {
EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), observer->current_url())
<< test.description;
// The navigation to Local NTP should be definitive i.e. can't go back.
EXPECT_FALSE(observer->can_go_back());
}
} }
} }
......
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