Commit 5b2090af authored by Avi Drissman's avatar Avi Drissman Committed by Commit Bot

Make the hung page dialog watch the instigating widget.

On Windows, fullscreen widgets kill themselves when losing focus,
which means that if they hang, the mere act of trying to display
the "hung page" dialog will kill the hung page.

Watch the widget to avoid a crash in this case.

This shouldn't be (and isn't) crashing on the Mac in this way, but
this makes the parallel changes on the Mac for symmetry.

BUG=811737
TEST=as in bug

Change-Id: I81f1797c3f5473b21eee2eed6c660e0f3acd1352
Reviewed-on: https://chromium-review.googlesource.com/961461Reviewed-by: default avatarSidney San Martín <sdy@chromium.org>
Commit-Queue: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543151}
parent dd36aa38
......@@ -18,6 +18,10 @@
#include "chrome/common/logging_chrome.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_observer.h"
......@@ -69,16 +73,20 @@ HungRendererController* g_hung_renderer_controller_instance = nil;
} // namespace
class HungRendererObserverBridge : public content::WebContentsObserver,
public content::RenderProcessHostObserver {
public content::RenderProcessHostObserver,
public content::NotificationObserver {
public:
HungRendererObserverBridge(WebContents* web_contents,
content::RenderProcessHost* hung_process,
content::RenderWidgetHost* hung_widget,
HungRendererController* controller)
: content::WebContentsObserver(web_contents),
hung_process_(hung_process),
hung_process_(hung_widget->GetProcess()),
process_observer_(this),
controller_(controller) {
process_observer_.Add(hung_process_);
notification_registrar_.Add(
this, content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
content::Source<content::RenderWidgetHost>(hung_widget));
}
~HungRendererObserverBridge() override = default;
......@@ -99,6 +107,14 @@ class HungRendererObserverBridge : public content::WebContentsObserver,
[controller_ renderProcessGone];
}
// NotificationObserver overrides:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override {
DCHECK_EQ(content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, type);
[controller_ renderProcessGone];
}
private:
content::RenderProcessHost* hung_process_;
......@@ -107,6 +123,8 @@ class HungRendererObserverBridge : public content::WebContentsObserver,
HungRendererController* controller_; // weak
content::NotificationRegistrar notification_registrar_;
DISALLOW_COPY_AND_ASSIGN(HungRendererObserverBridge);
};
......@@ -261,8 +279,8 @@ class HungRendererObserverBridge : public content::WebContentsObserver,
DCHECK(contents);
hungContents_ = contents;
hungWidget_ = renderWidget;
hungContentsObserver_.reset(new HungRendererObserverBridge(
contents, renderWidget->GetProcess(), self));
hungContentsObserver_.reset(
new HungRendererObserverBridge(contents, renderWidget, self));
base::scoped_nsobject<NSMutableArray> titles([[NSMutableArray alloc] init]);
base::scoped_nsobject<NSMutableArray> favicons([[NSMutableArray alloc] init]);
......
......@@ -29,6 +29,8 @@
#include "components/constrained_window/constrained_window_views.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "components/web_modal/web_contents_modal_dialog_host.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
......@@ -76,6 +78,7 @@ void HungPagesTableModel::InitForWebContents(
WebContents* contents,
content::RenderWidgetHost* render_widget_host) {
process_observer_.RemoveAll();
notification_registrar_.RemoveAll();
render_widget_host_ = render_widget_host;
tab_observers_.clear();
......@@ -87,8 +90,12 @@ void HungPagesTableModel::InitForWebContents(
}
}
if (render_widget_host_)
if (render_widget_host_) {
process_observer_.Add(render_widget_host_->GetProcess());
notification_registrar_.Add(
this, content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
content::Source<content::RenderWidgetHost>(render_widget_host_));
}
// The world is different.
if (observer_)
......@@ -131,6 +138,18 @@ void HungPagesTableModel::RenderProcessExited(content::RenderProcessHost* host,
// WARNING: we've likely been deleted.
}
///////////////////////////////////////////////////////////////////////////////
// HungPagesTableModel, NotificationObserver implementation:
void HungPagesTableModel::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, type);
// Notify the delegate.
delegate_->TabDestroyed();
// WARNING: we've likely been deleted.
}
void HungPagesTableModel::TabDestroyed(WebContentsObserverImpl* tab) {
// Clean up tab_observers_ and notify our observer.
size_t index = 0;
......
......@@ -8,6 +8,8 @@
#include "base/macros.h"
#include "base/scoped_observer.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/base/models/table_model.h"
......@@ -25,7 +27,8 @@ class Label;
// Provides functionality to display information about a hung renderer.
class HungPagesTableModel : public ui::TableModel,
public content::RenderProcessHostObserver {
public content::RenderProcessHostObserver,
public content::NotificationObserver {
public:
class Delegate {
public:
......@@ -60,6 +63,11 @@ class HungPagesTableModel : public ui::TableModel,
base::TerminationStatus status,
int exit_code) override;
// Overridden from NotificationObserver:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
private:
friend class HungRendererDialogViewBrowserTest;
......@@ -103,6 +111,8 @@ class HungPagesTableModel : public ui::TableModel,
ScopedObserver<content::RenderProcessHost, content::RenderProcessHostObserver>
process_observer_;
content::NotificationRegistrar notification_registrar_;
DISALLOW_COPY_AND_ASSIGN(HungPagesTableModel);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment