1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_
6 #define CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/search/instant_service_observer.h"
15 #include "chrome/browser/ui/search/search_ipc_router.h"
16 #include "chrome/browser/ui/search/search_model.h"
17 #include "chrome/common/instant_types.h"
18 #include "chrome/common/ntp_logging_events.h"
19 #include "components/omnibox/common/omnibox_focus_state.h"
20 #include "content/public/browser/web_contents_observer.h"
21 #include "content/public/browser/web_contents_user_data.h"
22 #include "ui/base/window_open_disposition.h"
26 struct LoadCommittedDetails
;
30 class InstantPageTest
;
34 class SearchIPCRouterTest
;
35 class SearchTabHelperDelegate
;
37 // Per-tab search "helper". Acts as the owner and controller of the tab's
40 // When the page is finished loading, SearchTabHelper determines the instant
41 // support for the page. When a navigation entry is committed (except for
42 // in-page navigations), SearchTabHelper resets the instant support state to
43 // INSTANT_SUPPORT_UNKNOWN and cause support to be determined again.
44 class SearchTabHelper
: public content::WebContentsObserver
,
45 public content::WebContentsUserData
<SearchTabHelper
>,
46 public InstantServiceObserver
,
47 public SearchIPCRouter::Delegate
{
49 ~SearchTabHelper() override
;
51 SearchModel
* model() {
55 // Sets up the initial state correctly for a preloaded NTP.
56 void InitForPreloadedNTP();
58 // Invoked when the omnibox input state is changed in some way that might
59 // affect the search mode.
60 void OmniboxInputStateChanged();
62 // Called to indicate that the omnibox focus state changed with the given
64 void OmniboxFocusChanged(OmniboxFocusState state
,
65 OmniboxFocusChangeReason reason
);
67 // Invoked when the active navigation entry is updated in some way that might
68 // affect the search mode. This is used by Instant when it "fixes up" the
69 // virtual URL of the active entry. Regular navigations are captured through
70 // the notification system and shouldn't call this method.
71 void NavigationEntryUpdated();
73 // Invoked to update the instant support state.
74 void InstantSupportChanged(bool supports_instant
);
76 // Returns true if the page supports instant. If the instant support state is
77 // not determined or if the page does not support instant returns false.
78 bool SupportsInstant() const;
80 // Sends the current SearchProvider suggestion to the Instant page if any.
81 void SetSuggestionToPrefetch(const InstantSuggestion
& suggestion
);
83 // Tells the page that the user pressed Enter in the omnibox.
84 void Submit(const base::string16
& text
,
85 const EmbeddedSearchRequestParams
& params
);
87 // Called when the tab corresponding to |this| instance is activated.
88 void OnTabActivated();
90 // Called when the tab corresponding to |this| instance is deactivated.
91 void OnTabDeactivated();
93 // Tells the page to toggle voice search.
94 void ToggleVoiceSearch();
96 // Returns true if the underlying page is a search results page.
97 bool IsSearchResultsPage();
99 void set_delegate(SearchTabHelperDelegate
* delegate
) { delegate_
= delegate
; }
102 friend class content::WebContentsUserData
<SearchTabHelper
>;
103 friend class InstantPageTest
;
104 friend class SearchIPCRouterPolicyTest
;
105 friend class SearchIPCRouterTest
;
106 friend class SearchTabHelperPrerenderTest
;
108 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
109 DetermineIfPageSupportsInstant_Local
);
110 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
111 DetermineIfPageSupportsInstant_NonLocal
);
112 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
113 PageURLDoesntBelongToInstantRenderer
);
114 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
115 OnChromeIdentityCheckMatch
);
116 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
117 OnChromeIdentityCheckMatchSlightlyDifferentGmail
);
118 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
119 OnChromeIdentityCheckMatchSlightlyDifferentGmail2
);
120 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
, OnChromeIdentityCheckMismatch
);
121 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
122 OnChromeIdentityCheckSignedOutMatch
);
123 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
124 OnChromeIdentityCheckSignedOutMismatch
);
125 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
126 OnHistorySyncCheckSyncInactive
);
127 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
128 OnHistorySyncCheckSyncing
);
129 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest
,
130 OnHistorySyncCheckNotSyncing
);
131 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest
,
132 OnProvisionalLoadFailRedirectNTPToLocal
);
133 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest
,
134 OnProvisionalLoadFailDontRedirectIfAborted
);
135 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest
,
136 OnProvisionalLoadFailDontRedirectNonNTP
);
137 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest
,
138 IgnoreMessageIfThePageIsNotActive
);
139 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest
,
140 DoNotSendSetDisplayInstantResultsMsg
);
141 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest
, HandleTabChangedEvents
);
142 FRIEND_TEST_ALL_PREFIXES(InstantPageTest
,
143 DetermineIfPageSupportsInstant_Local
);
144 FRIEND_TEST_ALL_PREFIXES(InstantPageTest
,
145 DetermineIfPageSupportsInstant_NonLocal
);
146 FRIEND_TEST_ALL_PREFIXES(InstantPageTest
,
147 PageURLDoesntBelongToInstantRenderer
);
148 FRIEND_TEST_ALL_PREFIXES(InstantPageTest
, PageSupportsInstant
);
150 explicit SearchTabHelper(content::WebContents
* web_contents
);
152 // Overridden from contents::WebContentsObserver:
153 void RenderViewCreated(content::RenderViewHost
* render_view_host
) override
;
154 void DidStartNavigationToPendingEntry(
156 content::NavigationController::ReloadType reload_type
) override
;
157 void DidNavigateMainFrame(
158 const content::LoadCommittedDetails
& details
,
159 const content::FrameNavigateParams
& params
) override
;
160 void DidFinishLoad(content::RenderFrameHost
* render_frame_host
,
161 const GURL
& validated_url
) override
;
162 void NavigationEntryCommitted(
163 const content::LoadCommittedDetails
& load_details
) override
;
165 // Overridden from SearchIPCRouter::Delegate:
166 void OnInstantSupportDetermined(bool supports_instant
) override
;
167 void OnSetVoiceSearchSupport(bool supports_voice_search
) override
;
168 void FocusOmnibox(OmniboxFocusState state
) override
;
169 void NavigateToURL(const GURL
& url
,
170 WindowOpenDisposition disposition
,
171 bool is_most_visited_item_url
) override
;
172 void OnDeleteMostVisitedItem(const GURL
& url
) override
;
173 void OnUndoMostVisitedDeletion(const GURL
& url
) override
;
174 void OnUndoAllMostVisitedDeletions() override
;
175 void OnLogEvent(NTPLoggingEventType event
, base::TimeDelta time
) override
;
176 void OnLogMostVisitedImpression(int position
,
177 const base::string16
& provider
) override
;
178 void OnLogMostVisitedNavigation(int position
,
179 const base::string16
& provider
) override
;
180 void PasteIntoOmnibox(const base::string16
& text
) override
;
181 void OnChromeIdentityCheck(const base::string16
& identity
) override
;
182 void OnHistorySyncCheck() override
;
184 // Overridden from InstantServiceObserver:
185 void ThemeInfoChanged(const ThemeBackgroundInfo
& theme_info
) override
;
186 void MostVisitedItemsChanged(
187 const std::vector
<InstantMostVisitedItem
>& items
) override
;
188 void OmniboxStartMarginChanged(int omnibox_start_margin
) override
;
190 // Sets the mode of the model based on the current URL of web_contents().
191 // Only updates the origin part of the mode if |update_origin| is true,
192 // otherwise keeps the current origin. If |is_preloaded_ntp| is true, the mode
193 // is set to NTP regardless of the current URL; this is used to ensure that
194 // InstantController can bind InstantTab to new tab pages immediately.
195 void UpdateMode(bool update_origin
, bool is_preloaded_ntp
);
197 // Tells the renderer to determine if the page supports the Instant API, which
198 // results in a call to OnInstantSupportDetermined() when the reply is
200 void DetermineIfPageSupportsInstant();
202 // Used by unit tests.
203 SearchIPCRouter
& ipc_router() { return ipc_router_
; }
205 Profile
* profile() const;
207 // Returns whether input is in progress, i.e. if the omnibox has focus and the
208 // active tab is in mode SEARCH_SUGGESTIONS.
209 bool IsInputInProgress() const;
211 // Returns the OmniboxView for |web_contents_| or NULL if not available.
212 OmniboxView
* GetOmniboxView() const;
214 typedef bool (*OmniboxHasFocusFn
)(OmniboxView
*);
216 void set_omnibox_has_focus_fn(OmniboxHasFocusFn fn
) {
217 omnibox_has_focus_fn_
= fn
;
220 const bool is_search_enabled_
;
222 // Model object for UI that cares about search state.
225 content::WebContents
* web_contents_
;
227 SearchIPCRouter ipc_router_
;
229 InstantService
* instant_service_
;
231 // Delegate for notifying our owner about the SearchTabHelper state. Not owned
233 // NULL on iOS and Android because they don't use the Instant framework.
234 SearchTabHelperDelegate
* delegate_
;
236 // Function to check if the omnibox has focus. Tests use this to modify the
238 OmniboxHasFocusFn omnibox_has_focus_fn_
;
240 DISALLOW_COPY_AND_ASSIGN(SearchTabHelper
);
243 #endif // CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_