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 23namespace content { 24class WebContents; 25struct LoadCommittedDetails; 26} 27 28class GURL; 29class InstantPageTest; 30class InstantService; 31class OmniboxView; 32class Profile; 33class SearchIPCRouterTest; 34class 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. 43class SearchTabHelper : public content::WebContentsObserver, 44 public content::WebContentsUserData<SearchTabHelper>, 45 public InstantServiceObserver, 46 public SearchIPCRouter::Delegate { 47 public: 48 virtual ~SearchTabHelper(); 49 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 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_TEST_ALL_PREFIXES(SearchTabHelperTest, 105 DetermineIfPageSupportsInstant_Local); 106 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 107 DetermineIfPageSupportsInstant_NonLocal); 108 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 109 PageURLDoesntBelongToInstantRenderer); 110 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 111 OnChromeIdentityCheckMatch); 112 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 113 OnChromeIdentityCheckMismatch); 114 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 115 OnChromeIdentityCheckSignedOutMatch); 116 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 117 OnChromeIdentityCheckSignedOutMismatch); 118 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, 119 OnChromeIdentityCheckMatchNotSyncing); 120 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 121 OnProvisionalLoadFailRedirectNTPToLocal); 122 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 123 OnProvisionalLoadFailDontRedirectIfAborted); 124 FRIEND_TEST_ALL_PREFIXES(SearchTabHelperWindowTest, 125 OnProvisionalLoadFailDontRedirectNonNTP); 126 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, 127 IgnoreMessageIfThePageIsNotActive); 128 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, 129 DoNotSendSetDisplayInstantResultsMsg); 130 FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, HandleTabChangedEvents); 131 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 132 DetermineIfPageSupportsInstant_Local); 133 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 134 DetermineIfPageSupportsInstant_NonLocal); 135 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 136 PageURLDoesntBelongToInstantRenderer); 137 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, PageSupportsInstant); 138 139 explicit SearchTabHelper(content::WebContents* web_contents); 140 141 // Overridden from contents::WebContentsObserver: 142 virtual void RenderViewCreated( 143 content::RenderViewHost* render_view_host) OVERRIDE; 144 virtual void DidStartNavigationToPendingEntry( 145 const GURL& url, 146 content::NavigationController::ReloadType reload_type) OVERRIDE; 147 virtual void DidNavigateMainFrame( 148 const content::LoadCommittedDetails& details, 149 const content::FrameNavigateParams& params) OVERRIDE; 150 virtual void DidFailProvisionalLoad( 151 int64 frame_id, 152 const base::string16& frame_unique_name, 153 bool is_main_frame, 154 const GURL& validated_url, 155 int error_code, 156 const base::string16& error_description, 157 content::RenderViewHost* render_view_host) OVERRIDE; 158 virtual void DidFinishLoad( 159 int64 frame_id, 160 const GURL& validated_url, 161 bool is_main_frame, 162 content::RenderViewHost* render_view_host) OVERRIDE; 163 virtual void NavigationEntryCommitted( 164 const content::LoadCommittedDetails& load_details) OVERRIDE; 165 166 // Overridden from SearchIPCRouter::Delegate: 167 virtual void OnInstantSupportDetermined(bool supports_instant) OVERRIDE; 168 virtual void OnSetVoiceSearchSupport(bool supports_voice_search) OVERRIDE; 169 virtual void FocusOmnibox(OmniboxFocusState state) OVERRIDE; 170 virtual void NavigateToURL(const GURL& url, 171 WindowOpenDisposition disposition, 172 bool is_most_visited_item_url) OVERRIDE; 173 virtual void OnDeleteMostVisitedItem(const GURL& url) OVERRIDE; 174 virtual void OnUndoMostVisitedDeletion(const GURL& url) OVERRIDE; 175 virtual void OnUndoAllMostVisitedDeletions() OVERRIDE; 176 virtual void OnLogEvent(NTPLoggingEventType event) OVERRIDE; 177 virtual void OnLogMostVisitedImpression( 178 int position, const base::string16& provider) OVERRIDE; 179 virtual void OnLogMostVisitedNavigation( 180 int position, const base::string16& provider) OVERRIDE; 181 virtual void PasteIntoOmnibox(const base::string16& text) OVERRIDE; 182 virtual void OnChromeIdentityCheck(const base::string16& identity) OVERRIDE; 183 184 // Overridden from InstantServiceObserver: 185 virtual void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) OVERRIDE; 186 virtual void MostVisitedItemsChanged( 187 const std::vector<InstantMostVisitedItem>& items) OVERRIDE; 188 virtual void OmniboxStartMarginChanged(int omnibox_start_margin) OVERRIDE; 189 190 // Removes recommended URLs if a matching URL is already open in the Browser, 191 // if the Most Visited Tile Placement experiment is enabled, and the client is 192 // in the experiment group. 193 void MaybeRemoveMostVisitedItems(std::vector<InstantMostVisitedItem>* items); 194 195 // Sets the mode of the model based on the current URL of web_contents(). 196 // Only updates the origin part of the mode if |update_origin| is true, 197 // otherwise keeps the current origin. If |is_preloaded_ntp| is true, the mode 198 // is set to NTP regardless of the current URL; this is used to ensure that 199 // InstantController can bind InstantTab to new tab pages immediately. 200 void UpdateMode(bool update_origin, bool is_preloaded_ntp); 201 202 // Tells the renderer to determine if the page supports the Instant API, which 203 // results in a call to OnInstantSupportDetermined() when the reply is 204 // received. 205 void DetermineIfPageSupportsInstant(); 206 207 // Used by unit tests. 208 SearchIPCRouter& ipc_router() { return ipc_router_; } 209 210 Profile* profile() const; 211 212 // Helper function to navigate the given contents to the local fallback 213 // Instant URL and trim the history correctly. 214 void RedirectToLocalNTP(); 215 216 // Returns whether input is in progress, i.e. if the omnibox has focus and the 217 // active tab is in mode SEARCH_SUGGESTIONS. 218 bool IsInputInProgress() const; 219 220 // Returns the OmniboxView for |web_contents_| or NULL if not available. 221 OmniboxView* GetOmniboxView() const; 222 223 const bool is_search_enabled_; 224 225 // Model object for UI that cares about search state. 226 SearchModel model_; 227 228 content::WebContents* web_contents_; 229 230 SearchIPCRouter ipc_router_; 231 232 InstantService* instant_service_; 233 234 // Delegate for notifying our owner about the SearchTabHelper state. Not owned 235 // by us. 236 // NULL on iOS and Android because they don't use the Instant framework. 237 SearchTabHelperDelegate* delegate_; 238 239 DISALLOW_COPY_AND_ASSIGN(SearchTabHelper); 240}; 241 242#endif // CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ 243