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_INSTANT_CONTROLLER_H_ 6 #define CHROME_BROWSER_UI_SEARCH_INSTANT_CONTROLLER_H_ 7 8 #include <list> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "base/basictypes.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/strings/string16.h" 17 #include "chrome/browser/ui/search/instant_page.h" 18 #include "chrome/common/instant_types.h" 19 #include "chrome/common/omnibox_focus_state.h" 20 #include "chrome/common/search_types.h" 21 #include "content/public/common/page_transition_types.h" 22 #include "ui/base/window_open_disposition.h" 23 #include "ui/gfx/native_widget_types.h" 24 #include "ui/gfx/rect.h" 25 #include "url/gurl.h" 26 27 class BrowserInstantController; 28 class InstantService; 29 class InstantTab; 30 class Profile; 31 32 namespace content { 33 class WebContents; 34 } 35 36 namespace gfx { 37 class Rect; 38 } 39 40 // Macro used for logging debug events. |message| should be a std::string. 41 #define LOG_INSTANT_DEBUG_EVENT(controller, message) \ 42 controller->LogDebugEvent(message) 43 44 // InstantController drives Chrome Instant, i.e., the browser implementation of 45 // the Embedded Search API (see http://dev.chromium.org/embeddedsearch). 46 // 47 // In extended mode, InstantController maintains and coordinates an InstantTab 48 // instance of InstantPage. An InstantTab instance points to the currently 49 // active tab, if it supports the Embedded Search API. InstantTab is backed by a 50 // WebContents and it does not own that WebContents. 51 // 52 // InstantController is owned by Browser via BrowserInstantController. 53 class InstantController : public InstantPage::Delegate { 54 public: 55 explicit InstantController(BrowserInstantController* browser); 56 virtual ~InstantController(); 57 58 // Sets the stored start-edge margin and width of the omnibox. 59 void SetOmniboxBounds(const gfx::Rect& bounds); 60 61 // Notifies |instant_Tab_| to toggle voice search. 62 void ToggleVoiceSearch(); 63 64 // Called if the browser is navigating to a search URL for |search_terms| with 65 // search-term-replacement enabled. If |instant_tab_| can be used to process 66 // the search, this does so and returns true. Else, returns false. 67 bool SubmitQuery(const string16& search_terms); 68 69 // Called to indicate that the omnibox focus state changed with the given 70 // |reason|. If |focus_state| is FOCUS_NONE, |view_gaining_focus| is set to 71 // the view gaining focus. 72 void OmniboxFocusChanged(OmniboxFocusState focus_state, 73 OmniboxFocusChangeReason reason, 74 gfx::NativeView view_gaining_focus); 75 76 // The search mode in the active tab has changed. Bind |instant_tab_| if the 77 // |new_mode| reflects an Instant search results page. 78 void SearchModeChanged(const SearchMode& old_mode, 79 const SearchMode& new_mode); 80 81 // The user switched tabs. Bind |instant_tab_| if the newly active tab is an 82 // Instant search results page. 83 void ActiveTabChanged(); 84 85 // The user is about to switch tabs. 86 void TabDeactivated(content::WebContents* contents); 87 88 // Adds a new event to |debug_events_| and also DVLOG's it. Ensures that 89 // |debug_events_| doesn't get too large. 90 void LogDebugEvent(const std::string& info) const; 91 92 // Resets list of debug events. 93 void ClearDebugEvents(); 94 95 // See comments for |debug_events_| below. 96 const std::list<std::pair<int64, std::string> >& debug_events() { 97 return debug_events_; 98 } 99 100 // Gets the stored start-edge margin and width of the omnibox. 101 const gfx::Rect omnibox_bounds() { 102 return omnibox_bounds_; 103 } 104 105 // Used by BrowserInstantController to notify InstantController about the 106 // instant support change event for the active web contents. 107 void InstantSupportChanged(InstantSupportState instant_support); 108 109 protected: 110 // Accessors are made protected for testing purposes. 111 virtual InstantTab* instant_tab() const; 112 113 virtual Profile* profile() const; 114 115 private: 116 friend class InstantExtendedManualTest; 117 friend class InstantTestBase; 118 119 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, ExtendedModeIsOn); 120 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, MostVisited); 121 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, NTPIsPreloaded); 122 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPIsUsedInNewTab); 123 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPIsUsedInSameTab); 124 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPForWrongProvider); 125 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPRenderProcessGone); 126 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, 127 PreloadedNTPDoesntSupportInstant); 128 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, ProcessIsolation); 129 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, UnrelatedSiteInstance); 130 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, OnDefaultSearchProviderChanged); 131 FRIEND_TEST_ALL_PREFIXES(InstantExtendedNetworkTest, 132 NTPReactsToNetworkChanges); 133 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, 134 AcceptingURLSearchDoesNotNavigate); 135 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, AcceptingJSSearchDoesNotRunJS); 136 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, 137 ReloadSearchAfterBackReloadsCorrectQuery); 138 FRIEND_TEST_ALL_PREFIXES(InstantExtendedFirstTabTest, 139 RedirectToLocalOnLoadFailure); 140 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, KeyboardTogglesVoiceSearch); 141 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, HomeButtonAffectsMargin); 142 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, SearchReusesInstantTab); 143 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, 144 SearchDoesntReuseInstantTabWithoutSupport); 145 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, 146 TypedSearchURLDoesntReuseInstantTab); 147 FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, 148 DispatchMVChangeEventWhileNavigatingBackToNTP); 149 150 // Overridden from InstantPage::Delegate: 151 // TODO(shishir): We assume that the WebContent's current RenderViewHost is 152 // the RenderViewHost being created which is not always true. Fix this. 153 virtual void InstantSupportDetermined( 154 const content::WebContents* contents, 155 bool supports_instant) OVERRIDE; 156 virtual void InstantPageAboutToNavigateMainFrame( 157 const content::WebContents* contents, 158 const GURL& url) OVERRIDE; 159 virtual void FocusOmnibox(const content::WebContents* contents, 160 OmniboxFocusState state) OVERRIDE; 161 virtual void NavigateToURL( 162 const content::WebContents* contents, 163 const GURL& url, 164 content::PageTransition transition, 165 WindowOpenDisposition disposition, 166 bool is_search_type) OVERRIDE; 167 virtual void PasteIntoOmnibox(const content::WebContents* contents, 168 const string16& text) OVERRIDE; 169 virtual void InstantPageLoadFailed(content::WebContents* contents) OVERRIDE; 170 171 // Invoked by the InstantLoader when the Instant page wants to delete a 172 // Most Visited item. 173 virtual void DeleteMostVisitedItem(const GURL& url) OVERRIDE; 174 175 // Invoked by the InstantLoader when the Instant page wants to undo a 176 // Most Visited deletion. 177 virtual void UndoMostVisitedDeletion(const GURL& url) OVERRIDE; 178 179 // Invoked by the InstantLoader when the Instant page wants to undo all 180 // Most Visited deletions. 181 virtual void UndoAllMostVisitedDeletions() OVERRIDE; 182 183 // Helper function to navigate the given contents to the local fallback 184 // Instant URL and trim the history correctly. 185 void RedirectToLocalNTP(content::WebContents* contents); 186 187 // Helper for OmniboxFocusChanged. Commit or discard the overlay. 188 void OmniboxLostFocus(gfx::NativeView view_gaining_focus); 189 190 // If the active tab is an Instant search results page, sets |instant_tab_| to 191 // point to it. Else, deletes any existing |instant_tab_|. 192 void ResetInstantTab(); 193 194 // Sends theme info, omnibox bounds, font info, etc. down to the Instant tab. 195 void UpdateInfoForInstantTab(); 196 197 // Returns whether input is in progress, i.e. if the omnibox has focus and the 198 // active tab is in mode SEARCH_SUGGESTIONS. 199 bool IsInputInProgress() const; 200 201 // Returns true if the local page is being used. 202 bool UsingLocalPage() const; 203 204 // Returns the InstantService for the browser profile. 205 InstantService* GetInstantService() const; 206 207 BrowserInstantController* const browser_; 208 209 // The instance of InstantPage maintained by InstantController. 210 scoped_ptr<InstantTab> instant_tab_; 211 212 // Omnibox focus state. 213 OmniboxFocusState omnibox_focus_state_; 214 215 // The reason for the most recent omnibox focus change. 216 OmniboxFocusChangeReason omnibox_focus_change_reason_; 217 218 // The search model mode for the active tab. 219 SearchMode search_mode_; 220 221 // The start-edge margin and width of the omnibox, used by the page to align 222 // its suggestions with the omnibox. 223 gfx::Rect omnibox_bounds_; 224 225 // List of events and their timestamps, useful in debugging Instant behaviour. 226 mutable std::list<std::pair<int64, std::string> > debug_events_; 227 228 DISALLOW_COPY_AND_ASSIGN(InstantController); 229 }; 230 231 #endif // CHROME_BROWSER_UI_SEARCH_INSTANT_CONTROLLER_H_ 232