summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/search/instant_controller.cc47
-rw-r--r--chrome/browser/ui/search/instant_controller.h30
-rw-r--r--chrome/browser/ui/search/instant_controller_unittest.cc254
-rw-r--r--chrome/browser/ui/search/instant_page.cc4
-rw-r--r--chrome/browser/ui/search/instant_page.h2
-rw-r--r--tools/metrics/histograms/histograms.xml1
6 files changed, 313 insertions, 25 deletions
diff --git a/chrome/browser/ui/search/instant_controller.cc b/chrome/browser/ui/search/instant_controller.cc
index d01af5d..c861a1c 100644
--- a/chrome/browser/ui/search/instant_controller.cc
+++ b/chrome/browser/ui/search/instant_controller.cc
@@ -7,12 +7,15 @@
#include <iterator>
#include "base/metrics/histogram.h"
+#include "base/prefs/pref_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete_provider.h"
#include "chrome/browser/autocomplete/autocomplete_result.h"
#include "chrome/browser/autocomplete/search_provider.h"
+#include "chrome/browser/content_settings/content_settings_provider.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/history_tab_helper.h"
@@ -30,6 +33,8 @@
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/content_settings_types.h"
+#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/sessions/serialized_navigation_entry.h"
#include "content/public/browser/navigation_entry.h"
@@ -1588,25 +1593,25 @@ void InstantController::ReloadStaleNTP() {
}
bool InstantController::ShouldSwitchToLocalNTP() const {
- if (!ntp_)
+ if (!ntp())
+ return true;
+
+ // Assume users with Javascript disabled do not want the online experience.
+ if (!IsJavascriptEnabled())
return true;
// Already a local page. Not calling IsLocal() because we want to distinguish
// between the Google-specific and generic local NTP.
- if (extended_enabled() && ntp_->instant_url() == GetLocalInstantURL())
+ if (extended_enabled() && ntp()->instant_url() == GetLocalInstantURL())
return false;
if (PageIsCurrent(ntp()))
return false;
- // TODO(shishir): This is not completely reliable. Find a better way to detect
- // startup time.
- const bool in_startup = !browser_->GetActiveWebContents();
-
// The preloaded NTP does not support instant yet. If we're not in startup,
// always fall back to the local NTP. If we are in startup, use the local NTP
// (unless the finch flag to use the remote NTP is set).
- return !(in_startup && chrome::ShouldPreferRemoteNTPOnStartup());
+ return !(InStartup() && chrome::ShouldPreferRemoteNTPOnStartup());
}
void InstantController::ResetOverlay(const std::string& instant_url) {
@@ -1631,6 +1636,10 @@ InstantController::ShouldSwitchToLocalOverlay() const {
if (!overlay())
return DetermineFallbackReason(NULL, std::string());
+ // Assume users with Javascript disabled do not want the online experience.
+ if (!IsJavascriptEnabled())
+ return INSTANT_FALLBACK_JAVASCRIPT_DISABLED;
+
if (overlay()->IsLocal())
return INSTANT_FALLBACK_NONE;
@@ -1874,3 +1883,27 @@ void InstantController::PopulateInstantAutocompleteResultFromMatch(
<< result->description << "' '" << result->search_query << "' "
<< result->transition << " " << result->autocomplete_match_index;
}
+
+bool InstantController::IsJavascriptEnabled() const {
+ GURL instant_url(GetInstantURL());
+ GURL origin(instant_url.GetOrigin());
+ ContentSetting js_setting = profile()->GetHostContentSettingsMap()->
+ GetContentSetting(origin, origin, CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ NO_RESOURCE_IDENTIFIER);
+ // Javascript can be disabled either in content settings or via a WebKit
+ // preference, so check both. Disabling it through the Settings page affects
+ // content settings. I'm not sure how to disable the WebKit preference, but
+ // it's theoretically possible some users have it off.
+ bool js_content_enabled =
+ js_setting == CONTENT_SETTING_DEFAULT ||
+ js_setting == CONTENT_SETTING_ALLOW;
+ bool js_webkit_enabled = profile()->GetPrefs()->GetBoolean(
+ prefs::kWebKitJavascriptEnabled);
+ return js_content_enabled && js_webkit_enabled;
+}
+
+bool InstantController::InStartup() const {
+ // TODO(shishir): This is not completely reliable. Find a better way to detect
+ // startup time.
+ return !browser_->GetActiveWebContents();
+}
diff --git a/chrome/browser/ui/search/instant_controller.h b/chrome/browser/ui/search/instant_controller.h
index cdb170b..0a3d42e 100644
--- a/chrome/browser/ui/search/instant_controller.h
+++ b/chrome/browser/ui/search/instant_controller.h
@@ -76,7 +76,8 @@ class InstantController : public InstantPage::Delegate {
INSTANT_FALLBACK_ORIGIN_PATH_MISMATCH = 3,
INSTANT_FALLBACK_INSTANT_NOT_SUPPORTED = 4,
INSTANT_FALLBACK_NO_OVERLAY = 5,
- INSTANT_FALLBACK_MAX = 6,
+ INSTANT_FALLBACK_JAVASCRIPT_DISABLED = 6,
+ INSTANT_FALLBACK_MAX = 7,
};
InstantController(BrowserInstantController* browser,
@@ -251,11 +252,30 @@ class InstantController : public InstantPage::Delegate {
virtual InstantTab* instant_tab() const;
virtual InstantNTP* ntp() const;
+ virtual Profile* profile() const;
+
+ // Returns true if Javascript is enabled and false otherwise.
+ virtual bool IsJavascriptEnabled() const;
+
+ // Returns true if the browser is in startup.
+ virtual bool InStartup() const;
+
private:
friend class InstantExtendedManualTest;
friend class InstantTestBase;
- FRIEND_TEST_ALL_PREFIXES(InstantControllerTest,
- ShouldSwitchToLocalOverlayReturn);
+#define UNIT_F(test) FRIEND_TEST_ALL_PREFIXES(InstantControllerTest, test)
+ UNIT_F(DoesNotSwitchToLocalNTPIfOnCurrentNTP);
+ UNIT_F(DoesNotSwitchToLocalNTPIfOnLocalNTP);
+ UNIT_F(IsJavascriptEnabled);
+ UNIT_F(IsJavascriptEnabledChecksContentSettings);
+ UNIT_F(IsJavascriptEnabledChecksPrefs);
+ UNIT_F(PrefersRemoteNTPOnStartup);
+ UNIT_F(ShouldSwitchToLocalOverlay);
+ UNIT_F(SwitchesToLocalNTPIfJSDisabled);
+ UNIT_F(SwitchesToLocalNTPIfNoInstantSupport);
+ UNIT_F(SwitchesToLocalNTPIfNoNTPReady);
+ UNIT_F(SwitchesToLocalNTPIfPathBad);
+#undef UNIT_F
FRIEND_TEST_ALL_PREFIXES(InstantTest, OmniboxFocusLoadsInstant);
FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, UsesOverlayIfTabNotReady);
FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest,
@@ -319,8 +339,6 @@ class InstantController : public InstantPage::Delegate {
TypedSearchURLDoesntReuseInstantTab);
#endif
- Profile* profile() const;
-
// Overridden from InstantPage::Delegate:
// TODO(shishir): We assume that the WebContent's current RenderViewHost is
// the RenderViewHost being created which is not always true. Fix this.
@@ -373,7 +391,7 @@ class InstantController : public InstantPage::Delegate {
// Returns the local Instant URL. (Just a convenience wrapper around
// chrome::GetLocalInstantURL.)
- std::string GetLocalInstantURL() const;
+ virtual std::string GetLocalInstantURL() const;
// Returns true if |page| has an up-to-date Instant URL and supports Instant.
// Note that local URLs will not pass this check.
diff --git a/chrome/browser/ui/search/instant_controller_unittest.cc b/chrome/browser/ui/search/instant_controller_unittest.cc
index d449236..3ed131e 100644
--- a/chrome/browser/ui/search/instant_controller_unittest.cc
+++ b/chrome/browser/ui/search/instant_controller_unittest.cc
@@ -3,12 +3,19 @@
// found in the LICENSE file.
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/statistics_recorder.h"
+#include "base/prefs/pref_service.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/search/instant_controller.h"
+#include "chrome/browser/ui/search/instant_ntp.h"
#include "chrome/browser/ui/search/instant_overlay.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::HistogramBase;
@@ -45,24 +52,75 @@ class TestableInstantOverlay : public InstantOverlay {
bool test_is_local_;
};
+class TestableInstantNTP : public InstantNTP {
+ public:
+ TestableInstantNTP(InstantController* controller,
+ const std::string& instant_url)
+ : InstantNTP(controller, instant_url) {
+ }
+
+ // Overrides from InstantPage
+ virtual bool supports_instant() const OVERRIDE {
+ return test_supports_instant_;
+ }
+
+ virtual bool IsLocal() const OVERRIDE {
+ return test_is_local_;
+ };
+
+ virtual const std::string& instant_url() const OVERRIDE {
+ return test_instant_url_;
+ }
+
+ void set_instant_url(const std::string& instant_url) {
+ test_instant_url_ = instant_url;
+ }
+
+ void set_supports_instant(bool supports_instant) {
+ test_supports_instant_ = supports_instant;
+ }
+
+ void set_is_local(bool is_local) {
+ test_is_local_ = is_local;
+ }
+
+ private:
+ std::string test_instant_url_;
+ bool test_supports_instant_;
+ bool test_is_local_;
+};
+
class TestableInstantController : public InstantController {
public:
TestableInstantController()
: InstantController(NULL, true),
test_instant_url_("http://test_url"),
- test_extended_enabled_(true) {}
+ test_extended_enabled_(true),
+ override_javascript_enabled_(true),
+ test_javascript_enabled_(true),
+ test_in_startup_(false),
+ test_overlay_(NULL),
+ test_ntp_(NULL) {}
// Overrides from InstantController
virtual std::string GetInstantURL() const OVERRIDE {
return test_instant_url_;
}
+ virtual std::string GetLocalInstantURL() const OVERRIDE {
+ return "http://local_instant_url";
+ }
+
virtual bool extended_enabled() const OVERRIDE {
return test_extended_enabled_;
}
virtual InstantOverlay* overlay() const OVERRIDE {
- return test_overlay_.get();
+ return test_overlay_;
+ }
+
+ virtual InstantNTP* ntp() const OVERRIDE {
+ return test_ntp_;
}
void set_instant_url(std::string instant_url) {
@@ -74,19 +132,56 @@ class TestableInstantController : public InstantController {
}
void set_overlay(InstantOverlay* overlay) {
- test_overlay_.reset(overlay);
+ test_overlay_ = overlay;
+ }
+
+ void set_ntp(InstantNTP* ntp) {
+ test_ntp_ = ntp;
+ }
+
+ void set_javascript_enabled(bool javascript_enabled) {
+ override_javascript_enabled_ = true;
+ test_javascript_enabled_ = javascript_enabled;
+ }
+
+ void set_override_javascript_enabled(bool override_javascript_enabled) {
+ override_javascript_enabled_ = override_javascript_enabled;
+ }
+
+ void set_in_startup(bool in_startup) {
+ test_in_startup_ = in_startup;
+ }
+
+ virtual bool IsJavascriptEnabled() const OVERRIDE {
+ if (override_javascript_enabled_)
+ return test_javascript_enabled_;
+ else
+ return InstantController::IsJavascriptEnabled();
+ }
+
+ virtual bool InStartup() const OVERRIDE {
+ return test_in_startup_;
+ }
+
+ virtual Profile* profile() const OVERRIDE {
+ return &profile_;
}
private:
std::string test_instant_url_;
bool test_extended_enabled_;
- scoped_ptr<InstantOverlay> test_overlay_;
+ bool override_javascript_enabled_;
+ bool test_javascript_enabled_;
+ bool test_in_startup_;
+ InstantOverlay* test_overlay_;
+ InstantNTP* test_ntp_;
+ mutable TestingProfile profile_;
};
class InstantControllerTest : public testing::Test {
public:
InstantControllerTest()
- : loop_(base::MessageLoop::TYPE_DEFAULT),
+ : ui_thread_(content::BrowserThread::UI),
instant_controller_(new TestableInstantController()) {
}
@@ -99,11 +194,11 @@ class InstantControllerTest : public testing::Test {
}
private:
- base::MessageLoop loop_;
+ content::TestBrowserThread ui_thread_;
scoped_ptr<TestableInstantController> instant_controller_;
};
-TEST_F(InstantControllerTest, ShouldSwitchToLocalOverlayReturn) {
+TEST_F(InstantControllerTest, ShouldSwitchToLocalOverlay) {
InstantController::InstantFallbackReason fallback_reason;
instant_controller()->set_extended_enabled(false);
@@ -115,13 +210,19 @@ TEST_F(InstantControllerTest, ShouldSwitchToLocalOverlayReturn) {
ASSERT_EQ(fallback_reason, InstantController::INSTANT_FALLBACK_NO_OVERLAY);
std::string instant_url("http://test_url");
- TestableInstantOverlay* test_overlay =
- new TestableInstantOverlay(instant_controller(), instant_url);
+ scoped_ptr<TestableInstantOverlay> test_overlay(
+ new TestableInstantOverlay(instant_controller(), instant_url));
test_overlay->set_is_local(true);
- instant_controller()->set_overlay(test_overlay);
+ instant_controller()->set_overlay(test_overlay.get());
fallback_reason = instant_controller()->ShouldSwitchToLocalOverlay();
ASSERT_EQ(fallback_reason, InstantController::INSTANT_FALLBACK_NONE);
+ instant_controller()->set_javascript_enabled(false);
+ fallback_reason = instant_controller()->ShouldSwitchToLocalOverlay();
+ ASSERT_EQ(fallback_reason,
+ InstantController::INSTANT_FALLBACK_JAVASCRIPT_DISABLED);
+ instant_controller()->set_javascript_enabled(true);
+
test_overlay->set_is_local(false);
instant_controller()->set_instant_url("");
fallback_reason = instant_controller()->ShouldSwitchToLocalOverlay();
@@ -143,3 +244,134 @@ TEST_F(InstantControllerTest, ShouldSwitchToLocalOverlayReturn) {
fallback_reason = instant_controller()->ShouldSwitchToLocalOverlay();
ASSERT_EQ(fallback_reason, InstantController::INSTANT_FALLBACK_NONE);
}
+
+TEST_F(InstantControllerTest, PrefersRemoteNTPOnStartup) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_controller(), instant_url));
+ ntp->set_is_local(false);
+ instant_controller()->set_ntp(ntp.get());
+ instant_controller()->set_javascript_enabled(true);
+ instant_controller()->set_extended_enabled(true);
+ instant_controller()->set_instant_url(instant_url);
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(false);
+ instant_controller()->set_in_startup(true);
+ EXPECT_EQ(!chrome::ShouldPreferRemoteNTPOnStartup(),
+ instant_controller()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantControllerTest, SwitchesToLocalNTPIfNoInstantSupport) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_controller(), instant_url));
+ ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
+ ntp->set_is_local(false);
+ instant_controller()->set_ntp(ntp.get());
+ instant_controller()->set_javascript_enabled(true);
+ instant_controller()->set_extended_enabled(true);
+ instant_controller()->set_instant_url(instant_url);
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(false);
+ instant_controller()->set_in_startup(false);
+ EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantControllerTest, SwitchesToLocalNTPIfPathBad) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_controller(), instant_url));
+ ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
+ ntp->set_is_local(false);
+ instant_controller()->set_ntp(ntp.get());
+ instant_controller()->set_javascript_enabled(true);
+ instant_controller()->set_extended_enabled(true);
+ instant_controller()->set_instant_url("http://bogus_url");
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(true);
+ instant_controller()->set_in_startup(false);
+ EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantControllerTest, DoesNotSwitchToLocalNTPIfOnCurrentNTP) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_controller(), instant_url));
+ ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
+ ntp->set_is_local(false);
+ instant_controller()->set_ntp(ntp.get());
+ instant_controller()->set_javascript_enabled(true);
+ instant_controller()->set_extended_enabled(true);
+ instant_controller()->set_instant_url(instant_url);
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(true);
+ instant_controller()->set_in_startup(false);
+ EXPECT_FALSE(instant_controller()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantControllerTest, DoesNotSwitchToLocalNTPIfOnLocalNTP) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_controller(), instant_url));
+ ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
+ ntp->set_is_local(false);
+ instant_controller()->set_ntp(ntp.get());
+ instant_controller()->set_javascript_enabled(true);
+ instant_controller()->set_extended_enabled(true);
+ instant_controller()->set_instant_url(instant_url);
+ ntp->set_instant_url("http://local_instant_url");
+ ntp->set_supports_instant(true);
+ instant_controller()->set_in_startup(false);
+ EXPECT_FALSE(instant_controller()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantControllerTest, SwitchesToLocalNTPIfJSDisabled) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_controller(), instant_url));
+ ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
+ ntp->set_is_local(false);
+ instant_controller()->set_ntp(ntp.get());
+ instant_controller()->set_javascript_enabled(false);
+ instant_controller()->set_extended_enabled(true);
+ instant_controller()->set_instant_url(instant_url);
+ ntp->set_instant_url("http://local_instant_url");
+ ntp->set_supports_instant(true);
+ instant_controller()->set_in_startup(false);
+ EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantControllerTest, SwitchesToLocalNTPIfNoNTPReady) {
+ EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantControllerTest, IsJavascriptEnabled) {
+ instant_controller()->set_override_javascript_enabled(false);
+ EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
+}
+
+TEST_F(InstantControllerTest, IsJavascriptEnabledChecksContentSettings) {
+ instant_controller()->set_override_javascript_enabled(false);
+ instant_controller()->profile()->GetHostContentSettingsMap()
+ ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_DEFAULT);
+ EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
+ instant_controller()->profile()->GetHostContentSettingsMap()
+ ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_ALLOW);
+ EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
+ instant_controller()->profile()->GetHostContentSettingsMap()
+ ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_BLOCK);
+ EXPECT_FALSE(instant_controller()->IsJavascriptEnabled());
+}
+
+TEST_F(InstantControllerTest, IsJavascriptEnabledChecksPrefs) {
+ instant_controller()->set_override_javascript_enabled(false);
+ instant_controller()->profile()->GetPrefs()->SetBoolean(
+ prefs::kWebKitJavascriptEnabled, true);
+ EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
+ instant_controller()->profile()->GetPrefs()->SetBoolean(
+ prefs::kWebKitJavascriptEnabled, false);
+ EXPECT_FALSE(instant_controller()->IsJavascriptEnabled());
+}
diff --git a/chrome/browser/ui/search/instant_page.cc b/chrome/browser/ui/search/instant_page.cc
index 8568d2e..356ecd0 100644
--- a/chrome/browser/ui/search/instant_page.cc
+++ b/chrome/browser/ui/search/instant_page.cc
@@ -25,6 +25,10 @@ bool InstantPage::supports_instant() const {
return supports_instant_;
}
+const std::string& InstantPage::instant_url() const {
+ return instant_url_;
+}
+
bool InstantPage::IsLocal() const {
return contents() &&
(contents()->GetURL() == GURL(chrome::kChromeSearchLocalNtpUrl) ||
diff --git a/chrome/browser/ui/search/instant_page.h b/chrome/browser/ui/search/instant_page.h
index 5bb3045..341defc 100644
--- a/chrome/browser/ui/search/instant_page.h
+++ b/chrome/browser/ui/search/instant_page.h
@@ -111,7 +111,7 @@ class InstantPage : public content::WebContentsObserver {
// Returns the Instant URL that was loaded for this page. Returns the empty
// string if no URL was explicitly loaded as is the case for InstantTab.
- const std::string& instant_url() const { return instant_url_; }
+ virtual const std::string& instant_url() const;
// Returns true if the page is known to support the Instant API. This starts
// out false, and is set to true whenever we get any message from the page.
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index d6c2d91..1658339 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -15001,6 +15001,7 @@ other types of suffix sets.
<int value="3" label="Page not current: origin/path mismatch"/>
<int value="4" label="Page not current: instant not supported"/>
<int value="5" label="No overlay"/>
+ <int value="6" label="Javascript disabled"/>
</enum>
<enum name="InstantExtended_InstantNavigation" type="int">