// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ #define CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ #include #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/time/time.h" #include "chrome/browser/search/instant_service_observer.h" #include "chrome/browser/ui/search/search_ipc_router.h" #include "chrome/browser/ui/search/search_model.h" #include "chrome/common/instant_types.h" #include "chrome/common/ntp_logging_events.h" #include "components/omnibox/common/omnibox_focus_state.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "ui/base/window_open_disposition.h" namespace content { class WebContents; struct LoadCommittedDetails; } class GURL; class InstantPageTest; class InstantService; class OmniboxView; class Profile; class SearchIPCRouterTest; class SearchTabHelperDelegate; // Per-tab search "helper". Acts as the owner and controller of the tab's // search UI model. // // When the page is finished loading, SearchTabHelper determines the instant // support for the page. When a navigation entry is committed (except for // in-page navigations), SearchTabHelper resets the instant support state to // INSTANT_SUPPORT_UNKNOWN and cause support to be determined again. class SearchTabHelper : public content::WebContentsObserver, public content::WebContentsUserData, public InstantServiceObserver, public SearchIPCRouter::Delegate { public: ~SearchTabHelper() override; SearchModel* model() { return &model_; } // Sets up the initial state correctly for a preloaded NTP. void InitForPreloadedNTP(); // Invoked when the omnibox input state is changed in some way that might // affect the search mode. void OmniboxInputStateChanged(); // Called to indicate that the omnibox focus state changed with the given // |reason|. void OmniboxFocusChanged(OmniboxFocusState state, OmniboxFocusChangeReason reason); // Invoked when the active navigation entry is updated in some way that might // affect the search mode. This is used by Instant when it "fixes up" the // virtual URL of the active entry. Regular navigations are captured through // the notification system and shouldn't call this method. void NavigationEntryUpdated(); // Invoked to update the instant support state. void InstantSupportChanged(bool supports_instant); // Returns true if the page supports instant. If the instant support state is // not determined or if the page does not support instant returns false. bool SupportsInstant() const; // Sends the current SearchProvider suggestion to the Instant page if any. void SetSuggestionToPrefetch(const InstantSuggestion& suggestion); // Tells the page that the user pressed Enter in the omnibox. void Submit(const base::string16& text, const EmbeddedSearchRequestParams& params); // Called when the tab corresponding to |this| instance is activated. void OnTabActivated(); // Called when the tab corresponding to |this| instance is deactivated. void OnTabDeactivated(); // Returns true if the underlying page is a search results page. bool IsSearchResultsPage(); void set_delegate(SearchTabHelperDelegate* delegate) { delegate_ = delegate; } private: friend class content::WebContentsUserData; friend class InstantPageTest; friend class SearchIPCRouterPolicyTest; friend class SearchIPCRouterTest; friend class SearchTabHelperPrerenderTest; FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, DetermineIfPageSupportsInstant_Local); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, DetermineIfPageSupportsInstant_NonLocal); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, PageURLDoesntBelongToInstantRenderer); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnChromeIdentityCheckMatch); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnChromeIdentityCheckMatchSlightlyDifferentGmail); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnChromeIdentityCheckMatchSlightlyDifferentGmail2); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnChromeIdentityCheckMismatch); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnChromeIdentityCheckSignedOutMatch); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnChromeIdentityCheckSignedOutMismatch); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnHistorySyncCheckSyncInactive); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnHistorySyncCheckSyncing); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnHistorySyncCheckNotSyncing); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnMostVisitedItemsChangedFromServer); FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest, OnMostVisitedItemsChangedFromClient); FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, IgnoreMessageIfThePageIsNotActive); FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, DoNotSendSetDisplayInstantResultsMsg); FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, HandleTabChangedEvents); FRIEND_TEST_ALL_PREFIXES(InstantPageTest, DetermineIfPageSupportsInstant_Local); FRIEND_TEST_ALL_PREFIXES(InstantPageTest, DetermineIfPageSupportsInstant_NonLocal); FRIEND_TEST_ALL_PREFIXES(InstantPageTest, PageURLDoesntBelongToInstantRenderer); FRIEND_TEST_ALL_PREFIXES(InstantPageTest, PageSupportsInstant); explicit SearchTabHelper(content::WebContents* web_contents); // Overridden from contents::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; void DidStartNavigationToPendingEntry( const GURL& url, content::NavigationController::ReloadType reload_type) override; void DidNavigateMainFrame( const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) override; void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; void NavigationEntryCommitted( const content::LoadCommittedDetails& load_details) override; // Overridden from SearchIPCRouter::Delegate: void OnInstantSupportDetermined(bool supports_instant) override; void FocusOmnibox(OmniboxFocusState state) override; void NavigateToURL(const GURL& url, WindowOpenDisposition disposition) override; void OnDeleteMostVisitedItem(const GURL& url) override; void OnUndoMostVisitedDeletion(const GURL& url) override; void OnUndoAllMostVisitedDeletions() override; void OnLogEvent(NTPLoggingEventType event, base::TimeDelta time) override; void OnLogMostVisitedImpression(int position, const base::string16& provider) override; void OnLogMostVisitedNavigation(int position, const base::string16& provider) override; void PasteIntoOmnibox(const base::string16& text) override; void OnChromeIdentityCheck(const base::string16& identity) override; void OnHistorySyncCheck() override; // Overridden from InstantServiceObserver: void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) override; void MostVisitedItemsChanged( const std::vector& items) override; // Sets the mode of the model based on the current URL of web_contents(). // Only updates the origin part of the mode if |update_origin| is true, // otherwise keeps the current origin. If |is_preloaded_ntp| is true, the mode // is set to NTP regardless of the current URL; this is used to ensure that // InstantController can bind InstantTab to new tab pages immediately. void UpdateMode(bool update_origin, bool is_preloaded_ntp); // Tells the renderer to determine if the page supports the Instant API, which // results in a call to OnInstantSupportDetermined() when the reply is // received. void DetermineIfPageSupportsInstant(); // Used by unit tests. SearchIPCRouter& ipc_router() { return ipc_router_; } Profile* profile() const; // Returns whether input is in progress, i.e. if the omnibox has focus and the // active tab is in mode SEARCH_SUGGESTIONS. bool IsInputInProgress() const; // Returns the OmniboxView for |web_contents_| or NULL if not available. OmniboxView* GetOmniboxView() const; // Record whether each suggestion comes from server or client. void LogMostVisitedItemsSource( const std::vector& items); typedef bool (*OmniboxHasFocusFn)(OmniboxView*); void set_omnibox_has_focus_fn(OmniboxHasFocusFn fn) { omnibox_has_focus_fn_ = fn; } const bool is_search_enabled_; // Model object for UI that cares about search state. SearchModel model_; content::WebContents* web_contents_; SearchIPCRouter ipc_router_; InstantService* instant_service_; // Delegate for notifying our owner about the SearchTabHelper state. Not owned // by us. // NULL on iOS and Android because they don't use the Instant framework. SearchTabHelperDelegate* delegate_; // Function to check if the omnibox has focus. Tests use this to modify the // default behavior. OmniboxHasFocusFn omnibox_has_focus_fn_; DISALLOW_COPY_AND_ASSIGN(SearchTabHelper); }; #endif // CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_