Fix the issue that any tab/window closing hotkey will crash the Pepper Flash Fullscreen.
BUG=149821
TEST=None
Review URL: https://chromiumcodereview.appspot.com/10968037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158408 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h
index 4f0243b..29011b53 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -9,6 +9,7 @@
namespace content {
+class RenderWidgetHostImpl;
struct NativeWebKeyboardEvent;
//
@@ -18,6 +19,9 @@
// of the RenderWidgetHost.
class CONTENT_EXPORT RenderWidgetHostDelegate {
public:
+ // The RenderWidgetHost is going to be deleted.
+ virtual void RenderWidgetDeleted(RenderWidgetHostImpl* render_widget_host) {}
+
// Callback to give the browser a chance to handle the specified keyboard
// event before sending it to the renderer.
// Returns true if the |event| was handled. Otherwise, if the |event| would
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index e5aaac8..62f2892 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -185,6 +185,9 @@
surface_id_ = 0;
process_->Release(routing_id_);
+
+ if (delegate_)
+ delegate_->RenderWidgetDeleted(this);
}
// static
@@ -969,10 +972,6 @@
bool is_keyboard_shortcut = false;
// Only pre-handle the key event if it's not handled by the input method.
- // A delegate_ of NULL seems impossible but crash reports show that it
- // can happen (see http://crbug.com/134465). This doesn't seem to happen
- // with Chrome 22 and later, so checking the delegate_ here can be removed
- // once Chrome 22 goes to stable..
if (delegate_ && !key_event.skip_in_browser) {
// We need to set |suppress_next_char_events_| to true if
// PreHandleKeyboardEvent() returns true, but |this| may already be
@@ -1849,7 +1848,7 @@
// We only send unprocessed key event upwards if we are not hidden,
// because the user has moved away from us and no longer expect any effect
// of this key event.
- if (!processed && !is_hidden_ && !front_item.skip_in_browser) {
+ if (delegate_ && !processed && !is_hidden_ && !front_item.skip_in_browser) {
delegate_->HandleKeyboardEvent(front_item);
// WARNING: This RenderWidgetHostImpl can be deallocated at this point
@@ -2060,4 +2059,8 @@
OnRenderAutoResized(new_size);
}
+void RenderWidgetHostImpl::DetachDelegate() {
+ delegate_ = NULL;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 4eeaa44a..916bcd58 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -66,6 +66,8 @@
public:
// routing_id can be MSG_ROUTING_NONE, in which case the next available
// routing id is taken from the RenderProcessHost.
+ // If this object outlives |delegate|, DetachDelegate() must be called when
+ // |delegate| goes away.
RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
int routing_id);
@@ -419,6 +421,8 @@
// any previous pending acks that are not relevant upon repaint.
void ResetSizeAndRepaintPendingFlags();
+ void DetachDelegate();
+
protected:
virtual RenderWidgetHostImpl* AsRenderWidgetHostImpl() OVERRIDE;
@@ -439,10 +443,9 @@
// when accelerated compositing is enabled.
gfx::GLSurfaceHandle GetCompositingSurface();
- // "RenderWidgetHostDelegate" ------------------------------------------------
- // There is no RenderWidgetHostDelegate but the following methods serve the
- // same purpose. They are overridden by RenderViewHost to send upwards to its
- // delegate.
+ // ---------------------------------------------------------------------------
+ // The following methods are overridden by RenderViewHost to send upwards to
+ // its delegate.
// Called when a mousewheel event was not processed by the renderer.
virtual void UnhandledWheelEvent(const WebKit::WebMouseWheelEvent& event) {}
@@ -638,6 +641,7 @@
void TickActiveSmoothScrollGesture();
// Our delegate, which wants to know mainly about keyboard events.
+ // It will remain non-NULL until DetachDelegate() is called.
RenderWidgetHostDelegate* delegate_;
// Created during construction but initialized during Init*(). Therefore, it
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index fe9c088..a92e5d3 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -365,6 +365,12 @@
WebContentsImpl::~WebContentsImpl() {
is_being_destroyed_ = true;
+ for (std::set<RenderWidgetHostImpl*>::iterator iter =
+ created_widgets_.begin(); iter != created_widgets_.end(); ++iter) {
+ (*iter)->DetachDelegate();
+ }
+ created_widgets_.clear();
+
// Clear out any JavaScript state.
if (dialog_creator_)
dialog_creator_->ResetJavaScriptState(this);
@@ -1194,6 +1200,19 @@
delegate_->LostCapture();
}
+void WebContentsImpl::RenderWidgetDeleted(
+ RenderWidgetHostImpl* render_widget_host) {
+ if (is_being_destroyed_) {
+ // |created_widgets_| might have been destroyed.
+ return;
+ }
+
+ std::set<RenderWidgetHostImpl*>::iterator iter =
+ created_widgets_.find(render_widget_host);
+ if (iter != created_widgets_.end())
+ created_widgets_.erase(iter);
+}
+
bool WebContentsImpl::PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) {
@@ -1356,6 +1375,8 @@
content::RenderProcessHost* process = GetRenderProcessHost();
RenderWidgetHostImpl* widget_host =
new RenderWidgetHostImpl(this, process, route_id);
+ created_widgets_.insert(widget_host);
+
RenderWidgetHostViewPort* widget_view =
RenderWidgetHostViewPort::CreateViewForWidget(widget_host);
if (!is_fullscreen) {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 2dcbfd2e..9429df3 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_IMPL_H_
#include <map>
+#include <set>
#include <string>
#include "base/compiler_specific.h"
@@ -47,6 +48,7 @@
class RenderViewHost;
class RenderViewHostDelegateView;
class RenderViewHostImpl;
+class RenderWidgetHostImpl;
class SiteInstance;
class TestWebContents;
class WebContentsDelegate;
@@ -429,6 +431,8 @@
// RenderWidgetHostDelegate --------------------------------------------------
+ virtual void RenderWidgetDeleted(
+ content::RenderWidgetHostImpl* render_widget_host) OVERRIDE;
virtual bool PreHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) OVERRIDE;
@@ -859,6 +863,10 @@
// to the RVH through which the message was received.
content::RenderViewHost* message_source_;
+ // All live RenderWidgetHostImpls that are created by this object and may
+ // outlive it.
+ std::set<content::RenderWidgetHostImpl*> created_widgets_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsImpl);
};