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 <set> | 8 #include <map> |
9 #include <string> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/memory/scoped_vector.h" | |
14 #include "base/memory/weak_ptr.h" | |
15 #include "base/string16.h" | 13 #include "base/string16.h" |
14 #include "base/timer.h" | |
16 #include "chrome/browser/instant/instant_commit_type.h" | 15 #include "chrome/browser/instant/instant_commit_type.h" |
17 #include "chrome/browser/instant/instant_loader_delegate.h" | 16 #include "chrome/browser/instant/instant_loader_delegate.h" |
18 #include "chrome/browser/search_engines/template_url_id.h" | |
19 #include "chrome/common/instant_types.h" | 17 #include "chrome/common/instant_types.h" |
20 #include "content/public/common/page_transition_types.h" | |
21 #include "googleurl/src/gurl.h" | |
22 #include "ui/gfx/native_widget_types.h" | |
23 #include "ui/gfx/rect.h" | 18 #include "ui/gfx/rect.h" |
24 | 19 |
25 struct AutocompleteMatch; | 20 struct AutocompleteMatch; |
21 class GURL; | |
26 class InstantControllerDelegate; | 22 class InstantControllerDelegate; |
27 class InstantLoader; | 23 class InstantLoader; |
28 class InstantTest; | |
29 class PrefService; | 24 class PrefService; |
30 class Profile; | 25 class Profile; |
31 class TabContents; | 26 class TabContents; |
32 class TemplateURL; | 27 class TemplateURL; |
33 | 28 |
34 // InstantController maintains a WebContents that is intended to give a preview | 29 // |InstantController| maintains a WebContents that is intended to give a |
sky
2012/07/19 17:55:19
Use |s for members/arguments, () for functions and
Jered
2012/07/19 22:01:33
Done.
| |
35 // of a URL. InstantController is owned by Browser. | 30 // preview of search results. InstantController is owned by Browser. |
36 // | 31 // |
37 // At any time the WebContents maintained by InstantController may be destroyed | 32 // At any time the WebContents maintained by InstantController may be hidden |
38 // by way of |DestroyPreviewContents|, which results in |HideInstant| being | 33 // from view by way of |Hide|, which may result in |HideInstant| being invoked |
39 // invoked on the delegate. Similarly the preview may be committed at any time | 34 // on the delegate. Similarly the preview may be committed at any time by |
40 // by invoking |CommitCurrentPreview|, which results in |CommitInstant| | 35 // invoking |CommitCurrentPreview|, which results in |CommitInstant| being |
41 // being invoked on the delegate. Also see |PrepareForCommit| below. | 36 // invoked on the delegate. |
42 class InstantController : public InstantLoaderDelegate { | 37 class InstantController : public InstantLoaderDelegate { |
43 public: | 38 public: |
44 // Amount of time to wait before starting the instant animation. | 39 // Amount of time to wait before starting the animation for suggested text. |
45 static const int kAutoCommitPauseTimeMS = 1000; | 40 static const int kAutoCommitPauseTimeMS = 1000; |
46 // Duration of the instant animation in which the colors change. | 41 |
42 // Duration of the suggested text animation in which the colors change. | |
47 static const int kAutoCommitFadeInTimeMS = 300; | 43 static const int kAutoCommitFadeInTimeMS = 300; |
48 | 44 |
49 // InstantController may operate in one of these modes: | 45 // InstantController may operate in one of these modes: |
50 // INSTANT: The default search engine is preloaded when the omnibox gets | 46 // INSTANT: The default search engine is preloaded when the omnibox gets |
51 // focus. Queries are issued as the user types. Predicted queries are | 47 // focus. Queries are issued as the user types. Predicted queries are |
52 // are inline autocompleted into the omnibox. Result previews are shown. | 48 // are inline autocompleted into the omnibox. Result previews are shown. |
53 // SUGGEST: Same as INSTANT, without visible previews. | 49 // SUGGEST: Same as INSTANT, without visible previews. |
54 // HIDDEN: Same as SUGGEST, without the inline autocompletion. | 50 // HIDDEN: Same as SUGGEST, without the inline autocompletion. |
55 // SILENT: Same as HIDDEN, without issuing queries as the user types. The | 51 // SILENT: Same as HIDDEN, without issuing queries as the user types. The |
56 // query is sent only after the user presses <Enter>. | 52 // query is sent only after the user presses <Enter>. |
57 enum Mode { | 53 enum Mode { |
58 INSTANT, | 54 INSTANT, |
59 SUGGEST, | 55 SUGGEST, |
60 HIDDEN, | 56 HIDDEN, |
61 SILENT | 57 SILENT |
62 }; | 58 }; |
63 | 59 |
64 InstantController(InstantControllerDelegate* delegate, Mode mode); | 60 InstantController(InstantControllerDelegate* delegate, Mode mode); |
65 virtual ~InstantController(); | 61 virtual ~InstantController(); |
66 | 62 |
67 // Registers instant related preferences. | 63 // Registers Instant related preferences. |
68 static void RegisterUserPrefs(PrefService* prefs); | 64 static void RegisterUserPrefs(PrefService* prefs); |
69 | 65 |
70 // Records instant metrics. | 66 // Records Instant metrics. |
71 static void RecordMetrics(Profile* profile); | 67 static void RecordMetrics(Profile* profile); |
72 | 68 |
73 // Returns true if instant is enabled in the given |profile|'s preferences. | 69 // Returns true if Instant is enabled in the given |profile|'s preferences. |
74 static bool IsEnabled(Profile* profile); | 70 static bool IsEnabled(Profile* profile); |
75 | 71 |
76 // Enables instant. | 72 // Enables Instant. |
77 static void Enable(Profile* profile); | 73 static void Enable(Profile* profile); |
78 | 74 |
79 // Disables instant. | 75 // Disables Instant. |
80 static void Disable(Profile* profile); | 76 static void Disable(Profile* profile); |
81 | 77 |
82 // Invoked as the user types in the omnibox with the url to navigate to. If | 78 // Invoked as the user types into the omnibox. |user_text| is what the user |
83 // the url is valid and a preview WebContents has not been created, it is | 79 // has typed. |suggested_text| is the current inline autocomplete text. It |
84 // created. If |verbatim| is true search results are shown for |user_text| | 80 // may be replaced by Instant's autocomplete suggestion, if any. If |verbatim| |
85 // rather than the best guess as to what the search thought the user meant. | 81 // is true, search results are shown for |user_text| rather than the best |
86 // |verbatim| only matters if the AutocompleteMatch is for a search engine | 82 // guess as to what Instant thinks the user means. Returns true if the update |
87 // that supports instant. Returns true if the attempt to update does not | 83 // is processed by Instant (i.e., if |match| is a search rather than a URL). |
88 // result in the preview WebContents being destroyed. | |
89 bool Update(const AutocompleteMatch& match, | 84 bool Update(const AutocompleteMatch& match, |
90 const string16& user_text, | 85 const string16& user_text, |
91 bool verbatim, | 86 bool verbatim, |
92 string16* suggested_text); | 87 string16* suggested_text, |
88 InstantCompleteBehavior* complete_behavior); | |
93 | 89 |
94 // Sets the bounds of the omnibox (in screen coordinates). The bounds are | 90 // Sets the bounds of the omnibox dropdown, in screen coordinates. |
95 // remembered until the preview is committed or destroyed. This is only used | |
96 // when showing results for a search provider that supports instant. | |
97 void SetOmniboxBounds(const gfx::Rect& bounds); | 91 void SetOmniboxBounds(const gfx::Rect& bounds); |
98 | 92 |
99 // Notifies the delegate to hide the preview and destroys the preview | 93 // The preview TabContents. May be NULL if |ReleasePreviewContents| has been |
100 // WebContents. Does nothing if the preview WebContents has not been created. | 94 // called, with no subsequent successful call to |Update|. InstantController |
101 void DestroyPreviewContents(); | 95 // retains ownership of the object. |
96 TabContents* GetPreviewContents() const; | |
102 | 97 |
103 // Notifies the delegate to hide the preview but leaves it around in hopes it | 98 // Hides the preview, but doesn't destroy it, in hopes it can be subsequently |
104 // can be subsequently used. The preview will not be used until Update() (with | 99 // reused. The preview will not be used until a call to |Update| succeeds. |
105 // valid parameters) is invoked. | |
106 void Hide(); | 100 void Hide(); |
107 | 101 |
108 // Returns true if we're showing the last URL passed to |Update|. If this is | 102 // Returns true if we're showing the last text passed to |Update|. If this is |
109 // false a commit does not result in committing the last url passed to update. | 103 // false, a commit does not result in committing the most recent |Update|. |
110 // A return value of false happens if we're in the process of determining if | |
111 // the page supports instant. | |
112 bool IsCurrent() const; | 104 bool IsCurrent() const; |
113 | 105 |
114 // Returns true if the caller should proceed with committing the preview. A | 106 // Unconditionally commits the preview. Returns the TabContents that contains |
115 // return value of false means that there is no valid preview to commit. This | 107 // the committed preview. |
116 // is used by Browser, when the user presses <Enter>, to decide whether to | |
117 // load the omnibox contents through Instant or otherwise. This is needed | |
118 // because calls to |Update| don't necessarily result in a preview being | |
119 // shown, such as in the HIDDEN and SILENT modes. | |
120 bool PrepareForCommit(); | |
121 | |
122 // Invoked when the user does some gesture that should trigger making the | |
123 // current previewed page the permanent page. Returns the TabContents that | |
124 // contains the committed preview. | |
125 TabContents* CommitCurrentPreview(InstantCommitType type); | 108 TabContents* CommitCurrentPreview(InstantCommitType type); |
126 | 109 |
127 // Accepts the currently showing instant preview, if any, and returns true. | 110 // Releases the preview WebContents passing ownership to the caller. This is |
128 // Returns false if there is no instant preview showing. | 111 // intended to be called when the preview WebContents is committed. This does |
129 bool CommitIfCurrent(); | 112 // not notify the delegate. |
113 TabContents* ReleasePreviewContents(InstantCommitType type) | |
114 WARN_UNUSED_RESULT; | |
sky
2012/07/19 17:55:19
Wrap 'InstantCommitType type' so that WARN_UNUSED_
Jered
2012/07/19 22:01:33
Done.
| |
130 | 115 |
131 // Sets InstantController so that when the mouse is released the preview is | 116 // The autocomplete edit that was initiating the current Instant session has |
132 // committed. | 117 // lost focus. Commit or discard the preview accordingly. |
133 void SetCommitOnMouseUp(); | 118 void OnAutocompleteLostFocus(); |
134 | 119 |
135 bool commit_on_mouse_up() const { return commit_on_mouse_up_; } | 120 // The autocomplete edit has gained focus. Preload the Instant URL of the |
136 | |
137 // Returns true if the mouse is down as the result of activating the preview | |
138 // content. | |
139 bool IsMouseDownFromActivate(); | |
140 | |
141 // The autocomplete edit that was initiating the current instant session has | |
142 // lost focus. Commit or discard the preview accordingly. | |
143 void OnAutocompleteLostFocus(gfx::NativeView view_gaining_focus); | |
144 | |
145 // The autocomplete edit has gained focus. Preload the instant URL of the | |
146 // default search engine, in anticipation of the user typing a query. | 121 // default search engine, in anticipation of the user typing a query. |
147 void OnAutocompleteGotFocus(); | 122 void OnAutocompleteGotFocus(); |
148 | 123 |
149 // Releases the preview WebContents passing ownership to the caller. This is | 124 // Returns whether the preview will be committed when the mouse is released. |
150 // intended to be called when the preview WebContents is committed. This does | 125 bool commit_on_mouse_up() const; |
151 // not notify the delegate. |tab_contents| is the underlying tab onto which | |
152 // the preview will be committed. It can be NULL when the underlying tab is | |
153 // irrelevant, for example when |type| is INSTANT_COMMIT_DESTROY. | |
154 // WARNING: be sure and invoke CompleteRelease after adding the returned | |
155 // WebContents to a tabstrip. | |
156 TabContents* ReleasePreviewContents(InstantCommitType type, | |
157 TabContents* tab_contents); | |
158 | 126 |
159 // Does cleanup after the preview contents has been added to the tabstrip. | 127 // InstantLoaderDelegate: |
160 // Invoke this if you explicitly invoke ReleasePreviewContents. | 128 virtual void SetSuggestions( |
161 void CompleteRelease(TabContents* tab); | 129 InstantLoader* loader, |
162 | 130 const std::vector<std::string>& suggestions, |
163 // The preview TabContents; may be null. | 131 InstantCompleteBehavior behavior) OVERRIDE; |
164 TabContents* GetPreviewContents() const; | |
165 | |
166 // Returns true if the preview TabContents is ready to be displayed. In | |
167 // some situations this may return false yet GetPreviewContents() returns | |
168 // non-NULL. | |
169 bool is_displayable() const { return is_displayable_; } | |
170 | |
171 // Returns the transition type of the last AutocompleteMatch passed to Update. | |
172 content::PageTransition last_transition_type() const { | |
173 return last_transition_type_; | |
174 } | |
175 | |
176 // InstantLoaderDelegate | |
177 virtual void InstantStatusChanged(InstantLoader* loader) OVERRIDE; | |
178 virtual void SetSuggestedTextFor(InstantLoader* loader, | |
179 const string16& text, | |
180 InstantCompleteBehavior behavior) OVERRIDE; | |
181 virtual gfx::Rect GetInstantBounds() OVERRIDE; | |
182 virtual bool ShouldCommitInstantOnMouseUp() OVERRIDE; | |
183 virtual void CommitInstantLoader(InstantLoader* loader) OVERRIDE; | 132 virtual void CommitInstantLoader(InstantLoader* loader) OVERRIDE; |
184 virtual void InstantLoaderDoesntSupportInstant( | 133 virtual void InstantLoaderPreviewLoaded(InstantLoader* loader) OVERRIDE; |
185 InstantLoader* loader) OVERRIDE; | 134 virtual void InstantSupportDetermined(InstantLoader* loader, |
186 virtual void AddToBlacklist(InstantLoader* loader, | 135 bool supports_instant) OVERRIDE; |
187 const GURL& url) OVERRIDE; | |
188 virtual void SwappedTabContents(InstantLoader* loader) OVERRIDE; | 136 virtual void SwappedTabContents(InstantLoader* loader) OVERRIDE; |
189 virtual void InstantLoaderContentsFocused() OVERRIDE; | 137 virtual void InstantLoaderContentsFocused(InstantLoader* loader) OVERRIDE; |
190 | 138 |
191 private: | 139 private: |
192 friend class InstantTest; | 140 friend class InstantTest; |
193 | 141 |
194 typedef std::set<std::string> HostBlacklist; | 142 // Creates a new loader if necessary (for example, if the |instant_id| has |
143 // changed since the last time we created the loader). | |
144 void ResetLoader(const string16& instant_id, | |
145 const GURL& instant_url, | |
146 const TabContents* tab_contents); | |
195 | 147 |
196 // Updates |is_displayable_| and if necessary notifies the delegate. | 148 // Destroys the |loader_| and its preview contents. |
197 void UpdateIsDisplayable(); | 149 void DeleteLoader(); |
198 | 150 |
199 // Updates InstantLoaderManager and its current InstantLoader. This is invoked | 151 // Counterpart to |Hide|. Asks the |delegate_| to display the preview. |
200 // internally from Update. | 152 void Show(); |
201 void UpdateLoader(TabContents* tab_contents, | |
202 const TemplateURL* template_url, | |
203 const GURL& url, | |
204 content::PageTransition transition_type, | |
205 const string16& user_text, | |
206 bool verbatim, | |
207 string16* suggested_text); | |
208 | 153 |
209 // Returns true if |template_url| is a valid TemplateURL for use by instant. | 154 // Send the omnibox dropdown bounds to the page. |
210 bool IsValidInstantTemplateURL(const TemplateURL* template_url); | 155 void SendBoundsToPage(); |
211 | 156 |
212 // Marks the loader as not supporting instant. | 157 // If |template_url| is a valid TemplateURL for use with Instant, fills in |
sky
2012/07/19 17:55:19
Description should include kInstantURL.
Jered
2012/07/19 22:01:33
Done.
| |
213 void BlacklistFromInstant(); | 158 // |instant_id| and |instant_url| and returns true; returns false otherwise. |
159 bool GetInstantURL(const TemplateURL* template_url, | |
160 string16* instant_id, | |
161 GURL* instant_url) const; | |
214 | 162 |
215 // Returns true if the specified id has been blacklisted from supporting | 163 // Returns true if the preview is no longer relevant, say because the last |
216 // instant. | 164 // |Update| was for a URL and not a search query, or the user switched tabs. |
217 bool IsBlacklistedFromInstant(TemplateURLID id); | 165 bool IsOutOfDate() const; |
218 | 166 |
219 // Clears the set of search engines blacklisted. | 167 InstantControllerDelegate* const delegate_; |
220 void ClearBlacklist(); | |
221 | |
222 // Deletes |loader| after a delay. At the time we determine a site doesn't | |
223 // want to participate in instant we can't destroy the loader (because | |
224 // destroying the loader destroys the WebContents and the WebContents is on | |
225 // the stack). Instead we place the loader in |loaders_to_destroy_| and | |
226 // schedule a task. | |
227 void ScheduleDestroy(InstantLoader* loader); | |
228 | |
229 // Destroys all loaders scheduled for destruction in |ScheduleForDestroy|. | |
230 void DestroyLoaders(); | |
231 | |
232 InstantControllerDelegate* delegate_; | |
233 | |
234 // True if |loader_| is ready to be displayed. | |
235 bool is_displayable_; | |
236 | |
237 // Set to true in Hide() and false in Update(). Used when we persist the | |
238 // |loader_|, but it isn't up to date. | |
239 bool is_out_of_date_; | |
240 | 168 |
241 scoped_ptr<InstantLoader> loader_; | 169 scoped_ptr<InstantLoader> loader_; |
242 | 170 |
243 // See description above setter. | 171 // See the enum description above. |
244 gfx::Rect omnibox_bounds_; | 172 const Mode mode_; |
245 | 173 |
246 // See description above CommitOnMouseUp. | 174 // The active tab at the time of the last |Update|. Used by |IsOutOfDate| to |
247 bool commit_on_mouse_up_; | 175 // know whether the user switched tabs. ***NEVER DEREFERENCE THIS POINTER.*** |
176 // It may be a dangling pointer to a freed object. Should only be used for | |
177 // pointer comparisons. | |
178 const void* last_tab_contents_; | |
248 | 179 |
249 // See description above getter. | 180 // The most recent full omnibox query text known to us. If this is empty, it |
250 content::PageTransition last_transition_type_; | 181 // could also mean that the omnibox text was a URL (or something else that |
251 | 182 // we shouldn't be processing). |
252 // The IDs of any search engines that don't support instant. We assume all | 183 string16 last_full_text_; |
253 // search engines support instant, but if we determine an engine doesn't | |
254 // support instant it is added to this list. The list is cleared out on every | |
255 // reset/commit. | |
256 std::set<TemplateURLID> blacklisted_ids_; | |
257 | |
258 // Used by ScheduleForDestroy; see it for details. | |
259 base::WeakPtrFactory<InstantController> weak_factory_; | |
260 | |
261 // List of InstantLoaders to destroy. See ScheduleForDestroy for details. | |
262 ScopedVector<InstantLoader> loaders_to_destroy_; | |
263 | |
264 // The URL of the most recent match passed to |Update|. | |
265 GURL last_url_; | |
266 | 184 |
267 // The most recent user_text passed to |Update|. | 185 // The most recent user_text passed to |Update|. |
268 string16 last_user_text_; | 186 string16 last_user_text_; |
269 | 187 |
270 // See the enum description above. | 188 // The most recent verbatim passed to |Update|. |
271 const Mode mode_; | 189 bool last_verbatim_; |
190 | |
191 // The most recent suggestion received from the page, minus any prefix that | |
192 // the user has typed. | |
193 string16 last_suggestion_; | |
194 | |
195 // The most recent autocomplete behavior for |last_suggestion_|. | |
196 InstantCompleteBehavior last_complete_behavior_; | |
197 | |
198 // True if the preview is currently being displayed. Guaranteed to be false | |
199 // if |IsOutOfDate| is true. | |
200 bool is_showing_; | |
201 | |
202 // True if we've received a response from the loader for the last |Update|, | |
203 // thus indicating that the page is ready to be shown. | |
204 bool loader_ready_; | |
sky
2012/07/19 17:55:19
This name is confusing. Its not whether the loader
Jered
2012/07/19 22:01:33
Done.
| |
205 | |
206 // Current omnibox bounds. | |
207 gfx::Rect omnibox_bounds_; | |
208 | |
209 // Last bounds passed to the page. | |
210 gfx::Rect last_omnibox_bounds_; | |
211 | |
212 // Timer used to update the bounds of the omnibox. | |
213 base::OneShotTimer<InstantController> update_bounds_timer_; | |
214 | |
215 // For each key K => value N, the map says that we found that the search | |
216 // engine identified by keyword K didn't support the Instant API in each of | |
217 // the last N times that we loaded it. If an ID isn't present in the map at | |
218 // all or has a value 0, it means that search engine supports the Instant API | |
219 // (or that we assume it does, since we haven't determined it doesn't). | |
220 std::map<string16, int> blacklisted_ids_; | |
sky
2012/07/19 17:55:19
This assumes that once it sees a keyword the Templ
Jered
2012/07/19 22:01:33
What is the proper id to use? Does this need to ma
sky
2012/07/19 23:43:49
The id from the TemplateURL never changes. That sa
Jered
2012/07/20 16:10:18
How about just using the instant url?
Jered
2012/07/20 21:21:26
Done.
| |
272 | 221 |
273 DISALLOW_COPY_AND_ASSIGN(InstantController); | 222 DISALLOW_COPY_AND_ASSIGN(InstantController); |
274 }; | 223 }; |
275 | 224 |
276 #endif // CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ | 225 #endif // CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ |
OLD | NEW |