Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: chrome/browser/ui/search/instant_controller.cc

Issue 14043009: Fall back to local page if online NTP fails to load. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix failing unittest & address comments Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/search/instant_controller.h" 5 #include "chrome/browser/ui/search/instant_controller.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/stringprintf.h" 9 #include "base/stringprintf.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 } 705 }
706 706
707 void InstantController::OmniboxNavigateToURL() { 707 void InstantController::OmniboxNavigateToURL() {
708 if (!extended_enabled_) 708 if (!extended_enabled_)
709 return; 709 return;
710 RecordNavigationHistogram(UsingLocalPage(), false); 710 RecordNavigationHistogram(UsingLocalPage(), false);
711 if (instant_tab_) 711 if (instant_tab_)
712 instant_tab_->Submit(string16()); 712 instant_tab_->Submit(string16());
713 } 713 }
714 714
715 void InstantController::InstantPageLoadFailed(content::WebContents* contents) {
716 if (!chrome::ShouldPreferRemoteNTPOnStartup() || !extended_enabled_) {
717 // We only need to fall back on errors if we're showing the online page
718 // at startup, as otherwise we fall back correctly when trying to show
719 // a page that hasn't yet indicated that it supports the InstantExtended
720 // API.
721 return;
722 }
723
724 if (IsContentsFrom(instant_tab(), contents)) {
725 // Verify we're not already on a local page and that the URL precisely
726 // equals the instant_url (minus the query params, as those will be filled
727 // in by template values). This check is necessary to make sure we don't
728 // inadvertently redirect to the local NTP if someone, say, reloads a SRP
729 // while offline, as a committed results page still counts as an instant
730 // url. We also check to make sure there's no forward history, as if
731 // someone hits the back button a lot when offline and returns to a NTP
732 // we don't want to redirect and nuke their forward history stack.
733 const GURL& current_url = contents->GetURL();
734 if (instant_tab_->IsLocal() ||
735 !chrome::MatchesOriginAndPath(GURL(GetInstantURL()), current_url) ||
736 !current_url.ref().empty() ||
737 contents->GetController().CanGoForward())
738 return;
739 LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: instant_tab");
740 RedirectToLocalNTP(contents);
741 } else if (IsContentsFrom(ntp(), contents)) {
742 LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: ntp");
743 bool is_local = ntp_->IsLocal();
744 DeletePageSoon(ntp_.Pass());
745 if (!is_local)
746 ResetNTP(GetLocalInstantURL());
747 } else if (IsContentsFrom(overlay(), contents)) {
748 LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: overlay");
749 bool is_local = overlay_->IsLocal();
750 DeletePageSoon(overlay_.Pass());
751 if (!is_local)
752 ResetOverlay(GetLocalInstantURL());
753 }
754 }
755
715 content::WebContents* InstantController::GetOverlayContents() const { 756 content::WebContents* InstantController::GetOverlayContents() const {
716 return overlay_ ? overlay_->contents() : NULL; 757 return overlay_ ? overlay_->contents() : NULL;
717 } 758 }
718 759
719 bool InstantController::IsOverlayingSearchResults() const { 760 bool InstantController::IsOverlayingSearchResults() const {
720 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && 761 return model_.mode().is_search_suggestions() && IsFullHeight(model_) &&
721 (last_match_was_search_ || 762 (last_match_was_search_ ||
722 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); 763 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER);
723 } 764 }
724 765
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 bool supports_instant) { 1170 bool supports_instant) {
1130 if (IsContentsFrom(instant_tab(), contents)) { 1171 if (IsContentsFrom(instant_tab(), contents)) {
1131 if (!supports_instant) 1172 if (!supports_instant)
1132 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); 1173 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release());
1133 1174
1134 content::NotificationService::current()->Notify( 1175 content::NotificationService::current()->Notify(
1135 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, 1176 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
1136 content::Source<InstantController>(this), 1177 content::Source<InstantController>(this),
1137 content::NotificationService::NoDetails()); 1178 content::NotificationService::NoDetails());
1138 } else if (IsContentsFrom(ntp(), contents)) { 1179 } else if (IsContentsFrom(ntp(), contents)) {
1139 if (!supports_instant) 1180 if (!supports_instant) {
1181 bool is_local = ntp_->IsLocal();
1140 DeletePageSoon(ntp_.Pass()); 1182 DeletePageSoon(ntp_.Pass());
1183 // Preload a local NTP in place of the broken online one.
1184 if (!is_local)
1185 ResetNTP(GetLocalInstantURL());
1186 }
1141 1187
1142 content::NotificationService::current()->Notify( 1188 content::NotificationService::current()->Notify(
1143 chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED, 1189 chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED,
1144 content::Source<InstantController>(this), 1190 content::Source<InstantController>(this),
1145 content::NotificationService::NoDetails()); 1191 content::NotificationService::NoDetails());
1146 1192
1147 } else if (IsContentsFrom(overlay(), contents)) { 1193 } else if (IsContentsFrom(overlay(), contents)) {
1148 if (!supports_instant) { 1194 if (!supports_instant) {
1149 HideInternal(); 1195 HideInternal();
1196 bool is_local = overlay_->IsLocal();
1150 DeletePageSoon(overlay_.Pass()); 1197 DeletePageSoon(overlay_.Pass());
1198 // Preload a local overlay in place of the broken online one.
1199 if (!is_local && extended_enabled_)
1200 ResetOverlay(GetLocalInstantURL());
1151 } 1201 }
1152 1202
1153 content::NotificationService::current()->Notify( 1203 content::NotificationService::current()->Notify(
1154 chrome::NOTIFICATION_INSTANT_OVERLAY_SUPPORT_DETERMINED, 1204 chrome::NOTIFICATION_INSTANT_OVERLAY_SUPPORT_DETERMINED,
1155 content::Source<InstantController>(this), 1205 content::Source<InstantController>(this),
1156 content::NotificationService::NoDetails()); 1206 content::NotificationService::NoDetails());
1157 } 1207 }
1158 } 1208 }
1159 1209
1160 void InstantController::InstantPageRenderViewGone( 1210 void InstantController::InstantPageRenderViewGone(
1161 const content::WebContents* contents) { 1211 const content::WebContents* contents) {
1162 if (IsContentsFrom(overlay(), contents)) { 1212 if (IsContentsFrom(overlay(), contents)) {
1163 HideInternal(); 1213 HideInternal();
1164 DeletePageSoon(overlay_.Pass()); 1214 DeletePageSoon(overlay_.Pass());
1165 } else if (IsContentsFrom(ntp(), contents)) { 1215 } else if (IsContentsFrom(ntp(), contents)) {
1166 DeletePageSoon(ntp_.Pass()); 1216 DeletePageSoon(ntp_.Pass());
1167 } else { 1217 } else {
1168 NOTREACHED(); 1218 NOTREACHED();
1169 } 1219 }
1170 } 1220 }
1171 1221
1172 void InstantController::InstantPageAboutToNavigateMainFrame( 1222 void InstantController::InstantPageAboutToNavigateMainFrame(
1173 const content::WebContents* contents, 1223 const content::WebContents* contents,
1174 const GURL& url) { 1224 const GURL& url) {
1175 DCHECK(IsContentsFrom(overlay(), contents)); 1225 if (IsContentsFrom(overlay(), contents)) {
1226 // If the page does not yet support Instant, we allow redirects and other
1227 // navigations to go through since the Instant URL can redirect - e.g. to
1228 // country specific pages.
1229 if (!overlay_->supports_instant())
1230 return;
1176 1231
1177 // If the page does not yet support Instant, we allow redirects and other 1232 GURL instant_url(overlay_->instant_url());
1178 // navigations to go through since the Instant URL can redirect - e.g. to
1179 // country specific pages.
1180 if (!overlay_->supports_instant())
1181 return;
1182 1233
1183 GURL instant_url(overlay_->instant_url()); 1234 // If we are navigating to the Instant URL, do nothing.
1235 if (url == instant_url)
1236 return;
1184 1237
1185 // If we are navigating to the Instant URL, do nothing. 1238 // Commit the navigation if either:
1186 if (url == instant_url) 1239 // - The page is in NTP mode (so it could only navigate on a user click) or
1187 return; 1240 // - The page is not in NTP mode and we are navigating to a URL with a
1188 1241 // different host or path than the Instant URL. This enables the instant
1189 // Commit the navigation if either: 1242 // page when it is showing search results to change the query parameters
1190 // - The page is in NTP mode (so it could only navigate on a user click) or 1243 // and fragments of the URL without it navigating.
1191 // - The page is not in NTP mode and we are navigating to a URL with a 1244 if (model_.mode().is_ntp() ||
1192 // different host or path than the Instant URL. This enables the instant 1245 (url.host() != instant_url.host() ||
1193 // page when it is showing search results to change the query parameters 1246 url.path() != instant_url.path())) {
1194 // and fragments of the URL without it navigating. 1247 CommitIfPossible(INSTANT_COMMIT_NAVIGATED);
1195 if (model_.mode().is_ntp() || 1248 }
1196 (url.host() != instant_url.host() || url.path() != instant_url.path())) { 1249 } else if (IsContentsFrom(instant_tab(), contents)) {
1197 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); 1250 // The Instant tab navigated. Send it the data it needs to display
1251 // properly.
1252 UpdateInfoForInstantTab();
1253 } else {
1254 NOTREACHED();
1198 } 1255 }
1199 } 1256 }
1200 1257
1201 void InstantController::SetSuggestions( 1258 void InstantController::SetSuggestions(
1202 const content::WebContents* contents, 1259 const content::WebContents* contents,
1203 const std::vector<InstantSuggestion>& suggestions) { 1260 const std::vector<InstantSuggestion>& suggestions) {
1204 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); 1261 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions");
1205 1262
1206 // Ignore if the message is from an unexpected source. 1263 // Ignore if the message is from an unexpected source.
1207 if (IsContentsFrom(ntp(), contents)) 1264 if (IsContentsFrom(ntp(), contents))
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 1502
1446 void InstantController::ResetInstantTab() { 1503 void InstantController::ResetInstantTab() {
1447 // Do not wire up the InstantTab in Incognito, to prevent it from sending data 1504 // Do not wire up the InstantTab in Incognito, to prevent it from sending data
1448 // to the page. 1505 // to the page.
1449 if (!search_mode_.is_origin_default() && 1506 if (!search_mode_.is_origin_default() &&
1450 !browser_->profile()->IsOffTheRecord()) { 1507 !browser_->profile()->IsOffTheRecord()) {
1451 content::WebContents* active_tab = browser_->GetActiveWebContents(); 1508 content::WebContents* active_tab = browser_->GetActiveWebContents();
1452 if (!instant_tab_ || active_tab != instant_tab_->contents()) { 1509 if (!instant_tab_ || active_tab != instant_tab_->contents()) {
1453 instant_tab_.reset(new InstantTab(this)); 1510 instant_tab_.reset(new InstantTab(this));
1454 instant_tab_->Init(active_tab); 1511 instant_tab_->Init(active_tab);
1455 // Update theme info for this tab. 1512 UpdateInfoForInstantTab();
1456 browser_->UpdateThemeInfo();
1457 instant_tab_->SetDisplayInstantResults(instant_enabled_);
1458 instant_tab_->SetOmniboxBounds(omnibox_bounds_);
1459 instant_tab_->InitializeFonts();
1460 StartListeningToMostVisitedChanges();
1461 instant_tab_->KeyCaptureChanged(
1462 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
1463 } 1513 }
1464 1514
1465 // Hide the |overlay_| since we are now using |instant_tab_| instead. 1515 // Hide the |overlay_| since we are now using |instant_tab_| instead.
1466 HideOverlay(); 1516 HideOverlay();
1467 } else { 1517 } else {
1468 instant_tab_.reset(); 1518 instant_tab_.reset();
1469 } 1519 }
1470 } 1520 }
1471 1521
1522 void InstantController::UpdateInfoForInstantTab() {
1523 if (instant_tab_) {
1524 browser_->UpdateThemeInfo();
1525 instant_tab_->SetDisplayInstantResults(instant_enabled_);
1526 instant_tab_->SetOmniboxBounds(omnibox_bounds_);
1527 instant_tab_->InitializeFonts();
1528 StartListeningToMostVisitedChanges();
1529 instant_tab_->KeyCaptureChanged(
1530 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
1531 }
1532 }
1533
1472 void InstantController::HideOverlay() { 1534 void InstantController::HideOverlay() {
1473 HideInternal(); 1535 HideInternal();
1474 ReloadOverlayIfStale(); 1536 ReloadOverlayIfStale();
1475 } 1537 }
1476 1538
1477 void InstantController::HideInternal() { 1539 void InstantController::HideInternal() {
1478 LOG_INSTANT_DEBUG_EVENT(this, "Hide"); 1540 LOG_INSTANT_DEBUG_EVENT(this, "Hide");
1479 1541
1480 // If GetOverlayContents() returns NULL, either we're already in the desired 1542 // If GetOverlayContents() returns NULL, either we're already in the desired
1481 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't 1543 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 } 1747 }
1686 } 1748 }
1687 1749
1688 return false; 1750 return false;
1689 } 1751 }
1690 1752
1691 bool InstantController::UsingLocalPage() const { 1753 bool InstantController::UsingLocalPage() const {
1692 return (instant_tab_ && instant_tab_->IsLocal()) || 1754 return (instant_tab_ && instant_tab_->IsLocal()) ||
1693 (!instant_tab_ && overlay_ && overlay_->IsLocal()); 1755 (!instant_tab_ && overlay_ && overlay_->IsLocal());
1694 } 1756 }
1757
1758 void InstantController::RedirectToLocalNTP(content::WebContents* contents) {
1759 contents->GetController().LoadURL(
1760 chrome::GetLocalInstantURL(browser_->profile()),
1761 content::Referrer(),
1762 content::PAGE_TRANSITION_SERVER_REDIRECT,
1763 std::string()); // No extra headers.
1764 // TODO(dcblack): Remove extraneous history entry caused by 404s.
1765 // Note that the base case of a 204 being returned doesn't push a history
1766 // entry.
1767 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/search/instant_controller.h ('k') | chrome/browser/ui/search/instant_extended_interactive_uitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698