• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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