[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 | |
avi | 655876a | 2015-12-25 07:18:15 | [diff] [blame] | 7 | #include <stddef.h> |
dcheng | 4a9d982 | 2015-12-26 22:35:30 | [diff] [blame] | 8 | #include <utility> |
avi | 655876a | 2015-12-25 07:18:15 | [diff] [blame] | 9 | |
fdoray | 283082bd | 2016-06-02 20:18:46 | [diff] [blame] | 10 | #include "base/location.h" |
[email protected] | f92d658 | 2013-06-10 22:02:36 | [diff] [blame] | 11 | #include "base/strings/stringprintf.h" |
fdoray | 283082bd | 2016-06-02 20:18:46 | [diff] [blame] | 12 | #include "base/threading/thread_task_runner_handle.h" |
[email protected] | 1a7ff74 | 2013-07-12 00:26:23 | [diff] [blame] | 13 | #include "chrome/browser/chrome_notification_types.h" |
[email protected] | d58688c6 | 2013-07-03 23:09:12 | [diff] [blame] | 14 | #include "chrome/browser/profiles/profile.h" |
[email protected] | a7b8e43d | 2013-03-18 18:52:43 | [diff] [blame] | 15 | #include "chrome/browser/search/instant_service.h" |
| 16 | #include "chrome/browser/search/instant_service_factory.h" |
| 17 | #include "chrome/browser/search/search.h" |
[email protected] | 4418dbb | 2012-10-25 03:21:54 | [diff] [blame] | 18 | #include "chrome/browser/ui/browser_instant_controller.h" |
[email protected] | 03bb710 | 2013-03-17 22:44:47 | [diff] [blame] | 19 | #include "chrome/browser/ui/search/instant_tab.h" |
[email protected] | 23f02b2 | 2012-10-26 06:08:27 | [diff] [blame] | 20 | #include "chrome/browser/ui/search/search_tab_helper.h" |
blundell | 47c6d8a | 2015-09-24 11:06:40 | [diff] [blame] | 21 | #include "components/sessions/core/serialized_navigation_entry.h" |
treib | 6344118 | 2016-07-13 09:29:44 | [diff] [blame] | 22 | #include "content/public/browser/navigation_controller.h" |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 23 | #include "content/public/browser/navigation_entry.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 24 | #include "content/public/browser/notification_service.h" |
[email protected] | 3d6a895 | 2012-12-14 03:18:07 | [diff] [blame] | 25 | #include "content/public/browser/web_contents.h" |
[email protected] | a46d67d9 | 2013-10-07 22:39:20 | [diff] [blame] | 26 | #include "url/gurl.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 27 | |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 28 | namespace { |
| 29 | |
sfiera | 948c97f | 2016-07-13 19:37:56 | [diff] [blame] | 30 | bool IsContentsFrom(const InstantTab* page, |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 31 | const content::WebContents* contents) { |
lucinka.brozkova | c25f7fb9 | 2014-09-04 06:42:56 | [diff] [blame] | 32 | return page && (page->web_contents() == contents); |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 33 | } |
| 34 | |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 35 | // Adds a transient NavigationEntry to the supplied |contents|'s |
| 36 | // NavigationController if the page's URL has not already been updated with the |
| 37 | // supplied |search_terms|. Sets the |search_terms| on the transient entry for |
| 38 | // search terms extraction to work correctly. |
| 39 | void EnsureSearchTermsAreSet(content::WebContents* contents, |
[email protected] | e9273e19 | 2013-12-11 17:51:49 | [diff] [blame] | 40 | const base::string16& search_terms) { |
[email protected] | 988cf72 | 2013-03-08 00:42:00 | [diff] [blame] | 41 | content::NavigationController* controller = &contents->GetController(); |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 42 | |
| 43 | // If search terms are already correct or there is already a transient entry |
| 44 | // (there shouldn't be), bail out early. |
sdefresne | 51bbec7b | 2015-08-03 14:18:13 | [diff] [blame] | 45 | if (search::GetSearchTerms(contents) == search_terms || |
[email protected] | 988cf72 | 2013-03-08 00:42:00 | [diff] [blame] | 46 | controller->GetTransientEntry()) |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 47 | return; |
| 48 | |
[email protected] | d8dca26 | 2013-11-20 06:16:24 | [diff] [blame] | 49 | const content::NavigationEntry* entry = controller->GetLastCommittedEntry(); |
dcheng | 9603ab9 | 2016-04-08 04:17:32 | [diff] [blame] | 50 | std::unique_ptr<content::NavigationEntry> transient = |
avi | 2576470 | 2015-06-23 15:43:37 | [diff] [blame] | 51 | controller->CreateNavigationEntry( |
dcheng | 9603ab9 | 2016-04-08 04:17:32 | [diff] [blame] | 52 | entry->GetURL(), entry->GetReferrer(), entry->GetTransitionType(), |
| 53 | false, std::string(), contents->GetBrowserContext()); |
[email protected] | 40a7e41 | 2013-04-29 18:13:01 | [diff] [blame] | 54 | transient->SetExtraData(sessions::kSearchTermsKey, search_terms); |
dcheng | 4a9d982 | 2015-12-26 22:35:30 | [diff] [blame] | 55 | controller->SetTransientEntry(std::move(transient)); |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 56 | |
[email protected] | 165fe42 | 2013-03-27 06:34:03 | [diff] [blame] | 57 | SearchTabHelper::FromWebContents(contents)->NavigationEntryUpdated(); |
[email protected] | 0b68426 | 2013-02-20 02:18:21 | [diff] [blame] | 58 | } |
| 59 | |
[email protected] | b67d0a4 | 2012-09-04 20:57:35 | [diff] [blame] | 60 | } // namespace |
| 61 | |
[email protected] | a780c7b2 | 2013-08-02 18:36:59 | [diff] [blame] | 62 | InstantController::InstantController(BrowserInstantController* browser) |
[email protected] | 416d753 | 2014-02-28 22:58:06 | [diff] [blame] | 63 | : browser_(browser) { |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 64 | } |
| 65 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 66 | InstantController::~InstantController() { |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 67 | } |
| 68 | |
kmadhusu | 562c49c8 | 2014-11-18 02:08:03 | [diff] [blame] | 69 | bool InstantController::SubmitQuery(const base::string16& search_terms, |
| 70 | const EmbeddedSearchRequestParams& params) { |
treib | cdd7937 | 2016-07-25 13:20:11 | [diff] [blame^] | 71 | if (!instant_tab_ || !instant_tab_->web_contents()) |
| 72 | return false; |
| 73 | |
| 74 | SearchTabHelper* search_tab = |
| 75 | SearchTabHelper::FromWebContents(instant_tab_->web_contents()); |
| 76 | if (!search_tab->SupportsInstant() || !search_mode_.is_origin_search()) |
| 77 | return false; |
| 78 | |
| 79 | // Use |instant_tab_| to run the query if we're already on a search results |
| 80 | // page. (NOTE: in particular, we do not send the query to NTPs.) |
| 81 | search_tab->Submit(search_terms, params); |
| 82 | instant_tab_->web_contents()->Focus(); |
| 83 | EnsureSearchTermsAreSet(instant_tab_->web_contents(), search_terms); |
| 84 | return true; |
[email protected] | 413558cb | 2013-06-10 16:44:45 | [diff] [blame] | 85 | } |
| 86 | |
[email protected] | 165fe42 | 2013-03-27 06:34:03 | [diff] [blame] | 87 | void InstantController::SearchModeChanged(const SearchMode& old_mode, |
| 88 | const SearchMode& new_mode) { |
treib | cdd7937 | 2016-07-25 13:20:11 | [diff] [blame^] | 89 | LogDebugEvent(base::StringPrintf( |
[email protected] | b97059d | 2013-01-26 00:06:40 | [diff] [blame] | 90 | "SearchModeChanged: [origin:mode] %d:%d to %d:%d", old_mode.origin, |
| 91 | old_mode.mode, new_mode.origin, new_mode.mode)); |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 92 | |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 93 | search_mode_ = new_mode; |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 94 | ResetInstantTab(); |
[email protected] | 0b10c9ff | 2012-10-09 17:31:55 | [diff] [blame] | 95 | } |
| 96 | |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 97 | void InstantController::ActiveTabChanged() { |
treib | cdd7937 | 2016-07-25 13:20:11 | [diff] [blame^] | 98 | LogDebugEvent("ActiveTabChanged"); |
[email protected] | d58688c6 | 2013-07-03 23:09:12 | [diff] [blame] | 99 | ResetInstantTab(); |
[email protected] | e41982a7 | 2012-11-20 07:16:51 | [diff] [blame] | 100 | } |
| 101 | |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 102 | void InstantController::LogDebugEvent(const std::string& info) const { |
| 103 | DVLOG(1) << info; |
| 104 | |
| 105 | debug_events_.push_front(std::make_pair( |
| 106 | base::Time::Now().ToInternalValue(), info)); |
| 107 | static const size_t kMaxDebugEventSize = 2000; |
| 108 | if (debug_events_.size() > kMaxDebugEventSize) |
| 109 | debug_events_.pop_back(); |
| 110 | } |
| 111 | |
[email protected] | 66be5181 | 2013-03-05 22:28:09 | [diff] [blame] | 112 | void InstantController::ClearDebugEvents() { |
| 113 | debug_events_.clear(); |
| 114 | } |
| 115 | |
[email protected] | 4066a695d | 2013-06-20 14:08:54 | [diff] [blame] | 116 | void InstantController::InstantSupportChanged( |
| 117 | InstantSupportState instant_support) { |
sfiera | 948c97f | 2016-07-13 19:37:56 | [diff] [blame] | 118 | // Handle INSTANT_SUPPORT_YES here because InstantTab is not hooked up to the |
| 119 | // active tab. Search model changed listener in InstantTab will handle other |
[email protected] | 4066a695d | 2013-06-20 14:08:54 | [diff] [blame] | 120 | // cases. |
| 121 | if (instant_support != INSTANT_SUPPORT_YES) |
| 122 | return; |
| 123 | |
| 124 | ResetInstantTab(); |
| 125 | } |
| 126 | |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 127 | void InstantController::InstantSupportDetermined( |
| 128 | const content::WebContents* contents, |
| 129 | bool supports_instant) { |
treib | cdd7937 | 2016-07-25 13:20:11 | [diff] [blame^] | 130 | DCHECK(IsContentsFrom(instant_tab_.get(), contents)); |
[email protected] | ab3e6667 | 2013-03-20 23:32:16 | [diff] [blame] | 131 | |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 132 | if (!supports_instant) |
fdoray | 283082bd | 2016-06-02 20:18:46 | [diff] [blame] | 133 | base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, |
| 134 | instant_tab_.release()); |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 135 | |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 136 | content::NotificationService::current()->Notify( |
| 137 | chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, |
| 138 | content::Source<InstantController>(this), |
| 139 | content::NotificationService::NoDetails()); |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 140 | } |
| 141 | |
sfiera | 948c97f | 2016-07-13 19:37:56 | [diff] [blame] | 142 | void InstantController::InstantTabAboutToNavigateMainFrame( |
[email protected] | 0c940663 | 2013-02-08 01:13:33 | [diff] [blame] | 143 | const content::WebContents* contents, |
| 144 | const GURL& url) { |
treib | cdd7937 | 2016-07-25 13:20:11 | [diff] [blame^] | 145 | DCHECK(IsContentsFrom(instant_tab_.get(), contents)); |
[email protected] | 4ff347e | 2013-07-22 19:39:00 | [diff] [blame] | 146 | |
| 147 | // The Instant tab navigated. Send it the data it needs to display |
| 148 | // properly. |
| 149 | UpdateInfoForInstantTab(); |
[email protected] | a682765 | 2012-11-20 23:41:08 | [diff] [blame] | 150 | } |
| 151 | |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 152 | void InstantController::ResetInstantTab() { |
[email protected] | 215ebc4 | 2013-06-22 00:24:50 | [diff] [blame] | 153 | if (!search_mode_.is_origin_default()) { |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 154 | content::WebContents* active_tab = browser_->GetActiveWebContents(); |
lucinka.brozkova | c25f7fb9 | 2014-09-04 06:42:56 | [diff] [blame] | 155 | if (!instant_tab_ || active_tab != instant_tab_->web_contents()) { |
treib | cdd7937 | 2016-07-25 13:20:11 | [diff] [blame^] | 156 | instant_tab_.reset(new InstantTab(this, active_tab)); |
| 157 | instant_tab_->Init(); |
[email protected] | 8cc9e53 | 2013-05-06 21:01:47 | [diff] [blame] | 158 | UpdateInfoForInstantTab(); |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 159 | } |
[email protected] | cd533bf | 2012-12-04 19:14:59 | [diff] [blame] | 160 | } else { |
| 161 | instant_tab_.reset(); |
| 162 | } |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 163 | } |
| 164 | |
[email protected] | 8cc9e53 | 2013-05-06 21:01:47 | [diff] [blame] | 165 | void InstantController::UpdateInfoForInstantTab() { |
| 166 | if (instant_tab_) { |
[email protected] | 6af4178 | 2013-06-22 13:49:11 | [diff] [blame] | 167 | // Update theme details. |
| 168 | InstantService* instant_service = GetInstantService(); |
[email protected] | ed68ae3 | 2013-06-29 20:46:48 | [diff] [blame] | 169 | if (instant_service) { |
[email protected] | 6af4178 | 2013-06-22 13:49:11 | [diff] [blame] | 170 | instant_service->UpdateThemeInfo(); |
[email protected] | ed68ae3 | 2013-06-29 20:46:48 | [diff] [blame] | 171 | instant_service->UpdateMostVisitedItemsInfo(); |
| 172 | } |
[email protected] | 8cc9e53 | 2013-05-06 21:01:47 | [diff] [blame] | 173 | } |
| 174 | } |
| 175 | |
[email protected] | 6af4178 | 2013-06-22 13:49:11 | [diff] [blame] | 176 | InstantService* InstantController::GetInstantService() const { |
treib | cdd7937 | 2016-07-25 13:20:11 | [diff] [blame^] | 177 | return InstantServiceFactory::GetForProfile(browser_->profile()); |
[email protected] | 6af4178 | 2013-06-22 13:49:11 | [diff] [blame] | 178 | } |