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 "content/public/browser/web_contents_observer.h" 19 #include "content/public/browser/web_contents_user_data.h" 20 #include "ui/base/window_open_disposition.h" 21 22 namespace content { 23 class WebContents; 24 struct LoadCommittedDetails; 25 } 26 27 class GURL; 28 class InstantPageTest; 29 class InstantService; 30 class Profile; 31 class SearchIPCRouterTest; 32 33 // Per-tab search "helper". Acts as the owner and controller of the tab's 34 // search UI model. 35 // 36 // When the page is finished loading, SearchTabHelper determines the instant 37 // support for the page. When a navigation entry is committed (except for 38 // in-page navigations), SearchTabHelper resets the instant support state to 39 // INSTANT_SUPPORT_UNKNOWN and cause support to be determined again. 40 class SearchTabHelper : public content::WebContentsObserver, 41 public content::WebContentsUserData<SearchTabHelper>, 42 public InstantServiceObserver, 43 public SearchIPCRouter::Delegate { 44 public: 45 virtual ~SearchTabHelper(); 46 model()47 SearchModel* model() { 48 return &model_; 49 } 50 51 // Sets up the initial state correctly for a preloaded NTP. 52 void InitForPreloadedNTP(); 53 54 // Invoked when the OmniboxEditModel changes state in some way that might 55 // affect the search mode. 56 void OmniboxEditModelChanged(bool user_input_in_progress, bool cancelling); 57 58 // Invoked when the active navigation entry is updated in some way that might 59 // affect the search mode. This is used by Instant when it "fixes up" the 60 // virtual URL of the active entry. Regular navigations are captured through 61 // the notification system and shouldn't call this method. 62 void NavigationEntryUpdated(); 63 64 // Invoked to update the instant support state. 65 void InstantSupportChanged(bool supports_instant); 66 67 // Returns true if the page supports instant. If the instant support state is 68 // not determined or if the page does not support instant returns false. 69 bool SupportsInstant() const; 70 71 // Sends the current SearchProvider suggestion to the Instant page if any. 72 void SetSuggestionToPrefetch(const InstantSuggestion& suggestion); 73 74 // Tells the page that the user pressed Enter in the omnibox. 75 void Submit(const base::string16& text); 76 77 // Called when the tab corresponding to |this| instance is activated. 78 void OnTabActivated(); 79 80 // Called when the tab corresponding to |this| instance is deactivated. 81 void OnTabDeactivated(); 82 83 // Tells the page to toggle voice search. 84 void ToggleVoiceSearch(); 85 86 // Returns true if the underlying page is a search results page. 87 bool IsSearchResultsPage(); 88 89 private: 90 friend class content::WebContentsUserData<SearchTabHelper>; 91 friend class InstantPageTest; 92 friend class SearchIPCRouterPolicyTest; 93 friend class SearchIPCRouterTest; 94 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 95 DetermineIfPageSupportsInstant_Local); 96 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 97 DetermineIfPageSupportsInstant_NonLocal); 98 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 99 PageURLDoesntBelongToInstantRenderer); 100 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 101 OnChromeIdentityCheckMatch); 102 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 103 OnChromeIdentityCheckMismatch); 104 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 105 OnChromeIdentityCheckSignedOutMatch); 106 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 107 OnChromeIdentityCheckSignedOutMismatch); 108 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 109 OnProvisionalLoadFailRedirectNTPToLocal); 110 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 111 OnProvisionalLoadFailDontRedirectIfAborted); 112 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 113 OnProvisionalLoadFailDontRedirectNonNTP); 114 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, 115 IgnoreMessageIfThePageIsNotActive); 116 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, 117 DoNotSendSetDisplayInstantResultsMsg); 118 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, HandleTabChangedEvents); 119 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 120 DetermineIfPageSupportsInstant_Local); 121 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 122 DetermineIfPageSupportsInstant_NonLocal); 123 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 124 PageURLDoesntBelongToInstantRenderer); 125 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, PageSupportsInstant); 126 127 explicit SearchTabHelper(content::WebContents* web_contents); 128 129 // Overridden from contents::WebContentsObserver: 130 virtual void RenderViewCreated( 131 content::RenderViewHost* render_view_host) OVERRIDE; 132 virtual void DidStartNavigationToPendingEntry( 133 const GURL& url, 134 content::NavigationController::ReloadType reload_type) OVERRIDE; 135 virtual void DidNavigateMainFrame( 136 const content::LoadCommittedDetails& details, 137 const content::FrameNavigateParams& params) OVERRIDE; 138 virtual void DidFailProvisionalLoad( 139 int64 frame_id, 140 const base::string16& frame_unique_name, 141 bool is_main_frame, 142 const GURL& validated_url, 143 int error_code, 144 const base::string16& error_description, 145 content::RenderViewHost* render_view_host) OVERRIDE; 146 virtual void DidFinishLoad( 147 int64 frame_id, 148 const GURL& validated_url, 149 bool is_main_frame, 150 content::RenderViewHost* render_view_host) OVERRIDE; 151 virtual void NavigationEntryCommitted( 152 const content::LoadCommittedDetails& load_details) OVERRIDE; 153 154 // Overridden from SearchIPCRouter::Delegate: 155 virtual void OnInstantSupportDetermined(bool supports_instant) OVERRIDE; 156 virtual void OnSetVoiceSearchSupport(bool supports_voice_search) OVERRIDE; 157 virtual void FocusOmnibox(OmniboxFocusState state) OVERRIDE; 158 virtual void NavigateToURL(const GURL& url, 159 WindowOpenDisposition disposition, 160 bool is_most_visited_item_url) OVERRIDE; 161 virtual void OnDeleteMostVisitedItem(const GURL& url) OVERRIDE; 162 virtual void OnUndoMostVisitedDeletion(const GURL& url) OVERRIDE; 163 virtual void OnUndoAllMostVisitedDeletions() OVERRIDE; 164 virtual void OnLogEvent(NTPLoggingEventType event) OVERRIDE; 165 virtual void OnLogImpression(int position, 166 const base::string16& provider) OVERRIDE; 167 virtual void PasteIntoOmnibox(const base::string16& text) OVERRIDE; 168 virtual void OnChromeIdentityCheck(const base::string16& identity) OVERRIDE; 169 170 // Overridden from InstantServiceObserver: 171 virtual void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) OVERRIDE; 172 virtual void MostVisitedItemsChanged( 173 const std::vector<InstantMostVisitedItem>& items) OVERRIDE; 174 175 // Removes recommended URLs if a matching URL is already open in the Browser, 176 // if the Most Visited Tile Placement experiment is enabled, and the client is 177 // in the experiment group. 178 void MaybeRemoveMostVisitedItems(std::vector<InstantMostVisitedItem>* items); 179 180 // Sets the mode of the model based on the current URL of web_contents(). 181 // Only updates the origin part of the mode if |update_origin| is true, 182 // otherwise keeps the current origin. If |is_preloaded_ntp| is true, the mode 183 // is set to NTP regardless of the current URL; this is used to ensure that 184 // InstantController can bind InstantTab to new tab pages immediately. 185 void UpdateMode(bool update_origin, bool is_preloaded_ntp); 186 187 // Tells the renderer to determine if the page supports the Instant API, which 188 // results in a call to OnInstantSupportDetermined() when the reply is 189 // received. 190 void DetermineIfPageSupportsInstant(); 191 192 // Used by unit tests. ipc_router()193 SearchIPCRouter& ipc_router() { return ipc_router_; } 194 195 Profile* profile() const; 196 197 // Helper function to navigate the given contents to the local fallback 198 // Instant URL and trim the history correctly. 199 void RedirectToLocalNTP(); 200 201 const bool is_search_enabled_; 202 203 // Tracks the last value passed to OmniboxEditModelChanged(). 204 bool user_input_in_progress_; 205 206 // Model object for UI that cares about search state. 207 SearchModel model_; 208 209 content::WebContents* web_contents_; 210 211 SearchIPCRouter ipc_router_; 212 213 InstantService* instant_service_; 214 215 DISALLOW_COPY_AND_ASSIGN(SearchTabHelper); 216 }; 217 218 #endif // CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ 219