| 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_LOADER_H_ | 5 #ifndef CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ |
| 6 #define CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ | 6 #define CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ |
| 7 | 7 |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/compiler_specific.h" |
| 11 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/string16.h" | 14 #include "base/string16.h" |
| 14 #include "base/timer.h" | |
| 15 #include "chrome/browser/instant/instant_commit_type.h" | 15 #include "chrome/browser/instant/instant_commit_type.h" |
| 16 #include "chrome/browser/search_engines/template_url_id.h" | |
| 17 #include "chrome/common/instant_types.h" | |
| 18 #include "content/public/browser/notification_observer.h" | 16 #include "content/public/browser/notification_observer.h" |
| 19 #include "content/public/browser/notification_registrar.h" | 17 #include "content/public/browser/notification_registrar.h" |
| 20 #include "content/public/common/page_transition_types.h" | |
| 21 #include "googleurl/src/gurl.h" | |
| 22 #include "ui/gfx/rect.h" | |
| 23 | 18 |
| 24 class InstantLoaderDelegate; | 19 class InstantLoaderDelegate; |
| 25 class InstantLoaderManagerTest; | |
| 26 class TabContents; | 20 class TabContents; |
| 27 class TemplateURL; | |
| 28 | 21 |
| 29 namespace content { | 22 namespace content { |
| 30 class SessionStorageNamespace; | 23 class NotificationDetails; |
| 24 class NotificationSource; |
| 31 } | 25 } |
| 32 | 26 |
| 33 // InstantLoader does the loading of a particular URL for InstantController. | 27 namespace gfx { |
| 34 // InstantLoader notifies its delegate, which is typically InstantController, of | 28 class Rect; |
| 35 // all interesting events. | 29 } |
| 36 // | 30 |
| 37 // InstantLoader is created with a TemplateURLID. If non-zero InstantLoader | 31 namespace history { |
| 38 // first determines if the site actually supports instant. If it doesn't, the | 32 class HistoryAddPageArgs; |
| 39 // delegate is notified by way of |InstantLoaderDoesntSupportInstant|. | 33 } |
| 40 // | 34 |
| 41 // If the TemplateURLID supplied to the constructor is zero, then the url is | 35 // InstantLoader is created with an "Instant URL". It loads the URL and tells |
| 42 // loaded as is. | 36 // its delegate (usually InstantController) of all interesting events. For |
| 37 // example, it determines if the page actually supports the Instant API |
| 38 // (http://dev.chromium.org/searchbox) and forwards messages (such as queries |
| 39 // and autocomplete suggestions) between the page and the delegate. |
| 43 class InstantLoader : public content::NotificationObserver { | 40 class InstantLoader : public content::NotificationObserver { |
| 44 public: | 41 public: |
| 45 // Header and value set on loads that originate from instant. | 42 // Creates a new empty WebContents. Use Init() to actually load |instant_url|. |
| 46 static const char* const kInstantHeader; | 43 // |tab_contents| is the page the preview will be shown on top of and |
| 47 static const char* const kInstantHeaderValue; | 44 // potentially replace. |instant_url| is typically the instant_url field of |
| 48 | 45 // the default search engine's TemplateURL, with the "{searchTerms}" parameter |
| 49 // |group| is an identifier suffixed to histograms to distinguish field trial | 46 // replaced with an empty string. |
| 50 // statistics from regular operation; can be a blank string. | |
| 51 InstantLoader(InstantLoaderDelegate* delegate, | 47 InstantLoader(InstantLoaderDelegate* delegate, |
| 52 TemplateURLID id, | 48 const std::string& instant_url, |
| 53 const std::string& group); | 49 const TabContents* tab_contents); |
| 54 virtual ~InstantLoader(); | 50 virtual ~InstantLoader(); |
| 55 | 51 |
| 56 // Invoked to load a URL. |tab_contents| is the TabContents the preview | 52 // Initializes |preview_contents_| and loads |instant_url_|. |
| 57 // is going to be shown on top of and potentially replace. Returns true if the | 53 void Init(); |
| 58 // arguments differ from the last call to |Update|. | |
| 59 bool Update(TabContents* tab_contents, | |
| 60 const TemplateURL* template_url, | |
| 61 const GURL& url, | |
| 62 content::PageTransition transition_type, | |
| 63 const string16& user_text, | |
| 64 bool verbatim, | |
| 65 string16* suggested_text); | |
| 66 | 54 |
| 67 // Sets the bounds of the omnibox (in screen coordinates). The bounds are | 55 // Tells the preview page that the user typed |user_text| into the omnibox. |
| 68 // remembered until the preview is committed or destroyed. This is only used | 56 // If |verbatim| is false, the page predicts the query the user means to type |
| 69 // when showing results for a search provider that supports instant. | 57 // and fetches results for the prediction. If |verbatim| is true, |user_text| |
| 58 // is taken as the exact query (no prediction is made). |
| 59 void Update(const string16& user_text, bool verbatim); |
| 60 |
| 61 // Tells the preview page of the bounds of the omnibox dropdown (in screen |
| 62 // coordinates). This is used by the page to offset the results to avoid them |
| 63 // being covered by the omnibox dropdown. |
| 70 void SetOmniboxBounds(const gfx::Rect& bounds); | 64 void SetOmniboxBounds(const gfx::Rect& bounds); |
| 71 | 65 |
| 72 // Returns true if the mouse or a touch-pointer is down as the result of | 66 // Releases the preview TabContents passing ownership to the caller. This |
| 73 // activating the preview content. | 67 // should be called when the preview is committed. Notifies the page but not |
| 74 bool IsPointerDownFromActivate(); | 68 // the delegate. |text| is the final omnibox text being committed. NOTE: The |
| 69 // caller should destroy this loader object right after this method, since |
| 70 // none of the other methods will work once the preview has been released. |
| 71 TabContents* ReleasePreviewContents(InstantCommitType type, |
| 72 const string16& text) WARN_UNUSED_RESULT; |
| 75 | 73 |
| 76 // Releases the preview TabContents passing ownership to the caller. | 74 // The preview TabContents. The loader retains ownership. This will be |
| 77 // This is intended to be called when the preview TabContents is | 75 // non-NULL until ReleasePreviewContents() is called. |
| 78 // committed. This does not notify the delegate. |tab_contents| is the | 76 TabContents* preview_contents() const { return preview_contents_.get(); } |
| 79 // underlying tab onto which the preview will be committed. It can be NULL | |
| 80 // when the underlying tab is irrelevant, for example when |type| is | |
| 81 // INSTANT_COMMIT_DESTROY. | |
| 82 TabContents* ReleasePreviewContents(InstantCommitType type, | |
| 83 TabContents* tab_contents); | |
| 84 | 77 |
| 85 // Calls through to method of same name on delegate. | 78 // Returns true if the preview page is known to support the Instant API. This |
| 86 bool ShouldCommitInstantOnPointerRelease(); | 79 // starts out false, and becomes true whenever we get any message from the |
| 87 void CommitInstantLoader(); | 80 // page. Once true, it never becomes false (the page isn't expected to drop |
| 81 // Instant API support suddenly). |
| 82 bool supports_instant() const { return supports_instant_; } |
| 88 | 83 |
| 89 // Preload |template_url|'s instant URL, if the loader doesn't already have | 84 // Returns the URL that we're loading. |
| 90 // a |preview_contents()| for it. | 85 const std::string& instant_url() const { return instant_url_; } |
| 91 void MaybeLoadInstantURL(TabContents* tab_contents, | |
| 92 const TemplateURL* template_url); | |
| 93 | 86 |
| 94 // Returns true if the preview NavigationController's WebContents has a | 87 // Returns info about the last navigation by the Instant page. If the page |
| 95 // pending NavigationEntry. | 88 // hasn't navigated since the last Update(), this contains NULL. |
| 96 bool IsNavigationPending() const; | 89 scoped_refptr<history::HistoryAddPageArgs> last_navigation() const { |
| 90 return last_navigation_; |
| 91 } |
| 92 |
| 93 // Returns true if the mouse or a touch pointer is down due to activating the |
| 94 // preview content. |
| 95 bool IsPointerDownFromActivate() const; |
| 97 | 96 |
| 98 // content::NotificationObserver: | 97 // content::NotificationObserver: |
| 99 virtual void Observe(int type, | 98 virtual void Observe(int type, |
| 100 const content::NotificationSource& source, | 99 const content::NotificationSource& source, |
| 101 const content::NotificationDetails& details) OVERRIDE; | 100 const content::NotificationDetails& details) OVERRIDE; |
| 102 | 101 |
| 103 // The preview TabContents; may be null. | |
| 104 TabContents* preview_contents() const { | |
| 105 return preview_contents_.get(); | |
| 106 } | |
| 107 | |
| 108 // Returns true if the preview TabContents is ready to be shown. A | |
| 109 // non-instant loader is ready once the renderer paints, otherwise it isn't | |
| 110 // ready until we get a response back from the page. | |
| 111 bool ready() const { return ready_; } | |
| 112 | |
| 113 // Returns true if the current load returned a 200. | |
| 114 bool http_status_ok() const { return http_status_ok_; } | |
| 115 | |
| 116 // Returns true if the url needs to be reloaded. This is set to true for | |
| 117 // downloads. | |
| 118 bool needs_reload() const { return needs_reload_; } | |
| 119 | |
| 120 const GURL& url() const { return url_; } | |
| 121 | |
| 122 bool verbatim() const { return verbatim_; } | |
| 123 | |
| 124 // Are we showing instant results? | |
| 125 bool is_showing_instant() const { return template_url_id_ != 0; } | |
| 126 | |
| 127 // If we're showing instant this returns non-zero. | |
| 128 TemplateURLID template_url_id() const { return template_url_id_; } | |
| 129 | |
| 130 // See description above field. | |
| 131 const string16& user_text() const { return user_text_; } | |
| 132 | |
| 133 // Are we waiting for the preview page to finish loading and to determine if | |
| 134 // it supports instant? | |
| 135 bool is_determining_if_page_supports_instant() const { | |
| 136 return frame_load_observer_.get() != NULL; | |
| 137 } | |
| 138 | |
| 139 private: | 102 private: |
| 140 friend class InstantLoaderManagerTest; | |
| 141 friend class InstantTest; | |
| 142 class FrameLoadObserver; | |
| 143 class PaintObserverImpl; | |
| 144 class WebContentsDelegateImpl; | 103 class WebContentsDelegateImpl; |
| 145 | 104 |
| 146 // Invoked when the page wants to update the suggested text. If |user_text_| | 105 void SetupPreviewContents(); |
| 147 // starts with |suggested_text|, then the delegate is notified of the change, | 106 void CleanupPreviewContents(); |
| 148 // which results in updating the omnibox. | 107 void ReplacePreviewContents(TabContents* old_tc, TabContents* new_tc); |
| 149 void SetCompleteSuggestedText(const string16& suggested_text, | |
| 150 InstantCompleteBehavior behavior); | |
| 151 | 108 |
| 152 // Invoked when the page paints. | 109 InstantLoaderDelegate* const loader_delegate_; |
| 153 void PreviewPainted(); | |
| 154 | 110 |
| 155 // Invoked when the http status code changes. This may notify the delegate. | 111 // See comments on the getter above. |
| 156 void SetHTTPStatusOK(bool is_ok); | 112 scoped_ptr<TabContents> preview_contents_; |
| 157 | |
| 158 // Invoked to show the preview. This is invoked in two possible cases: when | |
| 159 // the renderer paints, or when an auth dialog is shown. This notifies the | |
| 160 // delegate the preview is ready to be shown. | |
| 161 void ShowPreview(); | |
| 162 | |
| 163 // Invoked once the page has finished loading and the script has been sent. | |
| 164 void PageFinishedLoading(); | |
| 165 | |
| 166 // Returns the bounds of the omnibox in terms of the preview tab contents. | |
| 167 gfx::Rect GetOmniboxBoundsInTermsOfPreview(); | |
| 168 | |
| 169 // Invoked if it the page doesn't really support instant when we thought it | |
| 170 // did. If |needs_reload| is true, the text changed since the first load and | |
| 171 // the page needs to be reloaded. | |
| 172 void PageDoesntSupportInstant(bool needs_reload); | |
| 173 | |
| 174 // Invokes |SetBoundsToPage(false)|. This is called from the timer. | |
| 175 void ProcessBoundsChange(); | |
| 176 | |
| 177 // Notifes the page of the omnibox bounds. If |force_if_loading| is true the | |
| 178 // bounds are sent down even if we're waiting on the load, otherwise if we're | |
| 179 // waiting on the load and |force_if_loading| is false this does nothing. | |
| 180 void SendBoundsToPage(bool force_if_loading); | |
| 181 | |
| 182 // Called when the TabContentsDelegate wants to swap a new TabContents | |
| 183 // into our |preview_contents_|. | |
| 184 void ReplacePreviewContents(TabContents* old_tc, | |
| 185 TabContents* new_tc); | |
| 186 | |
| 187 // Called to set up the |preview_contents_| based on |tab_contents| when it is | |
| 188 // created or replaced. | |
| 189 void SetupPreviewContents(TabContents* tab_contents); | |
| 190 | |
| 191 // Creates and sets the preview TabContents. | |
| 192 void CreatePreviewContents(TabContents* tab_contents); | |
| 193 | |
| 194 // Creates and loads the |template_url|'s instant URL. | |
| 195 void LoadInstantURL(const TemplateURL* template_url, | |
| 196 content::PageTransition transition_type, | |
| 197 const string16& user_text, | |
| 198 bool verbatim, | |
| 199 bool override_user_agent); | |
| 200 | |
| 201 InstantLoaderDelegate* delegate_; | |
| 202 | |
| 203 // If we're showing instant results this is the ID of the TemplateURL driving | |
| 204 // the results. A value of 0 means there is no TemplateURL. | |
| 205 const TemplateURLID template_url_id_; | |
| 206 | |
| 207 // The url we're displaying. | |
| 208 GURL url_; | |
| 209 | 113 |
| 210 // Delegate of the preview WebContents. Used to detect when the user does some | 114 // Delegate of the preview WebContents. Used to detect when the user does some |
| 211 // gesture on the WebContents and the preview needs to be activated. | 115 // gesture on the WebContents and the preview needs to be activated. |
| 212 scoped_ptr<WebContentsDelegateImpl> preview_tab_contents_delegate_; | 116 scoped_ptr<WebContentsDelegateImpl> preview_delegate_; |
| 213 | 117 |
| 214 // The preview TabContents; may be null. | 118 // See comments on the getter above. |
| 215 scoped_ptr<TabContents> preview_contents_; | 119 bool supports_instant_; |
| 216 | 120 |
| 217 // Is the preview_contents ready to be shown? | 121 // See comments on the getter above. |
| 218 bool ready_; | 122 const std::string instant_url_; |
| 219 | |
| 220 // Was the last status code a 200? | |
| 221 bool http_status_ok_; | |
| 222 | |
| 223 // The text the user typed in the omnibox, stripped of the leading ?, if any. | |
| 224 string16 user_text_; | |
| 225 | |
| 226 // The latest suggestion from the page. | |
| 227 string16 complete_suggested_text_; | |
| 228 | |
| 229 // The latest suggestion (suggested text less the user text). | |
| 230 string16 last_suggestion_; | |
| 231 | |
| 232 // See description above setter. | |
| 233 gfx::Rect omnibox_bounds_; | |
| 234 | |
| 235 // Last bounds passed to the page. | |
| 236 gfx::Rect last_omnibox_bounds_; | |
| 237 | |
| 238 scoped_ptr<FrameLoadObserver> frame_load_observer_; | |
| 239 | |
| 240 // Transition type of the match last passed to Update. | |
| 241 content::PageTransition last_transition_type_; | |
| 242 | |
| 243 // Timer used to update the bounds of the omnibox. | |
| 244 base::OneShotTimer<InstantLoader> update_bounds_timer_; | |
| 245 | 123 |
| 246 // Used to get notifications about renderers coming and going. | 124 // Used to get notifications about renderers coming and going. |
| 247 content::NotificationRegistrar registrar_; | 125 content::NotificationRegistrar registrar_; |
| 248 | 126 |
| 249 // Last value of verbatim passed to |Update|. | 127 // See comments on the getter above. |
| 250 bool verbatim_; | 128 scoped_refptr<history::HistoryAddPageArgs> last_navigation_; |
| 251 | |
| 252 // True if the page needs to be reloaded. | |
| 253 bool needs_reload_; | |
| 254 | |
| 255 // See description above constructor. | |
| 256 std::string group_; | |
| 257 | |
| 258 // The session storage namespace identifier of the original tab contents that | |
| 259 // the preview_contents_ was based upon. | |
| 260 scoped_refptr<content::SessionStorageNamespace> session_storage_namespace_; | |
| 261 | 129 |
| 262 DISALLOW_COPY_AND_ASSIGN(InstantLoader); | 130 DISALLOW_COPY_AND_ASSIGN(InstantLoader); |
| 263 }; | 131 }; |
| 264 | 132 |
| 265 #endif // CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ | 133 #endif // CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ |
| OLD | NEW |