Chromium Code Reviews| Index: chrome/browser/instant/instant_loader.cc |
| diff --git a/chrome/browser/instant/instant_loader.cc b/chrome/browser/instant/instant_loader.cc |
| index 3d8189d826bad55ff727b0d91f765eaeae2834b8..8d4edc1b5c8b0286b2430137d9760a09c72a881d 100644 |
| --- a/chrome/browser/instant/instant_loader.cc |
| +++ b/chrome/browser/instant/instant_loader.cc |
| @@ -33,6 +33,7 @@ |
| #include "chrome/common/notification_details.h" |
| #include "chrome/common/notification_observer.h" |
| #include "chrome/common/notification_registrar.h" |
| +#include "chrome/common/notification_service.h" |
| #include "chrome/common/notification_source.h" |
| #include "chrome/common/notification_type.h" |
| #include "chrome/common/page_transition_types.h" |
| @@ -126,46 +127,13 @@ class InstantLoader::FrameLoadObserver : public NotificationObserver { |
| DISALLOW_COPY_AND_ASSIGN(FrameLoadObserver); |
| }; |
| -// PaintObserver implementation. When the RenderWidgetHost paints itself this |
| -// notifies the TabContentsDelegateImpl which ultimately notifies InstantLoader |
| -// and shows the preview. |
| -// The ownership of this class is tricky. It's created and |
| -// tracked by TabContentsDelegateImpl, but owned by RenderWidgetHost. When |
| -// deleted this notifies the TabContentsDelegateImpl so that it can clean |
| -// up appropriately. |
| -class InstantLoader::PaintObserverImpl |
| - : public RenderWidgetHost::PaintObserver { |
| - public: |
| - PaintObserverImpl(TabContentsDelegateImpl* delegate, |
| - RenderWidgetHost* rwh) |
| - : delegate_(delegate), |
| - rwh_(rwh) { |
| - rwh_->set_paint_observer(this); |
| - } |
| - |
| - ~PaintObserverImpl(); |
| - |
| - // Deletes this object by resetting the PaintObserver on the RenderWidgetHost. |
| - void Destroy() { |
| - rwh_->set_paint_observer(NULL); |
| - } |
| - |
| - virtual void RenderWidgetHostWillPaint(RenderWidgetHost* rwh) {} |
| - |
| - virtual void RenderWidgetHostDidPaint(RenderWidgetHost* rwh); |
| - |
| - private: |
| - TabContentsDelegateImpl* delegate_; |
| - RenderWidgetHost* rwh_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(PaintObserverImpl); |
| -}; |
| - |
| -class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { |
| +class InstantLoader::TabContentsDelegateImpl |
| + : public TabContentsDelegate, |
| + public NotificationObserver { |
| public: |
| explicit TabContentsDelegateImpl(InstantLoader* loader) |
| : loader_(loader), |
| - paint_observer_(NULL), |
| + registered_render_widget_host_(NULL), |
| waiting_for_new_page_(true), |
| is_mouse_down_from_activate_(false), |
| user_typed_before_load_(false) { |
| @@ -176,14 +144,14 @@ class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { |
| user_typed_before_load_ = false; |
| waiting_for_new_page_ = true; |
| add_page_vector_.clear(); |
| - DestroyPaintObserver(); |
| + UnregisterForPaintNotifications(); |
| } |
| // Invoked when removed as the delegate. Gives a chance to do any necessary |
| // cleanup. |
| void Reset() { |
| is_mouse_down_from_activate_ = false; |
| - DestroyPaintObserver(); |
| + UnregisterForPaintNotifications(); |
| } |
| // Invoked when the preview paints. Invokes PreviewPainted on the loader. |
| @@ -191,12 +159,6 @@ class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { |
| loader_->PreviewPainted(); |
| } |
| - // Invoked when the PaintObserverImpl is deleted. |
| - void PaintObserverDestroyed(PaintObserverImpl* observer) { |
| - if (observer == paint_observer_) |
| - paint_observer_ = NULL; |
| - } |
| - |
| bool is_mouse_down_from_activate() const { |
| return is_mouse_down_from_activate_; |
| } |
| @@ -262,20 +224,56 @@ class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { |
| } |
| } |
| + void RegisterForPaintNotifications(RenderWidgetHost* render_widget_host) { |
|
sky
2011/01/07 21:04:16
Move the register/unregister methods to the privat
|
| + DCHECK(registered_render_widget_host_ == NULL); |
| + registered_render_widget_host_ = render_widget_host; |
| + Source<RenderWidgetHost> source = |
| + Source<RenderWidgetHost>(registered_render_widget_host_); |
| + registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DID_PAINT, |
| + source); |
| + registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DESTROYED, |
| + source); |
| + } |
| + |
| + void UnregisterForPaintNotifications() { |
| + if (registered_render_widget_host_) { |
| + Source<RenderWidgetHost> source = |
| + Source<RenderWidgetHost>(registered_render_widget_host_); |
| + registrar_.Remove(this, NotificationType::RENDER_WIDGET_HOST_DID_PAINT, |
| + source); |
| + registrar_.Remove(this, NotificationType::RENDER_WIDGET_HOST_DESTROYED, |
| + source); |
| + registered_render_widget_host_ = NULL; |
| + } |
| + } |
| + |
| + void Observe(NotificationType type, |
|
sky
2011/01/07 21:04:16
virtual
|
| + const NotificationSource& source, |
| + const NotificationDetails& details) { |
| + if (type == NotificationType::RENDER_WIDGET_HOST_DID_PAINT) { |
| + UnregisterForPaintNotifications(); |
| + PreviewPainted(); |
| + } else if (type == NotificationType::RENDER_WIDGET_HOST_DESTROYED) { |
| + UnregisterForPaintNotifications(); |
| + } else { |
| + NOTREACHED() << "Got a notification we didn't register for."; |
| + } |
| + } |
| + |
| virtual void OpenURLFromTab(TabContents* source, |
| const GURL& url, const GURL& referrer, |
| WindowOpenDisposition disposition, |
| PageTransition::Type transition) {} |
| virtual void NavigationStateChanged(const TabContents* source, |
| unsigned changed_flags) { |
| - if (!loader_->ready() && !paint_observer_ && |
| + if (!loader_->ready() && !registered_render_widget_host_ && |
| source->controller().entry_count()) { |
| // The load has been committed. Install an observer that waits for the |
| // first paint then makes the preview active. We wait for the load to be |
| // committed before waiting on paint as there is always an initial paint |
| // when a new renderer is created from the resize so that if we showed the |
| // preview after the first paint we would end up with a white rect. |
| - paint_observer_ = new PaintObserverImpl(this, |
| + RegisterForPaintNotifications( |
| source->GetRenderWidgetHostView()->GetRenderWidgetHost()); |
| } |
| } |
| @@ -306,7 +304,7 @@ class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { |
| if (!loader_->ready()) { |
| // A constrained window shown for an auth may not paint. Show the preview |
| // contents. |
| - DestroyPaintObserver(); |
| + UnregisterForPaintNotifications(); |
| loader_->ShowPreview(); |
| } |
| } |
| @@ -384,22 +382,10 @@ class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { |
| loader_->CommitInstantLoader(); |
| } |
| - // If the PaintObserver is non-null Destroy is invoked on it. |
| - void DestroyPaintObserver() { |
| - if (paint_observer_) { |
| - paint_observer_->Destroy(); |
| - // Destroy should result in invoking PaintObserverDestroyed and NULLing |
| - // out paint_observer_. |
| - DCHECK(!paint_observer_); |
| - } |
| - } |
| - |
| InstantLoader* loader_; |
| - // Used to listen for paint so that we know when to show the preview. See |
| - // comment in NavigationStateChanged for details on this. |
| - // Ownership of this is tricky, see comment above PaintObserverImpl class. |
| - PaintObserverImpl* paint_observer_; |
| + NotificationRegistrar registrar_; |
| + RenderWidgetHost* registered_render_widget_host_; |
|
sky
2011/01/07 21:04:16
Comment?
|
| // Used to cache data that needs to be added to history. Normally entries are |
| // added to history as the user types, but for instant we only want to add the |
| @@ -420,22 +406,6 @@ class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate { |
| DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl); |
| }; |
| -InstantLoader::PaintObserverImpl::~PaintObserverImpl() { |
| - delegate_->PaintObserverDestroyed(this); |
| -} |
| - |
| -void InstantLoader::PaintObserverImpl::RenderWidgetHostDidPaint( |
| - RenderWidgetHost* rwh) { |
| - TabContentsDelegateImpl* delegate = delegate_; |
| - // Set the paint observer to NULL, which deletes us. Showing the preview may |
| - // reset the paint observer, and delete us. By resetting the delegate first we |
| - // know we've been deleted and can deal correctly. |
| - rwh->set_paint_observer(NULL); |
| - // WARNING: we've been deleted. |
| - if (delegate) |
| - delegate->PreviewPainted(); |
| -} |
| - |
| InstantLoader::InstantLoader(InstantLoaderDelegate* delegate, TemplateURLID id) |
| : delegate_(delegate), |
| template_url_id_(id), |
| @@ -611,11 +581,7 @@ TabContentsWrapper* InstantLoader::ReleasePreviewContents( |
| } |
| preview_tab_contents_delegate_->CommitHistory(template_url_id_ != 0); |
| } |
| - // Destroy the paint observer. |
| - // RenderWidgetHostView may be null during shutdown. |
| if (preview_contents_->tab_contents()->GetRenderWidgetHostView()) { |
| - preview_contents_->tab_contents()->GetRenderWidgetHostView()-> |
| - GetRenderWidgetHost()->set_paint_observer(NULL); |
| #if defined(OS_MACOSX) |
| preview_contents_->tab_contents()->GetRenderWidgetHostView()-> |
| SetTakesFocusOnlyOnMouseDown(false); |