12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/search/search_tab_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <set>
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/metrics/histogram.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/string16.h"
120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/strings/string_util.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/profiles/profile.h"
15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/search/instant_service.h"
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/search/instant_service_factory.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/search.h"
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_util.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/location_bar/location_bar.h"
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_view.h"
286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/browser/ui/search/instant_search_prerenderer.h"
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/search/search_ipc_router_policy_impl.h"
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/search/search_tab_helper_delegate.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h"
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/google/core/browser/google_util.h"
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/search/search.h"
37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/navigation_controller.h"
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/navigation_details.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/navigation_type.h"
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/notification_service.h"
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/notification_source.h"
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/render_frame_host.h"
45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/public/browser/render_process_host.h"
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/public/browser/web_contents.h"
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/common/referrer.h"
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/net_errors.h"
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/l10n/l10n_util.h"
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/page_transition_types.h"
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "url/gurl.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY(SearchTabHelper);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// For reporting Cacheable NTP navigations.
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)enum CacheableNTPLoad {
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CACHEABLE_NTP_LOAD_FAILED = 0,
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CACHEABLE_NTP_LOAD_SUCCEEDED = 1,
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CACHEABLE_NTP_LOAD_MAX = 2
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void RecordCacheableNTPLoadHistogram(bool succeeded) {
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("InstantExtended.CacheableNTPLoad",
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            succeeded ? CACHEABLE_NTP_LOAD_SUCCEEDED :
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                CACHEABLE_NTP_LOAD_FAILED,
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            CACHEABLE_NTP_LOAD_MAX);
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool IsCacheableNTP(const content::WebContents* contents) {
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const content::NavigationEntry* entry =
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents->GetController().GetLastCommittedEntry();
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return chrome::NavEntryIsInstantNTP(contents, entry) &&
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      entry->GetURL() != GURL(chrome::kChromeSearchLocalNtpUrl);
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsNTP(const content::WebContents* contents) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We can't use WebContents::GetURL() because that uses the active entry,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // whereas we want the visible entry.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const content::NavigationEntry* entry =
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetController().GetVisibleEntry();
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (entry && entry->GetVirtualURL() == GURL(chrome::kChromeUINewTabURL))
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chrome::IsInstantNTP(contents);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsSearchResults(const content::WebContents* contents) {
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !chrome::GetSearchTerms(contents).empty();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool IsLocal(const content::WebContents* contents) {
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!contents)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const content::NavigationEntry* entry =
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      contents->GetController().GetVisibleEntry();
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return entry && entry->GetURL() == GURL(chrome::kChromeSearchLocalNtpUrl);
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Returns true if |contents| are rendered inside an Instant process.
103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool InInstantProcess(Profile* profile,
104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                      const content::WebContents* contents) {
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!profile || !contents)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  InstantService* instant_service =
109558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      InstantServiceFactory::GetForProfile(profile);
110558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return instant_service &&
111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      instant_service->IsInstantProcess(
112558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          contents->GetRenderProcessHost()->GetID());
113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Called when an NTP finishes loading. If the load start time was noted,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// calculates and logs the total load time.
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RecordNewTabLoadTime(content::WebContents* contents) {
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents);
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (core_tab_helper->new_tab_start_time().is_null())
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta duration =
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::TimeTicks::Now() - core_tab_helper->new_tab_start_time();
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (IsCacheableNTP(contents)) {
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (google_util::IsGoogleDomainUrl(
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        contents->GetController().GetLastCommittedEntry()->GetURL(),
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        google_util::ALLOW_SUBDOMAIN,
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        google_util::DISALLOW_NON_STANDARD_PORTS)) {
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      UMA_HISTOGRAM_TIMES("Tab.NewTabOnload.Google", duration);
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else {
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      UMA_HISTOGRAM_TIMES("Tab.NewTabOnload.Other", duration);
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else {
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    UMA_HISTOGRAM_TIMES("Tab.NewTabOnload.Local", duration);
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  core_tab_helper->set_new_tab_start_time(base::TimeTicks());
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Returns true if the user is signed in and full history sync is enabled,
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// and false otherwise.
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool IsHistorySyncEnabled(Profile* profile) {
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ProfileSyncService* sync =
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return sync &&
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sync->sync_initialized() &&
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool OmniboxHasFocus(OmniboxView* omnibox) {
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return omnibox && omnibox->model()->has_focus();
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SearchTabHelper::SearchTabHelper(content::WebContents* web_contents)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : WebContentsObserver(web_contents),
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      is_search_enabled_(chrome::IsInstantExtendedAPIEnabled()),
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      web_contents_(web_contents),
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ipc_router_(web_contents, this,
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  make_scoped_ptr(new SearchIPCRouterPolicyImpl(web_contents))
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      .PassAs<SearchIPCRouter::Policy>()),
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      instant_service_(NULL),
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      delegate_(NULL),
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      omnibox_has_focus_fn_(&OmniboxHasFocus) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_search_enabled_)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  instant_service_ =
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      InstantServiceFactory::GetForProfile(
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          Profile::FromBrowserContext(web_contents_->GetBrowserContext()));
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (instant_service_)
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    instant_service_->AddObserver(this);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SearchTabHelper::~SearchTabHelper() {
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (instant_service_)
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    instant_service_->RemoveObserver(this);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SearchTabHelper::InitForPreloadedNTP() {
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UpdateMode(true, true);
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SearchTabHelper::OmniboxInputStateChanged() {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_search_enabled_)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UpdateMode(false, false);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SearchTabHelper::OmniboxFocusChanged(OmniboxFocusState state,
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                          OmniboxFocusChangeReason reason) {
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::NotificationService::current()->Notify(
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chrome::NOTIFICATION_OMNIBOX_FOCUS_CHANGED,
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      content::Source<SearchTabHelper>(this),
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      content::NotificationService::NoDetails());
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ipc_router_.OmniboxFocusChanged(state, reason);
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Don't send oninputstart/oninputend updates in response to focus changes
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // if there's a navigation in progress. This prevents Chrome from sending
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // a spurious oninputend when the user accepts a match in the omnibox.
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (web_contents_->GetController().GetPendingEntry() == NULL) {
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ipc_router_.SetInputInProgress(IsInputInProgress());
2056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    InstantSearchPrerenderer* prerenderer =
2076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        InstantSearchPrerenderer::GetForProfile(profile());
2086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (!prerenderer || !chrome::ShouldPrerenderInstantUrlOnOmniboxFocus())
2096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      return;
2106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (state == OMNIBOX_FOCUS_NONE) {
2126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      prerenderer->Cancel();
2136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      return;
2146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
2156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (!IsSearchResultsPage()) {
2176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      prerenderer->Init(
2186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          web_contents_->GetController().GetSessionStorageNamespaceMap(),
2196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          web_contents_->GetContainerBounds().size());
2206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SearchTabHelper::NavigationEntryUpdated() {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_search_enabled_)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UpdateMode(false, false);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SearchTabHelper::InstantSupportChanged(bool instant_support) {
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!is_search_enabled_)
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
235ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  InstantSupportState new_state = instant_support ? INSTANT_SUPPORT_YES :
236ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      INSTANT_SUPPORT_NO;
237ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
238ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  model_.SetInstantSupportState(new_state);
239ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  content::NavigationEntry* entry =
2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      web_contents_->GetController().GetLastCommittedEntry();
242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (entry) {
243ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    chrome::SetInstantSupportStateInNavigationEntry(new_state, entry);
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (delegate_ && !instant_support)
245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      delegate_->OnWebContentsInstantSupportDisabled(web_contents_);
246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool SearchTabHelper::SupportsInstant() const {
250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return model_.instant_support() == INSTANT_SUPPORT_YES;
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::SetSuggestionToPrefetch(
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const InstantSuggestion& suggestion) {
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ipc_router_.SetSuggestionToPrefetch(suggestion);
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SearchTabHelper::Submit(const base::string16& text) {
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ipc_router_.Submit(text);
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SearchTabHelper::OnTabActivated() {
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ipc_router_.OnTabActivated();
2646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  OmniboxView* omnibox_view = GetOmniboxView();
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (chrome::ShouldPrerenderInstantUrlOnOmniboxFocus() &&
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      omnibox_has_focus_fn_(omnibox_view)) {
2686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    InstantSearchPrerenderer* prerenderer =
2696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        InstantSearchPrerenderer::GetForProfile(profile());
2706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (prerenderer && !IsSearchResultsPage()) {
2716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      prerenderer->Init(
2726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          web_contents_->GetController().GetSessionStorageNamespaceMap(),
2736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          web_contents_->GetContainerBounds().size());
2746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
2756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SearchTabHelper::OnTabDeactivated() {
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ipc_router_.OnTabDeactivated();
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SearchTabHelper::ToggleVoiceSearch() {
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ipc_router_.ToggleVoiceSearch();
284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool SearchTabHelper::IsSearchResultsPage() {
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return model_.mode().is_origin_search();
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::RenderViewCreated(
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::RenderViewHost* render_view_host) {
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ipc_router_.SetPromoInformation(IsAppLauncherEnabled());
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SearchTabHelper::DidStartNavigationToPendingEntry(
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& url,
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::NavigationController::ReloadType /* reload_type */) {
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (chrome::IsNTPURL(url, profile())) {
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Set the title on any pending entry corresponding to the NTP. This
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // prevents any flickering of the tab title.
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::NavigationEntry* entry =
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        web_contents_->GetController().GetPendingEntry();
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (entry)
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      entry->SetTitle(l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SearchTabHelper::DidNavigateMainFrame(
309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const content::LoadCommittedDetails& details,
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const content::FrameNavigateParams& params) {
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (IsCacheableNTP(web_contents_)) {
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (details.http_status_code == 204 || details.http_status_code >= 400) {
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      RedirectToLocalNTP();
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      RecordCacheableNTPLoadHistogram(false);
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RecordCacheableNTPLoadHistogram(true);
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Always set the title on the new tab page to be the one from our UI
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // resources. Normally, we set the title when we begin a NTP load, but it can
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // get reset in several places (like when you press Reload). This check
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // ensures that the title is properly set to the string defined by the Chrome
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // UI language (rather than the server language) in all cases.
325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We only override the title when it's nonempty to allow the page to set the
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // title if it really wants. An empty title means to use the default. There's
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // also a race condition between this code and the page's SetTitle call which
329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // this rule avoids.
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  content::NavigationEntry* entry =
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      web_contents_->GetController().GetLastCommittedEntry();
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (entry && entry->GetTitle().empty() &&
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      (entry->GetVirtualURL() == GURL(chrome::kChromeUINewTabURL) ||
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       chrome::NavEntryIsInstantNTP(web_contents_, entry))) {
335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    entry->SetTitle(l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SearchTabHelper::DidFailProvisionalLoad(
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::RenderFrameHost* render_frame_host,
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& validated_url,
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int error_code,
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::string16& /* error_description */) {
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If error_code is ERR_ABORTED means that the user has canceled this
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // navigation so it shouldn't be redirected.
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!render_frame_host->GetParent() && error_code != net::ERR_ABORTED &&
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      validated_url != GURL(chrome::kChromeSearchLocalNtpUrl) &&
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      chrome::IsNTPURL(validated_url, profile())) {
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RedirectToLocalNTP();
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RecordCacheableNTPLoadHistogram(false);
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SearchTabHelper::DidFinishLoad(content::RenderFrameHost* render_frame_host,
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    const GURL& /* validated_url */) {
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!render_frame_host->GetParent()) {
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (chrome::IsInstantNTP(web_contents_))
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RecordNewTabLoadTime(web_contents_);
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DetermineIfPageSupportsInstant();
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SearchTabHelper::NavigationEntryCommitted(
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const content::LoadCommittedDetails& load_details) {
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!is_search_enabled_)
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!load_details.is_main_frame)
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (chrome::ShouldAssignURLToInstantRenderer(web_contents_->GetURL(),
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               profile())) {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InstantService* instant_service =
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        InstantServiceFactory::GetForProfile(profile());
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ipc_router_.SetOmniboxStartMargin(instant_service->omnibox_start_margin());
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ipc_router_.SetDisplayInstantResults();
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UpdateMode(true, false);
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::NavigationEntry* entry =
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      web_contents_->GetController().GetVisibleEntry();
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(entry);
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Already determined the instant support state for this page, do not reset
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the instant support state.
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // When we get a navigation entry committed event, there seem to be two ways
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // to tell whether the navigation was "in-page". Ideally, when
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // LoadCommittedDetails::is_in_page is true, we should have
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // LoadCommittedDetails::type to be NAVIGATION_TYPE_IN_PAGE. Unfortunately,
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // they are different in some cases. To workaround this bug, we are checking
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // (is_in_page || type == NAVIGATION_TYPE_IN_PAGE). Please refer to
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // crbug.com/251330 for more details.
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (load_details.is_in_page ||
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      load_details.type == content::NAVIGATION_TYPE_IN_PAGE) {
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // When an "in-page" navigation happens, we will not receive a
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // DidFinishLoad() event. Therefore, we will not determine the Instant
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // support for the navigated page. So, copy over the Instant support from
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // the previous entry. If the page does not support Instant, update the
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // location bar from here to turn off search terms replacement.
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    chrome::SetInstantSupportStateInNavigationEntry(model_.instant_support(),
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                    entry);
405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (delegate_ && model_.instant_support() == INSTANT_SUPPORT_NO)
406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      delegate_->OnWebContentsInstantSupportDisabled(web_contents_);
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  model_.SetInstantSupportState(INSTANT_SUPPORT_UNKNOWN);
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  model_.SetVoiceSearchSupported(false);
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome::SetInstantSupportStateInNavigationEntry(model_.instant_support(),
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                  entry);
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (InInstantProcess(profile(), web_contents_))
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ipc_router_.OnNavigationEntryCommitted();
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SearchTabHelper::OnInstantSupportDetermined(bool supports_instant) {
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  InstantSupportChanged(supports_instant);
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SearchTabHelper::OnSetVoiceSearchSupport(bool supports_voice_search) {
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  model_.SetVoiceSearchSupported(supports_voice_search);
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) {
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ipc_router_.SendThemeBackgroundInfo(theme_info);
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::MostVisitedItemsChanged(
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::vector<InstantMostVisitedItem>& items) {
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ipc_router_.SendMostVisitedItems(items);
4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SearchTabHelper::OmniboxStartMarginChanged(int omnibox_start_margin) {
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ipc_router_.SetOmniboxStartMargin(omnibox_start_margin);
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::FocusOmnibox(OmniboxFocusState state) {
4415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(kmadhusu): Move platform specific code from here and get rid of #ifdef.
4425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_ANDROID)
443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  OmniboxView* omnibox = GetOmniboxView();
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!omnibox)
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Do not add a default case in the switch block for the following reasons:
4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // (1) Explicitly handle the new states. If new states are added in the
4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // OmniboxFocusState, the compiler will warn the developer to handle the new
4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // states.
4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // (2) An attacker may control the renderer and sends the browser process a
4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // malformed IPC. This function responds to the invalid |state| values by
4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // doing nothing instead of crashing the browser process (intentional no-op).
4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switch (state) {
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case OMNIBOX_FOCUS_VISIBLE:
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      omnibox->SetFocus();
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      omnibox->model()->SetCaretVisibility(true);
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case OMNIBOX_FOCUS_INVISIBLE:
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      omnibox->SetFocus();
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      omnibox->model()->SetCaretVisibility(false);
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // If the user clicked on the fakebox, any text already in the omnibox
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // should get cleared when they start typing. Selecting all the existing
4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // text is a convenient way to accomplish this. It also gives a slight
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // visual cue to users who really understand selection state about what
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // will happen if they start typing.
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      omnibox->SelectAll(false);
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      omnibox->ShowImeIfNeeded();
4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case OMNIBOX_FOCUS_NONE:
4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Remove focus only if the popup is closed. This will prevent someone
4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // from changing the omnibox value and closing the popup without user
4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // interaction.
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!omnibox->model()->popup_model()->IsOpen())
475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        web_contents()->Focus();
4764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif
4794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SearchTabHelper::NavigateToURL(const GURL& url,
4821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    WindowOpenDisposition disposition,
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    bool is_most_visited_item_url) {
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (is_most_visited_item_url) {
4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    content::RecordAction(
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UserMetricsAction("InstantExtended.MostVisitedClicked"));
4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
489c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (delegate_)
490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    delegate_->NavigateOnThumbnailClick(url, disposition, web_contents_);
4911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::OnDeleteMostVisitedItem(const GURL& url) {
4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!url.is_empty());
4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (instant_service_)
4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    instant_service_->DeleteMostVisitedItem(url);
4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::OnUndoMostVisitedDeletion(const GURL& url) {
5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!url.is_empty());
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (instant_service_)
5024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    instant_service_->UndoMostVisitedDeletion(url);
5034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::OnUndoAllMostVisitedDeletions() {
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (instant_service_)
5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    instant_service_->UndoAllMostVisitedDeletions();
5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SearchTabHelper::OnLogEvent(NTPLoggingEventType event) {
5115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(kmadhusu): Move platform specific code from here and get rid of #ifdef.
5125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_ANDROID)
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NTPUserDataLogger::GetOrCreateFromWebContents(
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      web_contents())->LogEvent(event);
5155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SearchTabHelper::OnLogMostVisitedImpression(
519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int position, const base::string16& provider) {
5205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(kmadhusu): Move platform specific code from here and get rid of #ifdef.
5215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_ANDROID)
522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NTPUserDataLogger::GetOrCreateFromWebContents(
523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      web_contents())->LogMostVisitedImpression(position, provider);
5245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif
525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SearchTabHelper::OnLogMostVisitedNavigation(
528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int position, const base::string16& provider) {
5295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(kmadhusu): Move platform specific code from here and get rid of #ifdef.
5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_ANDROID)
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NTPUserDataLogger::GetOrCreateFromWebContents(
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      web_contents())->LogMostVisitedNavigation(position, provider);
5335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SearchTabHelper::PasteIntoOmnibox(const base::string16& text) {
5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(kmadhusu): Move platform specific code from here and get rid of #ifdef.
5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_ANDROID)
539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  OmniboxView* omnibox = GetOmniboxView();
540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!omnibox)
5411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The first case is for right click to paste, where the text is retrieved
5431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // from the clipboard already sanitized. The second case is needed to handle
5441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // drag-and-drop value and it has to be sanitazed before setting it into the
5451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // omnibox.
546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 text_to_paste = text.empty() ? omnibox->GetClipboardText() :
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      omnibox->SanitizeTextForPaste(text);
5481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (text_to_paste.empty())
5501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!omnibox->model()->has_focus())
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    omnibox->SetFocus();
5541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  omnibox->OnBeforePossibleChange();
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  omnibox->model()->OnPaste();
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  omnibox->SetUserText(text_to_paste);
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  omnibox->OnAfterPossibleChange();
5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif
5601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SearchTabHelper::OnChromeIdentityCheck(const base::string16& identity) {
5630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile());
5640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (manager) {
565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16 username =
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UTF8ToUTF16(manager->GetAuthenticatedUsername());
567f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The identity check only passes if the user is syncing their history.
568f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // TODO(beaudoin): Change this function name and related APIs now that it's
569f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // checking both the identity and the user's sync state.
570f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool matches = IsHistorySyncEnabled(profile()) && identity == username;
571f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ipc_router_.SendChromeIdentityCheckResult(identity, matches);
5720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
5730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
5740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SearchTabHelper::UpdateMode(bool update_origin, bool is_preloaded_ntp) {
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SearchMode::Type type = SearchMode::MODE_DEFAULT;
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SearchMode::Origin origin = SearchMode::ORIGIN_DEFAULT;
578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (IsNTP(web_contents_) || is_preloaded_ntp) {
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    type = SearchMode::MODE_NTP;
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    origin = SearchMode::ORIGIN_NTP;
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (IsSearchResults(web_contents_)) {
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    type = SearchMode::MODE_SEARCH_RESULTS;
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    origin = SearchMode::ORIGIN_SEARCH;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!update_origin)
586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    origin = model_.mode().origin;
587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
588c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  OmniboxView* omnibox = GetOmniboxView();
589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (omnibox && omnibox->model()->user_input_in_progress())
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    type = SearchMode::MODE_SEARCH_SUGGESTIONS;
591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SearchMode old_mode(model_.mode());
593a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  model_.SetMode(SearchMode(type, origin));
594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (old_mode.is_ntp() != model_.mode().is_ntp()) {
595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ipc_router_.SetInputInProgress(IsInputInProgress());
596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SearchTabHelper::DetermineIfPageSupportsInstant() {
6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!InInstantProcess(profile(), web_contents_)) {
601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // The page is not in the Instant process. This page does not support
602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // instant. If we send an IPC message to a page that is not in the Instant
603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // process, it will never receive it and will never respond. Therefore,
604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // return immediately.
605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    InstantSupportChanged(false);
606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else if (IsLocal(web_contents_)) {
607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Local pages always support Instant.
608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    InstantSupportChanged(true);
609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
61058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ipc_router_.DetermineIfPageSupportsInstant();
611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Profile* SearchTabHelper::profile() const {
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return Profile::FromBrowserContext(web_contents_->GetBrowserContext());
6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
61858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SearchTabHelper::RedirectToLocalNTP() {
61958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Extra parentheses to declare a variable.
62058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  content::NavigationController::LoadURLParams load_params(
62158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      (GURL(chrome::kChromeSearchLocalNtpUrl)));
62258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  load_params.referrer = content::Referrer();
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_params.transition_type = ui::PAGE_TRANSITION_SERVER_REDIRECT;
62458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Don't push a history entry.
62558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  load_params.should_replace_current_entry = true;
62658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  web_contents_->GetController().LoadURLWithParams(load_params);
627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool SearchTabHelper::IsInputInProgress() const {
630c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  OmniboxView* omnibox = GetOmniboxView();
631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return !model_.mode().is_ntp() && omnibox &&
632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      omnibox->model()->focus_state() == OMNIBOX_FOCUS_VISIBLE;
633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
634c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
635c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochOmniboxView* SearchTabHelper::GetOmniboxView() const {
636c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return delegate_ ? delegate_->GetOmniboxView() : NULL;
637c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
638