OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ | 5 #ifndef CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ |
6 #define CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ | 6 #define CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
16 #include "base/string16.h" | 16 #include "base/string16.h" |
17 #include "base/timer.h" | 17 #include "base/timer.h" |
18 #include "chrome/browser/instant/instant_commit_type.h" | 18 #include "chrome/browser/instant/instant_commit_type.h" |
19 #include "chrome/browser/instant/instant_loader_delegate.h" | |
20 #include "chrome/browser/instant/instant_model.h" | 19 #include "chrome/browser/instant/instant_model.h" |
21 #include "chrome/common/instant_types.h" | 20 #include "chrome/common/instant_types.h" |
22 #include "content/public/common/page_transition_types.h" | 21 #include "content/public/common/page_transition_types.h" |
23 #include "googleurl/src/gurl.h" | 22 #include "googleurl/src/gurl.h" |
24 #include "ui/gfx/native_widget_types.h" | 23 #include "ui/gfx/native_widget_types.h" |
25 #include "ui/gfx/rect.h" | 24 #include "ui/gfx/rect.h" |
26 | 25 |
27 struct AutocompleteMatch; | 26 struct AutocompleteMatch; |
28 class AutocompleteProvider; | 27 class AutocompleteProvider; |
29 class InstantControllerDelegate; | |
30 class InstantLoader; | 28 class InstantLoader; |
31 class PrefService; | 29 class PrefService; |
32 class Profile; | 30 class Profile; |
33 class TabContents; | 31 class TabContents; |
34 class TemplateURL; | 32 class TemplateURL; |
35 | 33 |
| 34 namespace chrome { |
| 35 class BrowserInstantController; |
| 36 } |
| 37 |
36 // InstantController maintains a WebContents that is intended to give a | 38 // InstantController maintains a WebContents that is intended to give a |
37 // preview of search results. InstantController is owned by Browser via | 39 // preview of search results. InstantController is owned by Browser via |
38 // BrowserInstantController. | 40 // BrowserInstantController. |
39 // | 41 // |
40 // At any time the WebContents maintained by InstantController may be hidden | 42 // At any time the WebContents maintained by InstantController may be hidden |
41 // from view by way of Hide(), which may result in a change in the model's | 43 // from view by way of Hide(), which may result in a change in the model's |
42 // display state and subsequent change in model observers. Similarly the preview | 44 // display state and subsequent change in model observers. Similarly, the |
43 // may be committed at any time by invoking CommitCurrentPreview(), which | 45 // preview may be committed at any time by invoking CommitCurrentPreview(), |
44 // results in CommitInstant() being invoked on the delegate. | 46 // which results in CommitInstant() being invoked on the browser. |
45 class InstantController : public InstantLoaderDelegate { | 47 class InstantController { |
46 public: | 48 public: |
47 // Amount of time to wait before starting the animation for suggested text. | |
48 static const int kInlineAutocompletePauseTimeMS = 1000; | |
49 | |
50 // Duration of the suggested text animation in which the colors change. | |
51 static const int kInlineAutocompleteFadeInTimeMS = 300; | |
52 | |
53 // InstantController may operate in one of these modes: | 49 // InstantController may operate in one of these modes: |
54 // EXTENDED: The default search engine is preloaded when the omnibox gets | 50 // EXTENDED: The default search engine is preloaded when the omnibox gets |
55 // focus. Queries are issued as the user types. Predicted queries are | 51 // focus. Queries are issued as the user types. Predicted queries are |
56 // inline autocompleted into the omnibox. Previews of search results | 52 // inline autocompleted into the omnibox. Previews of search results |
57 // as well as predicted URLs are shown. Search suggestions are rendered | 53 // as well as predicted URLs are shown. Search suggestions are rendered |
58 // within the search results preview. | 54 // within the search results preview. |
59 // INSTANT: Same as EXTENDED, without URL previews. Search suggestions are | 55 // INSTANT: Same as EXTENDED, without URL previews. Search suggestions are |
60 // rendered by the omnibox drop down, and not by the preview page. | 56 // rendered by the omnibox drop down, and not by the preview page. |
61 // SUGGEST: Same as INSTANT, without visible previews. | |
62 // HIDDEN: Same as SUGGEST, without the inline autocompletion. | |
63 // SILENT: Same as HIDDEN, without issuing queries as the user types. The | |
64 // query is sent only after the user presses <Enter>. | |
65 // DISABLED: Instant is disabled. | 57 // DISABLED: Instant is disabled. |
66 enum Mode { | 58 enum Mode { |
67 EXTENDED, | 59 EXTENDED, |
68 INSTANT, | 60 INSTANT, |
69 SUGGEST, | |
70 HIDDEN, | |
71 SILENT, | |
72 DISABLED, | 61 DISABLED, |
73 }; | 62 }; |
74 | 63 |
75 virtual ~InstantController(); | 64 virtual ~InstantController(); |
76 | 65 |
77 // Creates a new InstantController. Caller owns the returned object. The | 66 // Creates a new InstantController. Caller owns the returned object. The |
78 // |profile| pointer is not cached, so the underlying profile object need not | 67 // |profile| pointer is not cached, so the underlying profile object need not |
79 // live beyond this call. ***NOTE***: May return NULL, which means that | 68 // live beyond this call. ***NOTE***: May return NULL, which means that |
80 // Instant is disabled in this profile. | 69 // Instant is disabled in this profile. |
81 static InstantController* CreateInstant(Profile* profile, | 70 static InstantController* CreateInstant( |
82 InstantControllerDelegate* delegate); | 71 Profile* profile, |
| 72 chrome::BrowserInstantController* browser); |
83 | 73 |
84 // Returns true if Instant is enabled and supports the extended API. | 74 // Returns true if Instant is enabled and supports the extended API. |
85 static bool IsExtendedAPIEnabled(Profile* profile); | 75 static bool IsExtendedAPIEnabled(Profile* profile); |
86 | 76 |
87 // Returns true if Instant is enabled in a visible, preview-showing mode. | 77 // Returns true if Instant is enabled in a visible, preview-showing mode. |
88 static bool IsInstantEnabled(Profile* profile); | 78 static bool IsInstantEnabled(Profile* profile); |
89 | 79 |
90 // Returns true if Instant will provide autocomplete suggestions. | |
91 static bool IsSuggestEnabled(Profile* profile); | |
92 | |
93 // Registers Instant related preferences. | 80 // Registers Instant related preferences. |
94 static void RegisterUserPrefs(PrefService* prefs); | 81 static void RegisterUserPrefs(PrefService* prefs); |
95 | 82 |
96 // Invoked as the user types into the omnibox. |user_text| is what the user | 83 // Invoked as the user types into the omnibox. |user_text| is what the user |
97 // has typed. |full_text| is what the omnibox is showing. These may differ if | 84 // has typed. |full_text| is what the omnibox is showing. These may differ if |
98 // the user typed only some text, and the rest was inline autocompleted. If | 85 // the user typed only some text, and the rest was inline autocompleted. If |
99 // |verbatim| is true, search results are shown for the exact omnibox text, | 86 // |verbatim| is true, search results are shown for the exact omnibox text, |
100 // rather than the best guess as to what the user means. Returns true if the | 87 // rather than the best guess as to what the user means. Returns true if the |
101 // update is accepted (i.e., if |match| is a search rather than a URL). | 88 // update is accepted (i.e., if |match| is a search rather than a URL). |
102 bool Update(const AutocompleteMatch& match, | 89 bool Update(const AutocompleteMatch& match, |
(...skipping 20 matching lines...) Expand all Loading... |
123 | 110 |
124 // Hides the preview, but doesn't destroy it, in hopes it can be subsequently | 111 // Hides the preview, but doesn't destroy it, in hopes it can be subsequently |
125 // reused. The preview will not be used until a call to Update() succeeds. | 112 // reused. The preview will not be used until a call to Update() succeeds. |
126 void Hide(); | 113 void Hide(); |
127 | 114 |
128 // Returns true if the Instant preview can be committed now. This can be true | 115 // Returns true if the Instant preview can be committed now. This can be true |
129 // even if the preview is not showing yet, because we can commit as long as | 116 // even if the preview is not showing yet, because we can commit as long as |
130 // we've processed the last Update() and we know the loader supports Instant. | 117 // we've processed the last Update() and we know the loader supports Instant. |
131 bool IsCurrent() const; | 118 bool IsCurrent() const; |
132 | 119 |
133 // Commits the preview. Calls CommitInstant() on the delegate. | 120 // Commits the preview. Calls CommitInstant() on the browser. |
134 void CommitCurrentPreview(InstantCommitType type); | 121 void CommitCurrentPreview(InstantCommitType type); |
135 | 122 |
136 // The autocomplete edit that was initiating the current Instant session has | 123 // The autocomplete edit that was initiating the current Instant session has |
137 // lost focus. Commit or discard the preview accordingly. | 124 // lost focus. Commit or discard the preview accordingly. |
138 void OnAutocompleteLostFocus(gfx::NativeView view_gaining_focus); | 125 void OnAutocompleteLostFocus(gfx::NativeView view_gaining_focus); |
139 | 126 |
140 // The autocomplete edit has gained focus. Preload the Instant URL of the | 127 // The autocomplete edit has gained focus. Preload the Instant URL of the |
141 // default search engine, in anticipation of the user typing a query. | 128 // default search engine, in anticipation of the user typing a query. |
142 void OnAutocompleteGotFocus(); | 129 void OnAutocompleteGotFocus(); |
143 | 130 |
144 // The active tab's "NTP status" has changed. Pass the message down to the | 131 // The active tab's "NTP status" has changed. Pass the message down to the |
145 // loader which will notify the renderer. | 132 // loader which will notify the renderer. |
146 void OnActiveTabModeChanged(bool active_tab_is_ntp); | 133 void OnActiveTabModeChanged(bool active_tab_is_ntp); |
147 | 134 |
148 // Returns whether the preview will be committed when the mouse or touch | 135 // Returns whether the preview will be committed when the mouse or touch |
149 // pointer is released. | 136 // pointer is released. |
150 bool commit_on_pointer_release() const; | 137 bool commit_on_pointer_release() const; |
151 | 138 |
152 // Returns the transition type of the last AutocompleteMatch passed to Update. | 139 // Returns the transition type of the last AutocompleteMatch passed to Update. |
153 content::PageTransition last_transition_type() const { | 140 content::PageTransition last_transition_type() const { |
154 return last_transition_type_; | 141 return last_transition_type_; |
155 } | 142 } |
156 | 143 |
157 // InstantLoaderDelegate: | 144 const InstantModel* model() const { return &model_; } |
158 virtual void SetSuggestions( | 145 |
159 InstantLoader* loader, | 146 // Invoked by InstantLoader when it has suggested text. |
160 const std::vector<InstantSuggestion>& suggestions) OVERRIDE; | 147 void SetSuggestions(InstantLoader* loader, |
161 virtual void CommitInstantLoader(InstantLoader* loader) OVERRIDE; | 148 const std::vector<InstantSuggestion>& suggestions); |
162 virtual void ShowInstantPreview(InstantLoader* loader, | 149 |
163 InstantShownReason reason, | 150 // Invoked by InstantLoader to commit the preview. |
164 int height, | 151 void CommitInstantLoader(InstantLoader* loader); |
165 InstantSizeUnits units) OVERRIDE; | 152 |
166 virtual void InstantLoaderPreviewLoaded(InstantLoader* loader) OVERRIDE; | 153 // Invoked by InstantLoader to request that the preview be shown. |
167 virtual void InstantSupportDetermined(InstantLoader* loader, | 154 void ShowInstantPreview(InstantLoader* loader, |
168 bool supports_instant) OVERRIDE; | 155 InstantShownReason reason, |
169 virtual void SwappedTabContents(InstantLoader* loader) OVERRIDE; | 156 int height, |
170 virtual void InstantLoaderContentsFocused(InstantLoader* loader) OVERRIDE; | 157 InstantSizeUnits units); |
| 158 |
| 159 // Invoked by InstantLoader to notify that the Instant URL completed loading. |
| 160 void InstantLoaderPreviewLoaded(InstantLoader* loader); |
| 161 |
| 162 // Invoked by InstantLoader when it has determined whether or not the page |
| 163 // supports the Instant API. |
| 164 void InstantSupportDetermined(InstantLoader* loader, bool supports_instant); |
| 165 |
| 166 // Invoked by InstantLoader when it has swapped a different TabContents into |
| 167 // the preview, usually because a prerendered page was navigated to. |
| 168 void SwappedTabContents(InstantLoader* loader); |
| 169 |
| 170 // Invoked by InstantLoader when the preview gains focus, usually due to the |
| 171 // user clicking on it. |
| 172 void InstantLoaderContentsFocused(InstantLoader* loader); |
171 | 173 |
172 #if defined(UNIT_TEST) | 174 #if defined(UNIT_TEST) |
173 // Accessors used only in tests. | 175 // Accessors used only in tests. |
174 InstantLoader* loader() const { return loader_.get(); } | 176 InstantLoader* loader() const { return loader_.get(); } |
175 #endif | 177 #endif |
176 | 178 |
177 const InstantModel* model() const { return &model_; } | |
178 | |
179 private: | 179 private: |
180 FRIEND_TEST_ALL_PREFIXES(InstantTest, InstantLoaderRefresh); | 180 FRIEND_TEST_ALL_PREFIXES(InstantTest, InstantLoaderRefresh); |
181 | 181 |
182 InstantController(InstantControllerDelegate* delegate, Mode mode); | 182 InstantController(chrome::BrowserInstantController* browser, Mode mode); |
183 | 183 |
184 // Creates a new loader if necessary (for example, if the |instant_url| has | 184 // Creates a new loader if necessary (for example, if the |instant_url| has |
185 // changed since the last time we created the loader). | 185 // changed since the last time we created the loader). |
186 void ResetLoader(const std::string& instant_url, | 186 void ResetLoader(const std::string& instant_url, |
187 const TabContents* active_tab); | 187 const TabContents* active_tab); |
188 | 188 |
189 // Ensures that the |loader_| uses the default Instant URL, recreating it if | 189 // Ensures that the |loader_| uses the default Instant URL, recreating it if |
190 // necessary, and returns true. Returns false if the Instant URL could not be | 190 // necessary, and returns true. Returns false if the Instant URL could not be |
191 // determined or the active tab is NULL (browser is shutting down). | 191 // determined or the active tab is NULL (browser is shutting down). |
192 bool CreateDefaultLoader(); | 192 bool CreateDefaultLoader(); |
193 | 193 |
194 // If the |loader_| is not showing, it is deleted and recreated. Else the | 194 // If the |loader_| is not showing, it is deleted and recreated. Else the |
195 // refresh is skipped and the next refresh is scheduled. | 195 // refresh is skipped and the next refresh is scheduled. |
196 void OnStaleLoader(); | 196 void OnStaleLoader(); |
197 | 197 |
198 // Calls OnStaleLoader if |stale_loader_timer_| is not running. | 198 // Calls OnStaleLoader if |stale_loader_timer_| is not running. |
199 void MaybeOnStaleLoader(); | 199 void MaybeOnStaleLoader(); |
200 | 200 |
201 // Destroys the |loader_| and its preview contents. | 201 // Destroys the |loader_| and its preview contents. |
202 void DeleteLoader(); | 202 void DeleteLoader(); |
203 | 203 |
204 // Counterpart to Hide(). Asks the |delegate_| to display the preview with | 204 // Counterpart to Hide(). Asks the |browser_| to display the preview with |
205 // the given |height|. | 205 // the given |height|. |
206 void Show(int height, InstantSizeUnits units); | 206 void Show(int height, InstantSizeUnits units); |
207 | 207 |
208 // Send the omnibox dropdown bounds to the page. | 208 // Send the omnibox dropdown bounds to the page. |
209 void SendBoundsToPage(); | 209 void SendBoundsToPage(); |
210 | 210 |
211 // If |template_url| is a valid TemplateURL for use with Instant, fills in | 211 // If |template_url| is a valid TemplateURL for use with Instant, fills in |
212 // |instant_url| and returns true; returns false otherwise. | 212 // |instant_url| and returns true; returns false otherwise. |
213 // Note: If the command-line switch kInstantURL is set, this method uses its | 213 // Note: If the command-line switch kInstantURL is set, this method uses its |
214 // value for |instant_url| and returns true without examining |template_url|. | 214 // value for |instant_url| and returns true without examining |template_url|. |
215 bool GetInstantURL(const TemplateURL* template_url, | 215 bool GetInstantURL(const TemplateURL* template_url, |
216 const GURL& tab_url, | 216 const GURL& tab_url, |
217 std::string* instant_url) const; | 217 std::string* instant_url) const; |
218 | 218 |
219 // Returns true if the preview is no longer relevant, say because the last | 219 // Returns true if the preview is no longer relevant, say because the last |
220 // Update() was for a URL and not a search query, or the user switched tabs. | 220 // Update() was for a URL and not a search query, or the user switched tabs. |
221 bool IsOutOfDate() const; | 221 bool IsOutOfDate() const; |
222 | 222 |
223 InstantControllerDelegate* const delegate_; | 223 chrome::BrowserInstantController* const browser_; |
224 | 224 |
225 InstantModel model_; | 225 InstantModel model_; |
226 | 226 |
227 scoped_ptr<InstantLoader> loader_; | 227 scoped_ptr<InstantLoader> loader_; |
228 | 228 |
229 // See the enum description above. | 229 // See the enum description above. |
230 const Mode mode_; | 230 const Mode mode_; |
231 | 231 |
232 // The active tab at the time of the last Update(). Used by IsOutOfDate() to | 232 // The active tab at the time of the last Update(). Used by IsOutOfDate() to |
233 // know whether the user switched tabs. ***NEVER DEREFERENCE THIS POINTER.*** | 233 // know whether the user switched tabs. ***NEVER DEREFERENCE THIS POINTER.*** |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 // the map at all or has a value 0, it means that search engine supports the | 282 // the map at all or has a value 0, it means that search engine supports the |
283 // Instant API (or we assume it does, since we haven't determined it doesn't). | 283 // Instant API (or we assume it does, since we haven't determined it doesn't). |
284 std::map<std::string, int> blacklisted_urls_; | 284 std::map<std::string, int> blacklisted_urls_; |
285 | 285 |
286 // Search terms extraction (for autocomplete history matches) doesn't work | 286 // Search terms extraction (for autocomplete history matches) doesn't work |
287 // on Instant URLs. So, whenever the user commits an Instant search, we add | 287 // on Instant URLs. So, whenever the user commits an Instant search, we add |
288 // an equivalent non-Instant search URL to history, so that the search shows | 288 // an equivalent non-Instant search URL to history, so that the search shows |
289 // up in autocomplete history matches. | 289 // up in autocomplete history matches. |
290 GURL url_for_history_; | 290 GURL url_for_history_; |
291 | 291 |
292 DISALLOW_IMPLICIT_CONSTRUCTORS(InstantController); | 292 DISALLOW_COPY_AND_ASSIGN(InstantController); |
293 }; | 293 }; |
294 | 294 |
295 #endif // CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ | 295 #endif // CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ |
OLD | NEW |