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. 4 5 #ifndef CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ 6 #define CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/gtest_prod_util.h" 13 #include "chrome/browser/search/instant_service_observer.h" 14 #include "chrome/browser/ui/search/search_ipc_router.h" 15 #include "chrome/browser/ui/search/search_model.h" 16 #include "chrome/common/instant_types.h" 17 #include "chrome/common/ntp_logging_events.h" 18 #include "chrome/common/omnibox_focus_state.h" 19 #include "content/public/browser/web_contents_observer.h" 20 #include "content/public/browser/web_contents_user_data.h" 21 #include "ui/base/window_open_disposition.h" 22 23 namespace content { 24 class WebContents; 25 struct LoadCommittedDetails; 26 } 27 28 class GURL; 29 class InstantPageTest; 30 class InstantService; 31 class OmniboxView; 32 class Profile; 33 class SearchIPCRouterTest; 34 class SearchTabHelperDelegate; 35 36 // Per-tab search "helper". Acts as the owner and controller of the tab's 37 // search UI model. 38 // 39 // When the page is finished loading, SearchTabHelper determines the instant 40 // support for the page. When a navigation entry is committed (except for 41 // in-page navigations), SearchTabHelper resets the instant support state to 42 // INSTANT_SUPPORT_UNKNOWN and cause support to be determined again. 43 class SearchTabHelper : public content::WebContentsObserver, 44 public content::WebContentsUserData<SearchTabHelper>, 45 public InstantServiceObserver, 46 public SearchIPCRouter::Delegate { 47 public: 48 virtual ~SearchTabHelper(); 49 model()50 SearchModel* model() { 51 return &model_; 52 } 53 54 // Sets up the initial state correctly for a preloaded NTP. 55 void InitForPreloadedNTP(); 56 57 // Invoked when the omnibox input state is changed in some way that might 58 // affect the search mode. 59 void OmniboxInputStateChanged(); 60 61 // Called to indicate that the omnibox focus state changed with the given 62 // |reason|. 63 void OmniboxFocusChanged(OmniboxFocusState state, 64 OmniboxFocusChangeReason reason); 65 66 // Invoked when the active navigation entry is updated in some way that might 67 // affect the search mode. This is used by Instant when it "fixes up" the 68 // virtual URL of the active entry. Regular navigations are captured through 69 // the notification system and shouldn't call this method. 70 void NavigationEntryUpdated(); 71 72 // Invoked to update the instant support state. 73 void InstantSupportChanged(bool supports_instant); 74 75 // Returns true if the page supports instant. If the instant support state is 76 // not determined or if the page does not support instant returns false. 77 bool SupportsInstant() const; 78 79 // Sends the current SearchProvider suggestion to the Instant page if any. 80 void SetSuggestionToPrefetch(const InstantSuggestion& suggestion); 81 82 // Tells the page that the user pressed Enter in the omnibox. 83 void Submit(const base::string16& text); 84 85 // Called when the tab corresponding to |this| instance is activated. 86 void OnTabActivated(); 87 88 // Called when the tab corresponding to |this| instance is deactivated. 89 void OnTabDeactivated(); 90 91 // Tells the page to toggle voice search. 92 void ToggleVoiceSearch(); 93 94 // Returns true if the underlying page is a search results page. 95 bool IsSearchResultsPage(); 96 set_delegate(SearchTabHelperDelegate * delegate)97 void set_delegate(SearchTabHelperDelegate* delegate) { delegate_ = delegate; } 98 99 private: 100 friend class content::WebContentsUserData<SearchTabHelper>; 101 friend class InstantPageTest; 102 friend class SearchIPCRouterPolicyTest; 103 friend class SearchIPCRouterTest; 104 friend class SearchTabHelperPrerenderTest; 105 106 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 107 DetermineIfPageSupportsInstant_Local); 108 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 109 DetermineIfPageSupportsInstant_NonLocal); 110 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 111 PageURLDoesntBelongToInstantRenderer); 112 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 113 OnChromeIdentityCheckMatch); 114 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 115 OnChromeIdentityCheckMismatch); 116 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 117 OnChromeIdentityCheckSignedOutMatch); 118 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 119 OnChromeIdentityCheckSignedOutMismatch); 120 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 121 OnChromeIdentityCheckMatchNotSyncing); 122 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 123 OnProvisionalLoadFailRedirectNTPToLocal); 124 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 125 OnProvisionalLoadFailDontRedirectIfAborted); 126 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 127 OnProvisionalLoadFailDontRedirectNonNTP); 128 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, 129 IgnoreMessageIfThePageIsNotActive); 130 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, 131 DoNotSendSetDisplayInstantResultsMsg); 132 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, HandleTabChangedEvents); 133 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 134 DetermineIfPageSupportsInstant_Local); 135 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 136 DetermineIfPageSupportsInstant_NonLocal); 137 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 138 PageURLDoesntBelongToInstantRenderer); 139 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, PageSupportsInstant); 140 141 explicit SearchTabHelper(content::WebContents* web_contents); 142 143 // Overridden from contents::WebContentsObserver: 144 virtual void RenderViewCreated( 145 content::RenderViewHost* render_view_host) OVERRIDE; 146 virtual void DidStartNavigationToPendingEntry( 147 const GURL& url, 148 content::NavigationController::ReloadType reload_type) OVERRIDE; 149 virtual void DidNavigateMainFrame( 150 const content::LoadCommittedDetails& details, 151 const content::FrameNavigateParams& params) OVERRIDE; 152 virtual void DidFailProvisionalLoad( 153 content::RenderFrameHost* render_frame_host, 154 const GURL& validated_url, 155 int error_code, 156 const base::string16& error_description) OVERRIDE; 157 virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host, 158 const GURL& validated_url) OVERRIDE; 159 virtual void NavigationEntryCommitted( 160 const content::LoadCommittedDetails& load_details) OVERRIDE; 161 162 // Overridden from SearchIPCRouter::Delegate: 163 virtual void OnInstantSupportDetermined(bool supports_instant) OVERRIDE; 164 virtual void OnSetVoiceSearchSupport(bool supports_voice_search) OVERRIDE; 165 virtual void FocusOmnibox(OmniboxFocusState state) OVERRIDE; 166 virtual void NavigateToURL(const GURL& url, 167 WindowOpenDisposition disposition, 168 bool is_most_visited_item_url) OVERRIDE; 169 virtual void OnDeleteMostVisitedItem(const GURL& url) OVERRIDE; 170 virtual void OnUndoMostVisitedDeletion(const GURL& url) OVERRIDE; 171 virtual void OnUndoAllMostVisitedDeletions() OVERRIDE; 172 virtual void OnLogEvent(NTPLoggingEventType event) OVERRIDE; 173 virtual void OnLogMostVisitedImpression( 174 int position, const base::string16& provider) OVERRIDE; 175 virtual void OnLogMostVisitedNavigation( 176 int position, const base::string16& provider) OVERRIDE; 177 virtual void PasteIntoOmnibox(const base::string16& text) OVERRIDE; 178 virtual void OnChromeIdentityCheck(const base::string16& identity) OVERRIDE; 179 180 // Overridden from InstantServiceObserver: 181 virtual void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) OVERRIDE; 182 virtual void MostVisitedItemsChanged( 183 const std::vector<InstantMostVisitedItem>& items) OVERRIDE; 184 virtual void OmniboxStartMarginChanged(int omnibox_start_margin) OVERRIDE; 185 186 // Sets the mode of the model based on the current URL of web_contents(). 187 // Only updates the origin part of the mode if |update_origin| is true, 188 // otherwise keeps the current origin. If |is_preloaded_ntp| is true, the mode 189 // is set to NTP regardless of the current URL; this is used to ensure that 190 // InstantController can bind InstantTab to new tab pages immediately. 191 void UpdateMode(bool update_origin, bool is_preloaded_ntp); 192 193 // Tells the renderer to determine if the page supports the Instant API, which 194 // results in a call to OnInstantSupportDetermined() when the reply is 195 // received. 196 void DetermineIfPageSupportsInstant(); 197 198 // Used by unit tests. ipc_router()199 SearchIPCRouter& ipc_router() { return ipc_router_; } 200 201 Profile* profile() const; 202 203 // Helper function to navigate the given contents to the local fallback 204 // Instant URL and trim the history correctly. 205 void RedirectToLocalNTP(); 206 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; 210 211 // Returns the OmniboxView for |web_contents_| or NULL if not available. 212 OmniboxView* GetOmniboxView() const; 213 214 typedef bool (*OmniboxHasFocusFn)(OmniboxView*); 215 set_omnibox_has_focus_fn(OmniboxHasFocusFn fn)216 void set_omnibox_has_focus_fn(OmniboxHasFocusFn fn) { 217 omnibox_has_focus_fn_ = fn; 218 } 219 220 const bool is_search_enabled_; 221 222 // Model object for UI that cares about search state. 223 SearchModel model_; 224 225 content::WebContents* web_contents_; 226 227 SearchIPCRouter ipc_router_; 228 229 InstantService* instant_service_; 230 231 // Delegate for notifying our owner about the SearchTabHelper state. Not owned 232 // by us. 233 // NULL on iOS and Android because they don't use the Instant framework. 234 SearchTabHelperDelegate* delegate_; 235 236 // Function to check if the omnibox has focus. Tests use this to modify the 237 // default behavior. 238 OmniboxHasFocusFn omnibox_has_focus_fn_; 239 240 DISALLOW_COPY_AND_ASSIGN(SearchTabHelper); 241 }; 242 243 #endif // CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ 244