Home | History | Annotate | Download | only in search
      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 
     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 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.
    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 
    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