[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors. All rights reserved. |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 03bb710 | 2013-03-17 22:44:47 | [diff] [blame] | 5 | #include "chrome/browser/ui/search/instant_controller.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 6 | |
[email protected] | 2b3ded9 | 2013-06-19 05:48:43 | [diff] [blame] | 7 | #include "base/prefs/pref_service.h" |
[email protected] | f92d6588 | 2013-06-10 22:02:36 | [diff] [blame] | 8 | #include "base/strings/stringprintf.h" |
[email protected] | 1a7ff74 | 2013-07-12 00:26:23 | [diff] [blame] | 9 | #include "chrome/browser/chrome_notification_types.h" |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 10 | #include "chrome/browser/platform_util.h" |
[email protected] | d58688c6 | 2013-07-03 23:09:12 | [diff] [blame] | 11 | #include "chrome/browser/profiles/profile.h" |
[email protected] | a7b8e43d | 2013-03-18 18:52:43 | [diff] [blame] | 12 | #include "chrome/browser/search/instant_service.h" |
| 13 | #include "chrome/browser/search/instant_service_factory.h" |
| 14 | #include "chrome/browser/search/search.h" |
[email protected] | 8e5c89a | 2011-06-07 18:13:33 | [diff] [blame] | 15 | #include "chrome/browser/search_engines/template_url_service_factory.h" |
[email protected] | 4418dbb | 2012-10-25 03:21:54 | [diff] [blame] | 16 | #include "chrome/browser/ui/browser_instant_controller.h" |
[email protected] | 03bb710 | 2013-03-17 22:44:47 | [diff] [blame] | 17 | #include "chrome/browser/ui/search/instant_tab.h" |
[email protected] | 23f02b2 | 2012-10-26 06:08:27 | [diff] [blame] | 18 | #include "chrome/browser/ui/search/search_tab_helper.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 19 | #include "chrome/common/chrome_switches.h" |
[email protected] | 2309e91 | 2013-10-01 01:33:30 | [diff] [blame] | 20 | #include "chrome/common/search_urls.h" |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 21 | #include "chrome/common/url_constants.h" |
[email protected] | bf5c532d | 2014-07-05 00:29:53 | [diff] [blame] | 22 | #include "components/search_engines/template_url_service.h" |
blundell | 47c6d8a | 2015-09-24 11:06:40 | [diff] [blame^] | 23 | #include "components/sessions/core/serialized_navigation_entry.h" |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 24 | #include "content/public/browser/navigation_entry.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 25 | #include "content/public/browser/notification_service.h" |
[email protected] | d928589a | 2013-03-14 13:12:39 | [diff] [blame] | 26 | #include "content/public/browser/render_process_host.h" |
[email protected] | 5626b089 | 2012-02-20 14:46:58 | [diff] [blame] | 27 | #include "content/public/browser/render_widget_host_view.h" |
[email protected] | 3d6a895 | 2012-12-14 03:18:07 | [diff] [blame] | 28 | #include "content/public/browser/web_contents.h" |
[email protected] | a7c22e5 | 2012-10-12 19:19:05 | [diff] [blame] | 29 | #include "net/base/escape.h" |
[email protected] | 5aaa17d | 2013-05-06 22:44:34 | [diff] [blame] | 30 | #include "net/base/network_change_notifier.h" |
[email protected] | a46d67d9 | 2013-10-07 22:39:20 | [diff] [blame] | 31 | #include "url/gurl.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 32 | |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 33 | namespace { |
| 34 | |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 35 | bool IsContentsFrom(const InstantPage* page, |
| 36 | const content::WebContents* contents) { |
lucinka.brozkova | c25f7fb9 | 2014-09-04 06:42:56 | [diff] [blame] | 37 | return page && (page->web_contents() == contents); |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 38 | } |
| 39 | |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 40 | // Adds a transient NavigationEntry to the supplied |contents|'s |
| 41 | // NavigationController if the page's URL has not already been updated with the |
| 42 | // supplied |search_terms|. Sets the |search_terms| on the transient entry for |
| 43 | // search terms extraction to work correctly. |
| 44 | void EnsureSearchTermsAreSet(content::WebContents* contents, |
[email protected] | e9273e19 | 2013-12-11 17:51:49 | [diff] [blame] | 45 | const base::string16& search_terms) { |
[email protected] | 988cf72 | 2013-03-08 00:42:00 | [diff] [blame] | 46 | content::NavigationController* controller = &contents->GetController(); |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 47 | |
| 48 | // If search terms are already correct or there is already a transient entry |
| 49 | // (there shouldn't be), bail out early. |
sdefresne | 51bbec7b | 2015-08-03 14:18:13 | [diff] [blame] | 50 | if (search::GetSearchTerms(contents) == search_terms || |
[email protected] | 988cf72 | 2013-03-08 00:42:00 | [diff] [blame] | 51 | controller->GetTransientEntry()) |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 52 | return; |
| 53 | |
[email protected] | d8dca26 | 2013-11-20 06:16:24 | [diff] [blame] | 54 | const content::NavigationEntry* entry = controller->GetLastCommittedEntry(); |
avi | 2576470 | 2015-06-23 15:43:37 | [diff] [blame] | 55 | scoped_ptr<content::NavigationEntry> transient = |
| 56 | controller->CreateNavigationEntry( |
| 57 | entry->GetURL(), |
| 58 | entry->GetReferrer(), |
| 59 | entry->GetTransitionType(), |
| 60 | false, |
| 61 | std::string(), |
| 62 | contents->GetBrowserContext()); |
[email protected] | 40a7e41 | 2013-04-29 18:13:01 | [diff] [blame] | 63 | transient->SetExtraData(sessions::kSearchTermsKey, search_terms); |
avi | 2576470 | 2015-06-23 15:43:37 | [diff] [blame] | 64 | controller->SetTransientEntry(transient.Pass()); |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 65 | |
[email protected] | 165fe42 | 2013-03-27 06:34:03 | [diff] [blame] | 66 | SearchTabHelper::FromWebContents(contents)->NavigationEntryUpdated(); |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 67 | } |
| 68 | |
[email protected] | b67d0a4 | 2012-09-04 20:57:35 | [diff] [blame] | 69 | } // namespace |
| 70 | |
[email protected] | a780c7b2 | 2013-08-02 18:36:59 | [diff] [blame] | 71 | InstantController::InstantController(BrowserInstantController* browser) |
[email protected] | 416d753 | 2014-02-28 22:58:06 | [diff] [blame] | 72 | : browser_(browser) { |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 73 | } |
| 74 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 75 | InstantController::~InstantController() { |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 76 | } |
| 77 | |
kmadhusu | 562c49c8 | 2014-11-18 02:08:03 | [diff] [blame] | 78 | bool InstantController::SubmitQuery(const base::string16& search_terms, |
| 79 | const EmbeddedSearchRequestParams& params) { |
[email protected] | a780c7b2 | 2013-08-02 18:36:59 | [diff] [blame] | 80 | if (instant_tab_ && instant_tab_->supports_instant() && |
[email protected] | 413558cb | 2013-06-10 16:44:45 | [diff] [blame] | 81 | search_mode_.is_origin_search()) { |
| 82 | // Use |instant_tab_| to run the query if we're already on a search results |
| 83 | // page. (NOTE: in particular, we do not send the query to NTPs.) |
lucinka.brozkova | c25f7fb9 | 2014-09-04 06:42:56 | [diff] [blame] | 84 | SearchTabHelper::FromWebContents(instant_tab_->web_contents())->Submit( |
kmadhusu | 562c49c8 | 2014-11-18 02:08:03 | [diff] [blame] | 85 | search_terms, params); |
lucinka.brozkova | c25f7fb9 | 2014-09-04 06:42:56 | [diff] [blame] | 86 | instant_tab_->web_contents()->Focus(); |
| 87 | EnsureSearchTermsAreSet(instant_tab_->web_contents(), search_terms); |
[email protected] | 413558cb | 2013-06-10 16:44:45 | [diff] [blame] | 88 | return true; |
| 89 | } |
| 90 | return false; |
| 91 | } |
| 92 | |
[email protected] | 165fe42 | 2013-03-27 06:34:03 | [diff] [blame] | 93 | void InstantController::SearchModeChanged(const SearchMode& old_mode, |
| 94 | const SearchMode& new_mode) { |
[email protected] | b97059d | 2013-01-26 00:06:40 | [diff] [blame] | 95 | LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
| 96 | "SearchModeChanged: [origin:mode] %d:%d to %d:%d", old_mode.origin, |
| 97 | old_mode.mode, new_mode.origin, new_mode.mode)); |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 98 | |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 99 | search_mode_ = new_mode; |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 100 | ResetInstantTab(); |
[email protected] | 0b10c9ff | 2012-10-09 17:31:55 | [diff] [blame] | 101 | } |
| 102 | |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 103 | void InstantController::ActiveTabChanged() { |
[email protected] | b97059d | 2013-01-26 00:06:40 | [diff] [blame] | 104 | LOG_INSTANT_DEBUG_EVENT(this, "ActiveTabChanged"); |
[email protected] | d58688c6 | 2013-07-03 23:09:12 | [diff] [blame] | 105 | ResetInstantTab(); |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 106 | } |
| 107 | |
[email protected] | 3d6a895 | 2012-12-14 03:18:07 | [diff] [blame] | 108 | void InstantController::TabDeactivated(content::WebContents* contents) { |
[email protected] | ebc8046 | 2013-07-08 18:47:14 | [diff] [blame] | 109 | // If user is deactivating an NTP tab, log the number of mouseovers for this |
| 110 | // NTP session. |
sdefresne | 51bbec7b | 2015-08-03 14:18:13 | [diff] [blame] | 111 | if (search::IsInstantNTP(contents)) |
[email protected] | 6b7063e5 | 2013-12-04 22:15:23 | [diff] [blame] | 112 | InstantTab::EmitNtpStatistics(contents); |
[email protected] | a0b8466 | 2010-10-04 23:22:04 | [diff] [blame] | 113 | } |
| 114 | |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 115 | void InstantController::LogDebugEvent(const std::string& info) const { |
| 116 | DVLOG(1) << info; |
| 117 | |
| 118 | debug_events_.push_front(std::make_pair( |
| 119 | base::Time::Now().ToInternalValue(), info)); |
| 120 | static const size_t kMaxDebugEventSize = 2000; |
| 121 | if (debug_events_.size() > kMaxDebugEventSize) |
| 122 | debug_events_.pop_back(); |
| 123 | } |
| 124 | |
[email protected] | 66be5181 | 2013-03-05 22:28:09 | [diff] [blame] | 125 | void InstantController::ClearDebugEvents() { |
| 126 | debug_events_.clear(); |
| 127 | } |
| 128 | |
[email protected] | cc45906 | 2013-05-02 08:05:25 | [diff] [blame] | 129 | Profile* InstantController::profile() const { |
| 130 | return browser_->profile(); |
| 131 | } |
| 132 | |
[email protected] | cc45906 | 2013-05-02 08:05:25 | [diff] [blame] | 133 | InstantTab* InstantController::instant_tab() const { |
| 134 | return instant_tab_.get(); |
| 135 | } |
| 136 | |
[email protected] | 4066a695d | 2013-06-20 14:08:54 | [diff] [blame] | 137 | void InstantController::InstantSupportChanged( |
| 138 | InstantSupportState instant_support) { |
| 139 | // Handle INSTANT_SUPPORT_YES here because InstantPage is not hooked up to the |
| 140 | // active tab. Search model changed listener in InstantPage will handle other |
| 141 | // cases. |
| 142 | if (instant_support != INSTANT_SUPPORT_YES) |
| 143 | return; |
| 144 | |
| 145 | ResetInstantTab(); |
| 146 | } |
| 147 | |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 148 | void InstantController::InstantSupportDetermined( |
| 149 | const content::WebContents* contents, |
| 150 | bool supports_instant) { |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 151 | DCHECK(IsContentsFrom(instant_tab(), contents)); |
[email protected] | ab3e6667 | 2013-03-20 23:32:16 | [diff] [blame] | 152 | |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 153 | if (!supports_instant) |
| 154 | base::MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 155 | |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 156 | content::NotificationService::current()->Notify( |
| 157 | chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, |
| 158 | content::Source<InstantController>(this), |
| 159 | content::NotificationService::NoDetails()); |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 160 | } |
| 161 | |
| 162 | void InstantController::InstantPageAboutToNavigateMainFrame( |
| 163 | const content::WebContents* contents, |
| 164 | const GURL& url) { |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 165 | DCHECK(IsContentsFrom(instant_tab(), contents)); |
| 166 | |
| 167 | // The Instant tab navigated. Send it the data it needs to display |
| 168 | // properly. |
| 169 | UpdateInfoForInstantTab(); |
[email protected] | a682765 | 2012-11-20 23:41:08 | [diff] [blame] | 170 | } |
| 171 | |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 172 | void InstantController::ResetInstantTab() { |
[email protected] | 215ebc4 | 2013-06-22 00:24:50 | [diff] [blame] | 173 | if (!search_mode_.is_origin_default()) { |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 174 | content::WebContents* active_tab = browser_->GetActiveWebContents(); |
lucinka.brozkova | c25f7fb9 | 2014-09-04 06:42:56 | [diff] [blame] | 175 | if (!instant_tab_ || active_tab != instant_tab_->web_contents()) { |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 176 | instant_tab_.reset(new InstantTab(this, browser_->profile())); |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 177 | instant_tab_->Init(active_tab); |
[email protected] | 8cc9e53 | 2013-05-06 21:01:47 | [diff] [blame] | 178 | UpdateInfoForInstantTab(); |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 179 | } |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 180 | } else { |
| 181 | instant_tab_.reset(); |
| 182 | } |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 183 | } |
| 184 | |
[email protected] | 8cc9e53 | 2013-05-06 21:01:47 | [diff] [blame] | 185 | void InstantController::UpdateInfoForInstantTab() { |
| 186 | if (instant_tab_) { |
[email protected] | 6af4178 | 2013-06-22 13:49:11 | [diff] [blame] | 187 | // Update theme details. |
| 188 | InstantService* instant_service = GetInstantService(); |
[email protected] | ed68ae3 | 2013-06-29 20:46:48 | [diff] [blame] | 189 | if (instant_service) { |
[email protected] | 6af4178 | 2013-06-22 13:49:11 | [diff] [blame] | 190 | instant_service->UpdateThemeInfo(); |
[email protected] | ed68ae3 | 2013-06-29 20:46:48 | [diff] [blame] | 191 | instant_service->UpdateMostVisitedItemsInfo(); |
| 192 | } |
[email protected] | 8cc9e53 | 2013-05-06 21:01:47 | [diff] [blame] | 193 | } |
| 194 | } |
| 195 | |
[email protected] | 6af4178 | 2013-06-22 13:49:11 | [diff] [blame] | 196 | InstantService* InstantController::GetInstantService() const { |
| 197 | return InstantServiceFactory::GetForProfile(profile()); |
| 198 | } |