OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "chrome/browser/instant/instant_loader.h" | 5 #include "chrome/browser/instant/instant_loader.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 15 matching lines...) Expand all Loading... | |
26 #include "chrome/browser/tab_contents/navigation_controller.h" | 26 #include "chrome/browser/tab_contents/navigation_controller.h" |
27 #include "chrome/browser/tab_contents/navigation_entry.h" | 27 #include "chrome/browser/tab_contents/navigation_entry.h" |
28 #include "chrome/browser/tab_contents/tab_contents.h" | 28 #include "chrome/browser/tab_contents/tab_contents.h" |
29 #include "chrome/browser/tab_contents/tab_contents_delegate.h" | 29 #include "chrome/browser/tab_contents/tab_contents_delegate.h" |
30 #include "chrome/browser/tab_contents/tab_contents_view.h" | 30 #include "chrome/browser/tab_contents/tab_contents_view.h" |
31 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 31 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
32 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
33 #include "chrome/common/notification_details.h" | 33 #include "chrome/common/notification_details.h" |
34 #include "chrome/common/notification_observer.h" | 34 #include "chrome/common/notification_observer.h" |
35 #include "chrome/common/notification_registrar.h" | 35 #include "chrome/common/notification_registrar.h" |
36 #include "chrome/common/notification_service.h" | |
36 #include "chrome/common/notification_source.h" | 37 #include "chrome/common/notification_source.h" |
37 #include "chrome/common/notification_type.h" | 38 #include "chrome/common/notification_type.h" |
38 #include "chrome/common/page_transition_types.h" | 39 #include "chrome/common/page_transition_types.h" |
39 #include "chrome/common/render_messages.h" | 40 #include "chrome/common/render_messages.h" |
40 #include "chrome/common/renderer_preferences.h" | 41 #include "chrome/common/renderer_preferences.h" |
41 #include "gfx/codec/png_codec.h" | 42 #include "gfx/codec/png_codec.h" |
42 #include "ipc/ipc_message.h" | 43 #include "ipc/ipc_message.h" |
43 #include "net/http/http_util.h" | 44 #include "net/http/http_util.h" |
44 | 45 |
45 namespace { | 46 namespace { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 | 120 |
120 // unique_id of the NavigationEntry we're waiting on. | 121 // unique_id of the NavigationEntry we're waiting on. |
121 const int unique_id_; | 122 const int unique_id_; |
122 | 123 |
123 // Registers and unregisters us for notifications. | 124 // Registers and unregisters us for notifications. |
124 NotificationRegistrar registrar_; | 125 NotificationRegistrar registrar_; |
125 | 126 |
126 DISALLOW_COPY_AND_ASSIGN(FrameLoadObserver); | 127 DISALLOW_COPY_AND_ASSIGN(FrameLoadObserver); |
127 }; | 128 }; |
128 | 129 |
129 // PaintObserver implementation. When the RenderWidgetHost paints itself this | 130 class InstantLoader::TabContentsDelegateImpl |
130 // notifies the TabContentsDelegateImpl which ultimately notifies InstantLoader | 131 : public TabContentsDelegate, |
131 // and shows the preview. | 132 public NotificationObserver { |
132 // The ownership of this class is tricky. It's created and | |
133 // tracked by TabContentsDelegateImpl, but owned by RenderWidgetHost. When | |
134 // deleted this notifies the TabContentsDelegateImpl so that it can clean | |
135 // up appropriately. | |
136 class InstantLoader::PaintObserverImpl | |
137 : public RenderWidgetHost::PaintObserver { | |
138 public: | |
139 PaintObserverImpl(TabContentsDelegateImpl* delegate, | |
140 RenderWidgetHost* rwh) | |
141 : delegate_(delegate), | |
142 rwh_(rwh) { | |
143 rwh_->set_paint_observer(this); | |
144 } | |
145 | |
146 ~PaintObserverImpl(); | |
147 | |
148 // Deletes this object by resetting the PaintObserver on the RenderWidgetHost. | |
149 void Destroy() { | |
150 rwh_->set_paint_observer(NULL); | |
151 } | |
152 | |
153 virtual void RenderWidgetHostWillPaint(RenderWidgetHost* rwh) {} | |
154 | |
155 virtual void RenderWidgetHostDidPaint(RenderWidgetHost* rwh); | |
156 | |
157 private: | |
158 TabContentsDelegateImpl* delegate_; | |
159 RenderWidgetHost* rwh_; | |
160 | |
161 DISALLOW_COPY_AND_ASSIGN(PaintObserverImpl); | |
162 }; | |
163 | |
164 class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { | |
165 public: | 133 public: |
166 explicit TabContentsDelegateImpl(InstantLoader* loader) | 134 explicit TabContentsDelegateImpl(InstantLoader* loader) |
167 : loader_(loader), | 135 : loader_(loader), |
168 paint_observer_(NULL), | 136 registered_render_widget_host_(NULL), |
169 waiting_for_new_page_(true), | 137 waiting_for_new_page_(true), |
170 is_mouse_down_from_activate_(false), | 138 is_mouse_down_from_activate_(false), |
171 user_typed_before_load_(false) { | 139 user_typed_before_load_(false) { |
172 } | 140 } |
173 | 141 |
174 // Invoked prior to loading a new URL. | 142 // Invoked prior to loading a new URL. |
175 void PrepareForNewLoad() { | 143 void PrepareForNewLoad() { |
176 user_typed_before_load_ = false; | 144 user_typed_before_load_ = false; |
177 waiting_for_new_page_ = true; | 145 waiting_for_new_page_ = true; |
178 add_page_vector_.clear(); | 146 add_page_vector_.clear(); |
179 DestroyPaintObserver(); | 147 UnregisterForPaintNotifications(); |
180 } | 148 } |
181 | 149 |
182 // Invoked when removed as the delegate. Gives a chance to do any necessary | 150 // Invoked when removed as the delegate. Gives a chance to do any necessary |
183 // cleanup. | 151 // cleanup. |
184 void Reset() { | 152 void Reset() { |
185 is_mouse_down_from_activate_ = false; | 153 is_mouse_down_from_activate_ = false; |
186 DestroyPaintObserver(); | 154 UnregisterForPaintNotifications(); |
187 } | 155 } |
188 | 156 |
189 // Invoked when the preview paints. Invokes PreviewPainted on the loader. | 157 // Invoked when the preview paints. Invokes PreviewPainted on the loader. |
190 void PreviewPainted() { | 158 void PreviewPainted() { |
191 loader_->PreviewPainted(); | 159 loader_->PreviewPainted(); |
192 } | 160 } |
193 | 161 |
194 // Invoked when the PaintObserverImpl is deleted. | |
195 void PaintObserverDestroyed(PaintObserverImpl* observer) { | |
196 if (observer == paint_observer_) | |
197 paint_observer_ = NULL; | |
198 } | |
199 | |
200 bool is_mouse_down_from_activate() const { | 162 bool is_mouse_down_from_activate() const { |
201 return is_mouse_down_from_activate_; | 163 return is_mouse_down_from_activate_; |
202 } | 164 } |
203 | 165 |
204 void set_user_typed_before_load() { user_typed_before_load_ = true; } | 166 void set_user_typed_before_load() { user_typed_before_load_ = true; } |
205 | 167 |
206 // Sets the last URL that will be added to history when CommitHistory is | 168 // Sets the last URL that will be added to history when CommitHistory is |
207 // invoked and removes all but the first navigation. | 169 // invoked and removes all but the first navigation. |
208 void SetLastHistoryURLAndPrune(const GURL& url) { | 170 void SetLastHistoryURLAndPrune(const GURL& url) { |
209 if (add_page_vector_.empty()) | 171 if (add_page_vector_.empty()) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 // going to be added to history. We need to also set the favicon for the | 217 // going to be added to history. We need to also set the favicon for the |
256 // url we're adding to history (see comment in ReleasePreviewContents | 218 // url we're adding to history (see comment in ReleasePreviewContents |
257 // for details). | 219 // for details). |
258 favicon_service->SetFavicon(add_page_vector_.back()->url, | 220 favicon_service->SetFavicon(add_page_vector_.back()->url, |
259 active_entry->favicon().url(), | 221 active_entry->favicon().url(), |
260 image_data); | 222 image_data); |
261 } | 223 } |
262 } | 224 } |
263 } | 225 } |
264 | 226 |
227 void RegisterForPaintNotifications(RenderWidgetHost* render_widget_host) { | |
sky
2011/01/07 21:04:16
Move the register/unregister methods to the privat
| |
228 DCHECK(registered_render_widget_host_ == NULL); | |
229 registered_render_widget_host_ = render_widget_host; | |
230 Source<RenderWidgetHost> source = | |
231 Source<RenderWidgetHost>(registered_render_widget_host_); | |
232 registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DID_PAINT, | |
233 source); | |
234 registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DESTROYED, | |
235 source); | |
236 } | |
237 | |
238 void UnregisterForPaintNotifications() { | |
239 if (registered_render_widget_host_) { | |
240 Source<RenderWidgetHost> source = | |
241 Source<RenderWidgetHost>(registered_render_widget_host_); | |
242 registrar_.Remove(this, NotificationType::RENDER_WIDGET_HOST_DID_PAINT, | |
243 source); | |
244 registrar_.Remove(this, NotificationType::RENDER_WIDGET_HOST_DESTROYED, | |
245 source); | |
246 registered_render_widget_host_ = NULL; | |
247 } | |
248 } | |
249 | |
250 void Observe(NotificationType type, | |
sky
2011/01/07 21:04:16
virtual
| |
251 const NotificationSource& source, | |
252 const NotificationDetails& details) { | |
253 if (type == NotificationType::RENDER_WIDGET_HOST_DID_PAINT) { | |
254 UnregisterForPaintNotifications(); | |
255 PreviewPainted(); | |
256 } else if (type == NotificationType::RENDER_WIDGET_HOST_DESTROYED) { | |
257 UnregisterForPaintNotifications(); | |
258 } else { | |
259 NOTREACHED() << "Got a notification we didn't register for."; | |
260 } | |
261 } | |
262 | |
265 virtual void OpenURLFromTab(TabContents* source, | 263 virtual void OpenURLFromTab(TabContents* source, |
266 const GURL& url, const GURL& referrer, | 264 const GURL& url, const GURL& referrer, |
267 WindowOpenDisposition disposition, | 265 WindowOpenDisposition disposition, |
268 PageTransition::Type transition) {} | 266 PageTransition::Type transition) {} |
269 virtual void NavigationStateChanged(const TabContents* source, | 267 virtual void NavigationStateChanged(const TabContents* source, |
270 unsigned changed_flags) { | 268 unsigned changed_flags) { |
271 if (!loader_->ready() && !paint_observer_ && | 269 if (!loader_->ready() && !registered_render_widget_host_ && |
272 source->controller().entry_count()) { | 270 source->controller().entry_count()) { |
273 // The load has been committed. Install an observer that waits for the | 271 // The load has been committed. Install an observer that waits for the |
274 // first paint then makes the preview active. We wait for the load to be | 272 // first paint then makes the preview active. We wait for the load to be |
275 // committed before waiting on paint as there is always an initial paint | 273 // committed before waiting on paint as there is always an initial paint |
276 // when a new renderer is created from the resize so that if we showed the | 274 // when a new renderer is created from the resize so that if we showed the |
277 // preview after the first paint we would end up with a white rect. | 275 // preview after the first paint we would end up with a white rect. |
278 paint_observer_ = new PaintObserverImpl(this, | 276 RegisterForPaintNotifications( |
279 source->GetRenderWidgetHostView()->GetRenderWidgetHost()); | 277 source->GetRenderWidgetHostView()->GetRenderWidgetHost()); |
280 } | 278 } |
281 } | 279 } |
282 virtual std::string GetNavigationHeaders(const GURL& url) { | 280 virtual std::string GetNavigationHeaders(const GURL& url) { |
283 std::string header; | 281 std::string header; |
284 net::HttpUtil::AppendHeaderIfMissing(kPreviewHeader, kPreviewHeaderValue, | 282 net::HttpUtil::AppendHeaderIfMissing(kPreviewHeader, kPreviewHeaderValue, |
285 &header); | 283 &header); |
286 return header; | 284 return header; |
287 } | 285 } |
288 virtual void AddNewContents(TabContents* source, | 286 virtual void AddNewContents(TabContents* source, |
(...skipping 10 matching lines...) Expand all Loading... | |
299 virtual bool ShouldFocusConstrainedWindow() { | 297 virtual bool ShouldFocusConstrainedWindow() { |
300 // Return false so that constrained windows are not initially focused. If | 298 // Return false so that constrained windows are not initially focused. If |
301 // we did otherwise the preview would prematurely get committed when focus | 299 // we did otherwise the preview would prematurely get committed when focus |
302 // goes to the constrained window. | 300 // goes to the constrained window. |
303 return false; | 301 return false; |
304 } | 302 } |
305 virtual void WillShowConstrainedWindow(TabContents* source) { | 303 virtual void WillShowConstrainedWindow(TabContents* source) { |
306 if (!loader_->ready()) { | 304 if (!loader_->ready()) { |
307 // A constrained window shown for an auth may not paint. Show the preview | 305 // A constrained window shown for an auth may not paint. Show the preview |
308 // contents. | 306 // contents. |
309 DestroyPaintObserver(); | 307 UnregisterForPaintNotifications(); |
310 loader_->ShowPreview(); | 308 loader_->ShowPreview(); |
311 } | 309 } |
312 } | 310 } |
313 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {} | 311 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {} |
314 virtual void URLStarredChanged(TabContents* source, bool starred) {} | 312 virtual void URLStarredChanged(TabContents* source, bool starred) {} |
315 virtual void UpdateTargetURL(TabContents* source, const GURL& url) {} | 313 virtual void UpdateTargetURL(TabContents* source, const GURL& url) {} |
316 virtual bool ShouldSuppressDialogs() { | 314 virtual bool ShouldSuppressDialogs() { |
317 // Any message shown during instant cancels instant, so we suppress them. | 315 // Any message shown during instant cancels instant, so we suppress them. |
318 return true; | 316 return true; |
319 } | 317 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 typedef std::vector<scoped_refptr<history::HistoryAddPageArgs> > | 375 typedef std::vector<scoped_refptr<history::HistoryAddPageArgs> > |
378 AddPageVector; | 376 AddPageVector; |
379 | 377 |
380 void CommitFromMouseReleaseIfNecessary() { | 378 void CommitFromMouseReleaseIfNecessary() { |
381 bool was_down = is_mouse_down_from_activate_; | 379 bool was_down = is_mouse_down_from_activate_; |
382 is_mouse_down_from_activate_ = false; | 380 is_mouse_down_from_activate_ = false; |
383 if (was_down && loader_->ShouldCommitInstantOnMouseUp()) | 381 if (was_down && loader_->ShouldCommitInstantOnMouseUp()) |
384 loader_->CommitInstantLoader(); | 382 loader_->CommitInstantLoader(); |
385 } | 383 } |
386 | 384 |
387 // If the PaintObserver is non-null Destroy is invoked on it. | |
388 void DestroyPaintObserver() { | |
389 if (paint_observer_) { | |
390 paint_observer_->Destroy(); | |
391 // Destroy should result in invoking PaintObserverDestroyed and NULLing | |
392 // out paint_observer_. | |
393 DCHECK(!paint_observer_); | |
394 } | |
395 } | |
396 | |
397 InstantLoader* loader_; | 385 InstantLoader* loader_; |
398 | 386 |
399 // Used to listen for paint so that we know when to show the preview. See | 387 NotificationRegistrar registrar_; |
400 // comment in NavigationStateChanged for details on this. | 388 RenderWidgetHost* registered_render_widget_host_; |
sky
2011/01/07 21:04:16
Comment?
| |
401 // Ownership of this is tricky, see comment above PaintObserverImpl class. | |
402 PaintObserverImpl* paint_observer_; | |
403 | 389 |
404 // Used to cache data that needs to be added to history. Normally entries are | 390 // Used to cache data that needs to be added to history. Normally entries are |
405 // added to history as the user types, but for instant we only want to add the | 391 // added to history as the user types, but for instant we only want to add the |
406 // items to history if the user commits instant. So, we cache them here and if | 392 // items to history if the user commits instant. So, we cache them here and if |
407 // committed then add the items to history. | 393 // committed then add the items to history. |
408 AddPageVector add_page_vector_; | 394 AddPageVector add_page_vector_; |
409 | 395 |
410 // Are we we waiting for a NavigationType of NEW_PAGE? If we're waiting for | 396 // Are we we waiting for a NavigationType of NEW_PAGE? If we're waiting for |
411 // NEW_PAGE navigation we don't add history items to add_page_vector_. | 397 // NEW_PAGE navigation we don't add history items to add_page_vector_. |
412 bool waiting_for_new_page_; | 398 bool waiting_for_new_page_; |
413 | 399 |
414 // True if the mouse is down from an activate. | 400 // True if the mouse is down from an activate. |
415 bool is_mouse_down_from_activate_; | 401 bool is_mouse_down_from_activate_; |
416 | 402 |
417 // True if the user typed in the search box before the page loaded. | 403 // True if the user typed in the search box before the page loaded. |
418 bool user_typed_before_load_; | 404 bool user_typed_before_load_; |
419 | 405 |
420 DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl); | 406 DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl); |
421 }; | 407 }; |
422 | 408 |
423 InstantLoader::PaintObserverImpl::~PaintObserverImpl() { | |
424 delegate_->PaintObserverDestroyed(this); | |
425 } | |
426 | |
427 void InstantLoader::PaintObserverImpl::RenderWidgetHostDidPaint( | |
428 RenderWidgetHost* rwh) { | |
429 TabContentsDelegateImpl* delegate = delegate_; | |
430 // Set the paint observer to NULL, which deletes us. Showing the preview may | |
431 // reset the paint observer, and delete us. By resetting the delegate first we | |
432 // know we've been deleted and can deal correctly. | |
433 rwh->set_paint_observer(NULL); | |
434 // WARNING: we've been deleted. | |
435 if (delegate) | |
436 delegate->PreviewPainted(); | |
437 } | |
438 | |
439 InstantLoader::InstantLoader(InstantLoaderDelegate* delegate, TemplateURLID id) | 409 InstantLoader::InstantLoader(InstantLoaderDelegate* delegate, TemplateURLID id) |
440 : delegate_(delegate), | 410 : delegate_(delegate), |
441 template_url_id_(id), | 411 template_url_id_(id), |
442 ready_(false), | 412 ready_(false), |
443 last_transition_type_(PageTransition::LINK) { | 413 last_transition_type_(PageTransition::LINK) { |
444 preview_tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); | 414 preview_tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); |
445 } | 415 } |
446 | 416 |
447 InstantLoader::~InstantLoader() { | 417 InstantLoader::~InstantLoader() { |
448 registrar_.RemoveAll(); | 418 registrar_.RemoveAll(); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
604 if (preview_contents_.get()) { | 574 if (preview_contents_.get()) { |
605 if (type != INSTANT_COMMIT_DESTROY) { | 575 if (type != INSTANT_COMMIT_DESTROY) { |
606 if (template_url_id_) { | 576 if (template_url_id_) { |
607 // The URL used during instant is mostly gibberish, and not something | 577 // The URL used during instant is mostly gibberish, and not something |
608 // we'll parse and match as a past search. Set it to something we can | 578 // we'll parse and match as a past search. Set it to something we can |
609 // parse. | 579 // parse. |
610 preview_tab_contents_delegate_->SetLastHistoryURLAndPrune(url); | 580 preview_tab_contents_delegate_->SetLastHistoryURLAndPrune(url); |
611 } | 581 } |
612 preview_tab_contents_delegate_->CommitHistory(template_url_id_ != 0); | 582 preview_tab_contents_delegate_->CommitHistory(template_url_id_ != 0); |
613 } | 583 } |
614 // Destroy the paint observer. | |
615 // RenderWidgetHostView may be null during shutdown. | |
616 if (preview_contents_->tab_contents()->GetRenderWidgetHostView()) { | 584 if (preview_contents_->tab_contents()->GetRenderWidgetHostView()) { |
617 preview_contents_->tab_contents()->GetRenderWidgetHostView()-> | |
618 GetRenderWidgetHost()->set_paint_observer(NULL); | |
619 #if defined(OS_MACOSX) | 585 #if defined(OS_MACOSX) |
620 preview_contents_->tab_contents()->GetRenderWidgetHostView()-> | 586 preview_contents_->tab_contents()->GetRenderWidgetHostView()-> |
621 SetTakesFocusOnlyOnMouseDown(false); | 587 SetTakesFocusOnlyOnMouseDown(false); |
622 registrar_.Remove( | 588 registrar_.Remove( |
623 this, | 589 this, |
624 NotificationType::RENDER_VIEW_HOST_CHANGED, | 590 NotificationType::RENDER_VIEW_HOST_CHANGED, |
625 Source<NavigationController>(&preview_contents_->controller())); | 591 Source<NavigationController>(&preview_contents_->controller())); |
626 #endif | 592 #endif |
627 } | 593 } |
628 preview_contents_->set_delegate(NULL); | 594 preview_contents_->set_delegate(NULL); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
797 Source<NavigationController>(&preview_contents_->controller())); | 763 Source<NavigationController>(&preview_contents_->controller())); |
798 #endif | 764 #endif |
799 | 765 |
800 registrar_.Add( | 766 registrar_.Add( |
801 this, | 767 this, |
802 NotificationType::NAV_ENTRY_COMMITTED, | 768 NotificationType::NAV_ENTRY_COMMITTED, |
803 Source<NavigationController>(&preview_contents_->controller())); | 769 Source<NavigationController>(&preview_contents_->controller())); |
804 | 770 |
805 preview_contents_->tab_contents()->ShowContents(); | 771 preview_contents_->tab_contents()->ShowContents(); |
806 } | 772 } |
OLD | NEW |