blob: 8344448f5904d55a508c3cfa4a2b6b0dc989e7d5 [file] [log] [blame]
[email protected]e41982a72012-11-20 07:16:511// Copyright 2012 The Chromium Authors. All rights reserved.
[email protected]7acfaf92012-07-11 15:51:592// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/browser_instant_controller.h"
6
[email protected]0a46856e2013-04-24 00:33:027#include "base/bind.h"
sky4bdad242014-09-18 20:22:208#include "chrome/browser/infobars/infobar_service.h"
[email protected]7acfaf92012-07-11 15:51:599#include "chrome/browser/profiles/profile.h"
[email protected]0a46856e2013-04-24 00:33:0210#include "chrome/browser/search/instant_service.h"
11#include "chrome/browser/search/instant_service_factory.h"
[email protected]a7b8e43d2013-03-18 18:52:4312#include "chrome/browser/search/search.h"
[email protected]7acfaf92012-07-11 15:51:5913#include "chrome/browser/ui/browser.h"
[email protected]7acfaf92012-07-11 15:51:5914#include "chrome/browser/ui/browser_window.h"
[email protected]d57ce6a2014-07-03 15:39:2315#include "chrome/browser/ui/location_bar/location_bar.h"
[email protected]6cf51b62013-08-10 13:49:2216#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
[email protected]c18cb672012-12-05 04:42:1217#include "chrome/browser/ui/omnibox/omnibox_view.h"
[email protected]e97887c2013-12-11 01:27:3118#include "chrome/browser/ui/search/instant_search_prerenderer.h"
[email protected]4066a695d2013-06-20 14:08:5419#include "chrome/browser/ui/search/search_model.h"
[email protected]9d3d11702012-11-08 01:01:1220#include "chrome/browser/ui/search/search_tab_helper.h"
[email protected]e41982a72012-11-20 07:16:5121#include "chrome/browser/ui/tabs/tab_strip_model.h"
kmadhusu562c49c82014-11-18 02:08:0322#include "chrome/common/instant_types.h"
[email protected]0c9406632013-02-08 01:13:3323#include "chrome/common/url_constants.h"
mathp880d3282015-02-20 00:10:0524#include "content/public/browser/navigation_controller.h"
[email protected]0a46856e2013-04-24 00:33:0225#include "content/public/browser/render_process_host.h"
[email protected]233f0f962013-02-27 21:14:1926#include "content/public/browser/user_metrics.h"
[email protected]0a46856e2013-04-24 00:33:0227#include "content/public/browser/web_contents.h"
mathp880d3282015-02-20 00:10:0528#include "content/public/common/referrer.h"
29#include "ui/base/page_transition_types.h"
[email protected]c4b2af22014-05-11 19:48:5330
31// Helpers --------------------------------------------------------------------
[email protected]233f0f962013-02-27 21:14:1932
[email protected]e97887c2013-12-11 01:27:3133namespace {
34
35InstantSearchPrerenderer* GetInstantSearchPrerenderer(Profile* profile) {
36 DCHECK(profile);
37 InstantService* instant_service =
38 InstantServiceFactory::GetForProfile(profile);
39 return instant_service ? instant_service->instant_search_prerenderer() : NULL;
40}
41
42} // namespace
43
[email protected]c4b2af22014-05-11 19:48:5344
45// BrowserInstantController ---------------------------------------------------
[email protected]7acfaf92012-07-11 15:51:5946
47BrowserInstantController::BrowserInstantController(Browser* browser)
[email protected]8a236702012-09-28 13:30:5748 : browser_(browser),
[email protected]777590052014-01-17 22:11:5449 instant_(this) {
[email protected]0b10c9ff2012-10-09 17:31:5550 browser_->search_model()->AddObserver(this);
[email protected]4ff347e2013-07-22 19:39:0051
52 InstantService* instant_service =
53 InstantServiceFactory::GetForProfile(profile());
[email protected]c8a118e2013-09-24 21:33:4054 instant_service->AddObserver(this);
[email protected]7acfaf92012-07-11 15:51:5955}
56
57BrowserInstantController::~BrowserInstantController() {
[email protected]0b10c9ff2012-10-09 17:31:5558 browser_->search_model()->RemoveObserver(this);
[email protected]4ff347e2013-07-22 19:39:0059
60 InstantService* instant_service =
61 InstantServiceFactory::GetForProfile(profile());
[email protected]c8a118e2013-09-24 21:33:4062 instant_service->RemoveObserver(this);
[email protected]0c9406632013-02-08 01:13:3363}
64
[email protected]413558cb2013-06-10 16:44:4565bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition,
66 const GURL& url) {
[email protected]e41982a72012-11-20 07:16:5167 // Unsupported dispositions.
[email protected]413558cb2013-06-10 16:44:4568 if (disposition == NEW_BACKGROUND_TAB || disposition == NEW_WINDOW ||
69 disposition == NEW_FOREGROUND_TAB)
[email protected]7acfaf92012-07-11 15:51:5970 return false;
[email protected]7acfaf92012-07-11 15:51:5971
[email protected]7acfaf92012-07-11 15:51:5972 // The omnibox currently doesn't use other dispositions, so we don't attempt
[email protected]c72226c82012-10-01 21:02:3273 // to handle them. If you hit this DCHECK file a bug and I'll (sky) add
[email protected]7acfaf92012-07-11 15:51:5974 // support for the new disposition.
[email protected]413558cb2013-06-10 16:44:4575 DCHECK(disposition == CURRENT_TAB) << disposition;
[email protected]c72226c82012-10-01 21:02:3276
[email protected]dcd0249872013-12-06 23:58:4577 const base::string16& search_terms =
sdefresne51bbec7b2015-08-03 14:18:1378 search::ExtractSearchTermsFromURL(profile(), url);
kmadhusu562c49c82014-11-18 02:08:0379 EmbeddedSearchRequestParams request_params(url);
[email protected]413558cb2013-06-10 16:44:4580 if (search_terms.empty())
81 return false;
82
[email protected]e97887c2013-12-11 01:27:3183 InstantSearchPrerenderer* prerenderer =
84 GetInstantSearchPrerenderer(profile());
[email protected]f028cf5b2014-01-24 07:36:0385 if (prerenderer) {
86 if (prerenderer->CanCommitQuery(GetActiveWebContents(), search_terms)) {
87 // Submit query to render the prefetched results. Browser will swap the
88 // prerendered contents with the active tab contents.
kmadhusu562c49c82014-11-18 02:08:0389 prerenderer->Commit(search_terms, request_params);
[email protected]f028cf5b2014-01-24 07:36:0390 return false;
91 } else {
92 prerenderer->Cancel();
93 }
[email protected]e97887c2013-12-11 01:27:3194 }
95
[email protected]50da1902014-02-14 02:40:1996 // If we will not be replacing search terms from this URL, don't send to
97 // InstantController.
sdefresne51bbec7b2015-08-03 14:18:1398 if (!search::IsQueryExtractionAllowedForURL(profile(), url))
[email protected]50da1902014-02-14 02:40:1999 return false;
kmadhusu562c49c82014-11-18 02:08:03100 return instant_.SubmitQuery(search_terms, request_params);
[email protected]7acfaf92012-07-11 15:51:59101}
102
[email protected]0c9406632013-02-08 01:13:33103Profile* BrowserInstantController::profile() const {
104 return browser_->profile();
105}
106
[email protected]cd533bf2012-12-04 19:14:59107content::WebContents* BrowserInstantController::GetActiveWebContents() const {
108 return browser_->tab_strip_model()->GetActiveWebContents();
[email protected]7acfaf92012-07-11 15:51:59109}
110
[email protected]e41982a72012-11-20 07:16:51111void BrowserInstantController::ActiveTabChanged() {
112 instant_.ActiveTabChanged();
113}
114
[email protected]3d6a8952012-12-14 03:18:07115void BrowserInstantController::TabDeactivated(content::WebContents* contents) {
116 instant_.TabDeactivated(contents);
[email protected]e97887c2013-12-11 01:27:31117
118 InstantSearchPrerenderer* prerenderer =
119 GetInstantSearchPrerenderer(profile());
120 if (prerenderer)
121 prerenderer->Cancel();
[email protected]3d6a8952012-12-14 03:18:07122}
123
[email protected]5ee671f2013-03-19 11:23:05124void BrowserInstantController::ModelChanged(
[email protected]165fe422013-03-27 06:34:03125 const SearchModel::State& old_state,
126 const SearchModel::State& new_state) {
[email protected]4066a695d2013-06-20 14:08:54127 if (old_state.mode != new_state.mode) {
128 const SearchMode& new_mode = new_state.mode;
[email protected]5ee671f2013-03-19 11:23:05129
[email protected]a780c7b22013-08-02 18:36:59130 // Record some actions corresponding to the mode change. Note that to get
131 // the full story, it's necessary to look at other UMA actions as well,
132 // such as tab switches.
133 if (new_mode.is_search_results())
[email protected]c4b2af22014-05-11 19:48:53134 content::RecordAction(base::UserMetricsAction("InstantExtended.ShowSRP"));
[email protected]a780c7b22013-08-02 18:36:59135 else if (new_mode.is_ntp())
[email protected]c4b2af22014-05-11 19:48:53136 content::RecordAction(base::UserMetricsAction("InstantExtended.ShowNTP"));
[email protected]5ee671f2013-03-19 11:23:05137
[email protected]4066a695d2013-06-20 14:08:54138 instant_.SearchModeChanged(old_state.mode, new_mode);
[email protected]c19ba1042013-03-11 17:17:13139 }
140
[email protected]4066a695d2013-06-20 14:08:54141 if (old_state.instant_support != new_state.instant_support)
142 instant_.InstantSupportChanged(new_state.instant_support);
[email protected]7acfaf92012-07-11 15:51:59143}
144
mathp880d3282015-02-20 00:10:05145void BrowserInstantController::DefaultSearchProviderChanged(
146 bool google_base_url_domain_changed) {
[email protected]0a46856e2013-04-24 00:33:02147 InstantService* instant_service =
[email protected]c8a118e2013-09-24 21:33:40148 InstantServiceFactory::GetForProfile(profile());
[email protected]0a46856e2013-04-24 00:33:02149 if (!instant_service)
150 return;
151
152 TabStripModel* tab_model = browser_->tab_strip_model();
153 int count = tab_model->count();
154 for (int index = 0; index < count; ++index) {
155 content::WebContents* contents = tab_model->GetWebContentsAt(index);
156 if (!contents)
157 continue;
158
[email protected]2309e912013-10-01 01:33:30159 // Send new search URLs to the renderer.
160 content::RenderProcessHost* rph = contents->GetRenderProcessHost();
161 instant_service->SendSearchURLsToRenderer(rph);
[email protected]0a46856e2013-04-24 00:33:02162
[email protected]2309e912013-10-01 01:33:30163 if (!instant_service->IsInstantProcess(rph->GetID()))
164 continue;
sky4bdad242014-09-18 20:22:20165
mathp880d3282015-02-20 00:10:05166 if (google_base_url_domain_changed &&
167 SearchTabHelper::FromWebContents(contents)->model()->mode().is_ntp()) {
168 // Replace the server NTP with the local NTP.
sdefresne51bbec7b2015-08-03 14:18:13169 content::NavigationController::LoadURLParams params(
170 search::GetLocalInstantURL(profile()));
mathp880d3282015-02-20 00:10:05171 params.should_replace_current_entry = true;
172 params.referrer = content::Referrer();
173 params.transition_type = ui::PAGE_TRANSITION_RELOAD;
174 contents->GetController().LoadURLWithParams(params);
175 } else {
176 // Reload the contents to ensure that it gets assigned to a
177 // non-priviledged renderer.
178 contents->GetController().Reload(false);
sky4bdad242014-09-18 20:22:20179
mathp880d3282015-02-20 00:10:05180 // As the reload was not triggered by the user we don't want to close any
181 // infobars. We have to tell the InfoBarService after the reload,
182 // otherwise it would ignore this call when
183 // WebContentsObserver::DidStartNavigationToPendingEntry is invoked.
184 InfoBarService::FromWebContents(contents)->set_ignore_next_reload();
185 }
[email protected]0a46856e2013-04-24 00:33:02186 }
[email protected]0a46856e2013-04-24 00:33:02187}