summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsamarth@chromium.org <samarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-28 00:36:39 +0000
committersamarth@chromium.org <samarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-28 00:36:39 +0000
commit33c867665307e75078bea129ea7cf2a94fda1395 (patch)
tree10205b378a6c37a4d022d0553cffb8d78a9dc608
parent8afcc5a5e98a4c944260dfe3cfbef5a36321466e (diff)
downloadchromium_src-33c867665307e75078bea129ea7cf2a94fda1395.zip
chromium_src-33c867665307e75078bea129ea7cf2a94fda1395.tar.gz
chromium_src-33c867665307e75078bea129ea7cf2a94fda1395.tar.bz2
InstantExtended: fall back to offline NTP if Instant NTP not ready.
BUG=190190 COLLABORATOR=shishir@chromium.org Review URL: https://chromiumcodereview.appspot.com/12578006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191076 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/search/search.cc21
-rw-r--r--chrome/browser/search/search.h4
-rw-r--r--chrome/browser/ui/search/instant_controller.cc115
-rw-r--r--chrome/browser/ui/search/instant_controller.h16
-rw-r--r--chrome/browser/ui/search/instant_overlay.cc4
-rw-r--r--chrome/browser/ui/search/instant_overlay.h4
-rw-r--r--chrome/browser/ui/search/instant_page.cc11
-rw-r--r--chrome/browser/ui/search/instant_page.h8
8 files changed, 119 insertions, 64 deletions
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index b8c16dc..cf5a50f 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -55,6 +55,9 @@ const char kInstantExtendedActivationName[] = "instant";
const InstantExtendedDefault kInstantExtendedActivationDefault =
INSTANT_DEFAULT_ON;
+// Key for specifying local NTP beahvior trials.
+const char kLocalNTPFlagName[] = "local_ntp";
+
// Constants for the field trial name and group prefix.
const char kInstantExtendedFieldTrialName[] = "InstantExtended";
const char kGroupNumberPrefix[] = "Group";
@@ -447,6 +450,24 @@ bool IsInstantEnabled(Profile* profile) {
return GetInstantURL(profile, kDisableStartMargin).is_valid();
}
+bool IsAggressiveLocalNTPFallbackEnabled() {
+ // Check the command-line/about:flags setting first, which should have
+ // precedence and allows the trial to not be reported (if it's never queried).
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDisableInstantExtendedAPI) ||
+ command_line->HasSwitch(switches::kEnableInstantExtendedAPI)) {
+ return false;
+ }
+
+ FieldTrialFlags flags;
+ if (GetFieldTrialInfo(
+ base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName),
+ &flags, NULL)) {
+ return GetBoolValueForFlagWithDefault(kLocalNTPFlagName, false, flags);
+ }
+ return false;
+}
+
void EnableInstantExtendedAPIForTesting() {
CommandLine* cl = CommandLine::ForCurrentProcess();
cl->AppendSwitch(switches::kEnableInstantExtendedAPI);
diff --git a/chrome/browser/search/search.h b/chrome/browser/search/search.h
index ee9dfb62..bec267e 100644
--- a/chrome/browser/search/search.h
+++ b/chrome/browser/search/search.h
@@ -105,6 +105,10 @@ GURL GetInstantURL(Profile* profile, int start_margin);
// lead to an infinite recursion.
bool IsInstantEnabled(Profile* profile);
+// Returns true if the aggressive local NTP fallback is enabled in field
+// trials.
+bool IsAggressiveLocalNTPFallbackEnabled();
+
// -----------------------------------------------------
// The following APIs are exposed for use in tests only.
// -----------------------------------------------------
diff --git a/chrome/browser/ui/search/instant_controller.cc b/chrome/browser/ui/search/instant_controller.cc
index fd7f30d..e1e3551 100644
--- a/chrome/browser/ui/search/instant_controller.cc
+++ b/chrome/browser/ui/search/instant_controller.cc
@@ -277,7 +277,7 @@ bool InstantController::Update(const AutocompleteMatch& match,
// DCHECKs below because |user_text| and |full_text| have different semantics
// when keyword search is in effect.
if (is_keyword_search) {
- if (instant_tab_)
+ if (UseInstantTabToShowSuggestions())
instant_tab_->Update(string16(), 0, 0, true);
else
HideOverlay();
@@ -330,7 +330,8 @@ bool InstantController::Update(const AutocompleteMatch& match,
// If we have an |instant_tab_| use it, else ensure we have an overlay that is
// current or is using the local overlay.
- if (!instant_tab_ && !(overlay_ && overlay_->IsUsingLocalOverlay()) &&
+ if (!UseInstantTabToShowSuggestions() &&
+ !(overlay_ && overlay_->IsLocalOverlay()) &&
!EnsureOverlayIsCurrent(false)) {
HideOverlay();
return false;
@@ -341,7 +342,7 @@ bool InstantController::Update(const AutocompleteMatch& match,
if (!user_input_in_progress) {
// If the user isn't typing and the omnibox popup is closed, it means a
// regular navigation, tab-switch or the user hitting Escape.
- if (instant_tab_) {
+ if (UseInstantTabToShowSuggestions()) {
// The user is on a search results page. It may be showing results for
// a partial query the user typed before they hit Escape. Send the
// omnibox text to the page to restore the original results.
@@ -365,7 +366,7 @@ bool InstantController::Update(const AutocompleteMatch& match,
last_omnibox_text_.clear();
last_user_text_.clear();
last_suggestion_ = InstantSuggestion();
- if (instant_tab_) {
+ if (UseInstantTabToShowSuggestions()) {
// On a search results page, tell it to clear old results.
instant_tab_->Update(string16(), 0, 0, true);
} else if (search_mode_.is_origin_ntp()) {
@@ -395,7 +396,7 @@ bool InstantController::Update(const AutocompleteMatch& match,
last_omnibox_text_.clear();
last_user_text_.clear();
last_suggestion_ = InstantSuggestion();
- if (instant_tab_)
+ if (UseInstantTabToShowSuggestions())
instant_tab_->Update(string16(), 0, 0, true);
else if (search_mode_.is_origin_ntp())
overlay_->Update(string16(), 0, 0, true);
@@ -450,7 +451,7 @@ bool InstantController::Update(const AutocompleteMatch& match,
if (!extended_enabled_)
search_mode_.mode = SearchMode::MODE_SEARCH_SUGGESTIONS;
- if (instant_tab_) {
+ if (UseInstantTabToShowSuggestions()) {
// If we have an |instant_tab_| but it doesn't support Instant yet, sever
// the connection to it so we use the overlay instead. This ensures that the
// user interaction will be responsive and handles cases where
@@ -461,7 +462,7 @@ bool InstantController::Update(const AutocompleteMatch& match,
instant_tab_.reset();
}
- if (!instant_tab_) {
+ if (!UseInstantTabToShowSuggestions()) {
if (first_interaction_time_.is_null())
first_interaction_time_ = base::Time::Now();
allow_overlay_to_show_search_suggestions_ = true;
@@ -469,7 +470,7 @@ bool InstantController::Update(const AutocompleteMatch& match,
// For extended mode, if the loader is not ready at this point, switch over
// to a backup loader.
if (extended_enabled_ && !overlay_->supports_instant() &&
- !overlay_->IsUsingLocalOverlay() && browser_->GetActiveWebContents()) {
+ !overlay_->IsLocalOverlay() && browser_->GetActiveWebContents()) {
CreateOverlay(chrome::kChromeSearchLocalOmniboxPopupURL,
browser_->GetActiveWebContents());
}
@@ -491,25 +492,20 @@ bool InstantController::Update(const AutocompleteMatch& match,
}
scoped_ptr<content::WebContents> InstantController::ReleaseNTPContents() {
- if (!extended_enabled_)
+ if (!extended_enabled_ || use_local_overlay_only_)
return scoped_ptr<content::WebContents>(NULL);
LOG_INSTANT_DEBUG_EVENT(this, "ReleaseNTPContents");
- // Don't use the Instant NTP if it doesn't match the current Instant URL.
- std::string instant_url;
- if (!GetInstantURL(browser_->profile(), false, &instant_url) ||
- (ntp_ &&
- !MatchesOriginAndPath(GURL(ntp_->instant_url()), GURL(instant_url)))) {
- ntp_.reset();
- }
+ if (ShouldSwitchToLocalNTP())
+ ResetNTP(false, true);
scoped_ptr<content::WebContents> ntp_contents;
if (ntp_)
ntp_contents = ntp_->ReleaseContents();
// Override the blacklist on an explicit user action.
- ResetNTP(true);
+ ResetNTP(true, false);
return ntp_contents.Pass();
}
@@ -568,7 +564,7 @@ void InstantController::HandleAutocompleteResults(
// Unless we are talking to the local overlay, skip SearchProvider, since
// it only echoes suggestions.
if (from_search_provider &&
- (instant_tab_ || !overlay_->IsUsingLocalOverlay()))
+ (UseInstantTabToShowSuggestions() || !overlay_->IsLocalOverlay()))
continue;
// Only send autocomplete results when all the providers are done. Skip
// this check for the SearchProvider, since it isn't done until the page
@@ -600,7 +596,7 @@ void InstantController::HandleAutocompleteResults(
"HandleAutocompleteResults: total_results=%d",
static_cast<int>(results.size())));
- if (instant_tab_)
+ if (UseInstantTabToShowSuggestions())
instant_tab_->SendAutocompleteResults(results);
else
overlay_->SendAutocompleteResults(results);
@@ -613,7 +609,7 @@ bool InstantController::OnUpOrDownKeyPressed(int count) {
if (!instant_tab_ && !overlay_)
return false;
- if (instant_tab_)
+ if (UseInstantTabToShowSuggestions())
instant_tab_->UpOrDownKeyPressed(count);
else
overlay_->UpOrDownKeyPressed(count);
@@ -638,7 +634,7 @@ void InstantController::OnCancel(const AutocompleteMatch& match,
last_user_text_ = user_text;
last_suggestion_ = InstantSuggestion();
- if (instant_tab_)
+ if (UseInstantTabToShowSuggestions())
instant_tab_->CancelSelection(full_text);
else
overlay_->CancelSelection(full_text);
@@ -666,7 +662,7 @@ bool InstantController::CommitIfPossible(InstantCommitType type) {
// If we are on an already committed search results page, send a submit event
// to the page, but otherwise, nothing else to do.
- if (instant_tab_) {
+ if (UseInstantTabToShowSuggestions()) {
if (type == INSTANT_COMMIT_PRESSED_ENTER &&
(last_match_was_search_ ||
last_suggestion_.behavior == INSTANT_COMPLETE_NEVER)) {
@@ -695,7 +691,7 @@ bool InstantController::CommitIfPossible(InstantCommitType type) {
return false;
// Never commit the local overlay.
- if (overlay_->IsUsingLocalOverlay())
+ if (overlay_->IsLocalOverlay())
return false;
if (type == INSTANT_COMMIT_FOCUS_LOST) {
@@ -892,7 +888,7 @@ void InstantController::SetInstantEnabled(bool instant_enabled,
if (extended_enabled_ || instant_enabled_)
EnsureOverlayIsCurrent(false);
if (extended_enabled_)
- ResetNTP(false);
+ ResetNTP(false, false);
if (instant_tab_)
instant_tab_->SetDisplayInstantResults(instant_enabled_);
}
@@ -924,7 +920,7 @@ void InstantController::FocusedOverlayContents() {
void InstantController::ReloadOverlayIfStale() {
// The local overlay is never stale.
- if (overlay_ && overlay_->IsUsingLocalOverlay())
+ if (overlay_ && overlay_->IsLocalOverlay())
return;
// If the overlay is showing or the omnibox has focus, don't delete the
@@ -1114,7 +1110,8 @@ void InstantController::SetSuggestions(
// Ignore if the message is from an unexpected source.
if (IsContentsFrom(ntp(), contents))
return;
- if (instant_tab_ && !IsContentsFrom(instant_tab(), contents))
+ if (UseInstantTabToShowSuggestions() &&
+ !IsContentsFrom(instant_tab(), contents))
return;
if (IsContentsFrom(overlay(), contents) &&
!allow_overlay_to_show_search_suggestions_)
@@ -1124,22 +1121,11 @@ void InstantController::SetSuggestions(
if (!suggestions.empty())
suggestion = suggestions[0];
- if (instant_tab_ &&
- (search_mode_.is_search_results() || search_mode_.is_ntp()) &&
- suggestion.behavior == INSTANT_COMPLETE_REPLACE) {
- // Update |last_omnibox_text_| so that the controller commits the proper
- // query if the user focuses the omnibox and presses Enter.
- last_omnibox_text_ = suggestion.text;
- last_suggestion_ = InstantSuggestion();
- last_match_was_search_ = suggestion.type == INSTANT_SUGGESTION_SEARCH;
- // This means a committed page in state search called setValue(). We should
- // update the omnibox to reflect what the search page says.
- browser_->SetInstantSuggestion(suggestion);
- return;
- }
-
- // Ignore if we are not currently accepting search suggestions.
- if (!search_mode_.is_search_suggestions() || last_omnibox_text_.empty())
+ bool can_use_instant_tab = UseInstantTabToShowSuggestions() &&
+ !search_mode_.is_default();
+ bool can_use_overlay = search_mode_.is_search_suggestions() &&
+ !last_omnibox_text_.empty();
+ if (!can_use_instant_tab && !can_use_overlay)
return;
if (suggestion.behavior == INSTANT_COMPLETE_REPLACE) {
@@ -1243,7 +1229,7 @@ void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) {
if (model_.mode().is_default()) {
// Correct search terms if the user clicked on the committed results page
// while showing an autocomplete suggestion
- if (instant_tab_ && !last_suggestion_.text.empty() &&
+ if (UseInstantTabToShowSuggestions() && !last_suggestion_.text.empty() &&
last_suggestion_.behavior == INSTANT_COMPLETE_NEVER &&
IsViewInContents(GetViewGainingFocus(view_gaining_focus),
instant_tab_->contents())) {
@@ -1279,18 +1265,16 @@ void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) {
#endif
}
-void InstantController::ResetNTP(bool ignore_blacklist) {
+void InstantController::ResetNTP(bool ignore_blacklist, bool use_local_ntp) {
ntp_.reset();
std::string instant_url;
- if (browser_->profile()->IsOffTheRecord() ||
- !GetInstantURL(browser_->profile(), ignore_blacklist, &instant_url)) {
- // TODO(sreeram|samarth): use local ntp here once available.
- return;
- }
+ if (use_local_ntp ||
+ !GetInstantURL(browser_->profile(), ignore_blacklist, &instant_url))
+ instant_url = chrome::kChromeSearchLocalNtpUrl;
ntp_.reset(new InstantNTP(this, instant_url));
ntp_->InitContents(browser_->profile(), browser_->GetActiveWebContents(),
base::Bind(&InstantController::ResetNTP,
- base::Unretained(this), false));
+ base::Unretained(this), false, false));
}
bool InstantController::EnsureOverlayIsCurrent(bool ignore_blacklist) {
@@ -1386,7 +1370,7 @@ void InstantController::HideInternal() {
void InstantController::ShowOverlay(int height, InstantSizeUnits units) {
// If we are on a committed search results page, the |overlay_| is not in use.
- if (instant_tab_)
+ if (UseInstantTabToShowSuggestions())
return;
LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
@@ -1415,7 +1399,7 @@ void InstantController::ShowOverlay(int height, InstantSizeUnits units) {
// - Instant is disabled. The page needs to be able to show only a dropdown.
// - The page is over a website other than search or an NTP, and is not
// already showing at 100% height.
- if (overlay_->IsUsingLocalOverlay() || !instant_enabled_ ||
+ if (overlay_->IsLocalOverlay() || !instant_enabled_ ||
(search_mode_.is_origin_default() && !IsFullHeight(model_)))
model_.SetOverlayState(search_mode_, height, units);
else
@@ -1493,7 +1477,7 @@ void InstantController::BlacklistAndResetNTP() {
RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
delete ntp_->ReleaseContents().release();
MessageLoop::current()->DeleteSoon(FROM_HERE, ntp_.release());
- ResetNTP(false);
+ ResetNTP(false, false);
}
void InstantController::BlacklistAndResetOverlay() {
@@ -1630,3 +1614,28 @@ bool InstantController::FixSuggestion(InstantSuggestion* suggestion) const {
return false;
}
+
+bool InstantController::UseInstantTabToShowSuggestions() const {
+ return instant_tab_ && !instant_tab_->IsLocalNTP();
+}
+
+bool InstantController::ShouldSwitchToLocalNTP() const {
+ // If there is no NTP, or no Instant URL or the NTP is stale, switch.
+ std::string instant_url;
+ if (!ntp_ || !GetInstantURL(browser_->profile(), false, &instant_url) ||
+ !MatchesOriginAndPath(GURL(ntp_->instant_url()), GURL(instant_url))) {
+ return true;
+ }
+
+ if (ntp_->supports_instant())
+ return false;
+
+ // If this is not window startup, switch.
+ // TODO(shishir): This is not completely reliable. Find a better way to detect
+ // startup time.
+ if (browser_->GetActiveWebContents())
+ return true;
+
+ return chrome::IsAggressiveLocalNTPFallbackEnabled();
+}
+
diff --git a/chrome/browser/ui/search/instant_controller.h b/chrome/browser/ui/search/instant_controller.h
index b2ca248..ecd333e 100644
--- a/chrome/browser/ui/search/instant_controller.h
+++ b/chrome/browser/ui/search/instant_controller.h
@@ -272,14 +272,15 @@ class InstantController : public InstantPage::Delegate,
void OmniboxLostFocus(gfx::NativeView view_gaining_focus);
// Creates a new NTP, using the instant_url property of the default
- // TemplateURL.
- void ResetNTP(bool ignore_blacklist);
+ // TemplateURL, or chrome::kChromeSearchLocalNTPURL if |use_local_ntp| is
+ // true. For |ignore_blacklist| look at comments in GetInstantURL().
+ void ResetNTP(bool ignore_blacklist, bool use_local_ntp);
// Ensures that |overlay_| uses the Instant URL returned by GetInstantURL(),
// creating a new overlay if necessary. In extended mode, will fallback to
// using the kLocalOmniboxPopupURL as the Instant URL in case GetInstantURL()
// returns false. Returns true if an Instant URL could be determined.
- // For |ignore_blacklist| look at comments in |GetInstantURL|.
+ // For |ignore_blacklist| look at comments in GetInstantURL().
bool EnsureOverlayIsCurrent(bool ignore_blacklist);
// Recreates the |overlay_| with |instant_url|. Note that |overlay_| is
@@ -362,6 +363,15 @@ class InstantController : public InstantPage::Delegate,
// returns false.)
bool FixSuggestion(InstantSuggestion* suggestion) const;
+ // Returns true if we should use |instant_tab_| instead of |overlay_| for
+ // handling suggestions.
+ // TODO(samarth|sreeram): this is brittle. Instead, we should probably just
+ // combine the two local pages into one.
+ bool UseInstantTabToShowSuggestions() const;
+
+ // Returns true if we should switch to using the local NTP.
+ bool ShouldSwitchToLocalNTP() const;
+
BrowserInstantController* const browser_;
// Whether the extended API and regular API are enabled. If both are false,
diff --git a/chrome/browser/ui/search/instant_overlay.cc b/chrome/browser/ui/search/instant_overlay.cc
index 352bfbc..fa22139 100644
--- a/chrome/browser/ui/search/instant_overlay.cc
+++ b/chrome/browser/ui/search/instant_overlay.cc
@@ -72,10 +72,6 @@ void InstantOverlay::DidNavigate(
last_navigation_ = add_page_args;
}
-bool InstantOverlay::IsUsingLocalOverlay() const {
- return instant_url_ == chrome::kChromeSearchLocalOmniboxPopupURL;
-}
-
void InstantOverlay::Update(const string16& text,
size_t selection_start,
size_t selection_end,
diff --git a/chrome/browser/ui/search/instant_overlay.h b/chrome/browser/ui/search/instant_overlay.h
index f20a986..5894f80 100644
--- a/chrome/browser/ui/search/instant_overlay.h
+++ b/chrome/browser/ui/search/instant_overlay.h
@@ -67,10 +67,6 @@ class InstantOverlay : public InstantPage,
// to the history service had this WebContents not been used for Instant.
void DidNavigate(const history::HistoryAddPageArgs& add_page_args);
- // Returns true if the overlay is using
- // InstantController::kLocalOmniboxPopupURL as the |instant_url_|.
- bool IsUsingLocalOverlay() const;
-
// Overridden from InstantPage:
virtual void Update(const string16& text,
size_t selection_start,
diff --git a/chrome/browser/ui/search/instant_page.cc b/chrome/browser/ui/search/instant_page.cc
index 764a565..8c12ae7 100644
--- a/chrome/browser/ui/search/instant_page.cc
+++ b/chrome/browser/ui/search/instant_page.cc
@@ -6,6 +6,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/common/render_messages.h"
+#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font.h"
@@ -16,6 +17,16 @@ InstantPage::Delegate::~Delegate() {
InstantPage::~InstantPage() {
}
+bool InstantPage::IsLocalNTP() const {
+ return contents() &&
+ contents()->GetURL() == GURL(chrome::kChromeSearchLocalNtpUrl);
+}
+
+bool InstantPage::IsLocalOverlay() const {
+ return contents() &&
+ contents()->GetURL() == GURL(chrome::kChromeSearchLocalOmniboxPopupURL);
+}
+
void InstantPage::Update(const string16& text,
size_t selection_start,
size_t selection_end,
diff --git a/chrome/browser/ui/search/instant_page.h b/chrome/browser/ui/search/instant_page.h
index 6564945..caaf8d2 100644
--- a/chrome/browser/ui/search/instant_page.h
+++ b/chrome/browser/ui/search/instant_page.h
@@ -114,6 +114,14 @@ class InstantPage : public content::WebContentsObserver {
// support suddenly).
bool supports_instant() const { return supports_instant_; }
+ // Returns true if the page is the local NTP (i.e. its URL is
+ // chrome::kChromeSearchLocalNTPURL).
+ bool IsLocalNTP() const;
+
+ // Returns true if the page is the local overlay (i.e. its URL is
+ // chrome::kChromeSearchLocalOmniboxPopupURL).
+ bool IsLocalOverlay() const;
+
// Tells the page that the user typed |text| into the omnibox. If |verbatim|
// is false, the page predicts the query the user means to type and fetches
// results for the prediction. If |verbatim| is true, |text| is taken as the