diff options
author | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-18 01:34:33 +0000 |
---|---|---|
committer | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-18 01:34:33 +0000 |
commit | c092f5c4102aaf44e02c958a5cf46de8691324d7 (patch) | |
tree | 345afcd92b9062b3395b881d96b8ba3fb59643aa | |
parent | 3ed389390ce8e321d0a5691f16ca139d7c3a0e81 (diff) | |
download | chromium_src-c092f5c4102aaf44e02c958a5cf46de8691324d7.zip chromium_src-c092f5c4102aaf44e02c958a5cf46de8691324d7.tar.gz chromium_src-c092f5c4102aaf44e02c958a5cf46de8691324d7.tar.bz2 |
Changes to RenderFrameProxy:
- Add accessors: web_frame(), routing_id(), render_view().
- Remove accessor: render_frame(). Where we do need to touch the
RenderFrame, we'll look it up by its routing ID.
- Small change to the CompositingHelper to use the new getters.
- Add a map to allow finding a RenderFrameProxy by its associated
blink::WebFrame.
- Introduce a second factory function and differentiate the two
factory functions according to the two ways RenderFrameProxies will
be created. The first is for when an extant local RenderFrame is
being swapped out and replaced with a new RenderFrameProxy. The
second is for when a RenderFrameProxy needs to be created without
displacing an existing RenderFrame, as shall occur once we mirror
the frame tree.
- This second factory function, which is uncalled at the moment, will
create WebRemoteFrames. Also there is stubbed out code in the first
factory function to create WebRemoteFrames. This code is in
preparation for eliminating the RenderFrame (and its attendant
WebLocalFrame) and having instead just a RenderFrameProxy.
- Add some defensive checks to prepare for when the render frame may
not exist, as will happen once the second factory function
enters use.
- Add an Init function so that code can be shared between the two
factory functions.
As an adminstrative note, this patch is a chunk of nasko's
larger "use RenderFrameProxyHost" effor (issue 241223002)
BUG=357747
TEST=browsertests, http://csreis.github.io/tests/cross-site-iframe.html renders after going cross-site under --site-per-process
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=283572
Review URL: https://codereview.chromium.org/357043006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283965 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/renderer/browser_plugin/browser_plugin.cc | 5 | ||||
-rw-r--r-- | content/renderer/child_frame_compositing_helper.cc | 15 | ||||
-rw-r--r-- | content/renderer/child_frame_compositing_helper.h | 8 | ||||
-rw-r--r-- | content/renderer/render_frame_impl.cc | 3 | ||||
-rw-r--r-- | content/renderer/render_frame_proxy.cc | 139 | ||||
-rw-r--r-- | content/renderer/render_frame_proxy.h | 52 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 5 |
7 files changed, 172 insertions, 55 deletions
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 94ff36e..5cad47f 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -558,9 +558,8 @@ void BrowserPlugin::EnableCompositing(bool enable) { if (enable) { DCHECK(!compositing_helper_.get()); if (!compositing_helper_.get()) { - compositing_helper_ = - ChildFrameCompositingHelper::CreateCompositingHelperForBrowserPlugin( - weak_ptr_factory_.GetWeakPtr()); + compositing_helper_ = ChildFrameCompositingHelper::CreateForBrowserPlugin( + weak_ptr_factory_.GetWeakPtr()); } } compositing_helper_->EnableCompositing(enable); diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 8790ae2..480d3c0 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc @@ -40,20 +40,19 @@ ChildFrameCompositingHelper::SwapBuffersInfo::SwapBuffersInfo() shared_memory(NULL) {} ChildFrameCompositingHelper* -ChildFrameCompositingHelper::CreateCompositingHelperForBrowserPlugin( +ChildFrameCompositingHelper::CreateForBrowserPlugin( const base::WeakPtr<BrowserPlugin>& browser_plugin) { return new ChildFrameCompositingHelper( browser_plugin, NULL, NULL, browser_plugin->render_view_routing_id()); } ChildFrameCompositingHelper* -ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( - blink::WebFrame* frame, - RenderFrameProxy* render_frame_proxy, - int host_routing_id) { - return new ChildFrameCompositingHelper( - base::WeakPtr<BrowserPlugin>(), frame, render_frame_proxy, - host_routing_id); +ChildFrameCompositingHelper::CreateForRenderFrameProxy( + RenderFrameProxy* render_frame_proxy) { + return new ChildFrameCompositingHelper(base::WeakPtr<BrowserPlugin>(), + render_frame_proxy->web_frame(), + render_frame_proxy, + render_frame_proxy->routing_id()); } ChildFrameCompositingHelper::ChildFrameCompositingHelper( diff --git a/content/renderer/child_frame_compositing_helper.h b/content/renderer/child_frame_compositing_helper.h index d66ae3f..5ecf9a8 100644 --- a/content/renderer/child_frame_compositing_helper.h +++ b/content/renderer/child_frame_compositing_helper.h @@ -56,12 +56,10 @@ class CONTENT_EXPORT ChildFrameCompositingHelper : public base::RefCounted<ChildFrameCompositingHelper>, public cc::DelegatedFrameResourceCollectionClient { public: - static ChildFrameCompositingHelper* CreateCompositingHelperForBrowserPlugin( + static ChildFrameCompositingHelper* CreateForBrowserPlugin( const base::WeakPtr<BrowserPlugin>& browser_plugin); - static ChildFrameCompositingHelper* CreateCompositingHelperForRenderFrame( - blink::WebFrame* frame, - RenderFrameProxy* render_frame_proxy, - int host_routing_id); + static ChildFrameCompositingHelper* CreateForRenderFrameProxy( + RenderFrameProxy* render_frame_proxy); void CopyFromCompositingSurface(int request_id, gfx::Rect source_rect, diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index dba0887..85308be 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -954,7 +954,8 @@ void RenderFrameImpl::OnSwapOut(int proxy_routing_id) { // RenderFrameProxy as well so its routing id is registered for receiving // IPC messages. render_view_->SyncNavigationState(); - proxy = RenderFrameProxy::CreateFrameProxy(proxy_routing_id, routing_id_); + proxy = RenderFrameProxy::CreateProxyToReplaceFrame(this, + proxy_routing_id); // Synchronously run the unload handler before sending the ACK. // TODO(creis): Call dispatchUnloadEvent unconditionally here to support diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 2e85a52..e8da001 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc @@ -19,18 +19,72 @@ namespace content { namespace { +// Facilitates lookup of RenderFrameProxy by routing_id. typedef std::map<int, RenderFrameProxy*> RoutingIDProxyMap; static base::LazyInstance<RoutingIDProxyMap> g_routing_id_proxy_map = LAZY_INSTANCE_INITIALIZER; +// Facilitates lookup of RenderFrameProxy by WebFrame. +typedef std::map<blink::WebFrame*, RenderFrameProxy*> FrameMap; +base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER; + } // namespace // static -RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(int routing_id, - int frame_routing_id) { - DCHECK_NE(routing_id, MSG_ROUTING_NONE); - RenderFrameProxy* proxy = new RenderFrameProxy(routing_id, frame_routing_id); - return proxy; +RenderFrameProxy* RenderFrameProxy::CreateProxyToReplaceFrame( + RenderFrameImpl* frame_to_replace, + int routing_id) { + CHECK_NE(routing_id, MSG_ROUTING_NONE); + + scoped_ptr<RenderFrameProxy> proxy( + new RenderFrameProxy(routing_id, frame_to_replace->GetRoutingID())); +#if 0 + // TODO(nick): Enable this code when we're ready to create WebRemoteFrames. + blink::WebRemoteFrame* web_frame = NULL; + if (frame_to_replace->GetWebFrame()->parent() && + frame_to_replace->GetWebFrame()->parent()->isWebRemoteFrame()) { + blink::WebRemoteFrame* parent_web_frame = + frame_to_replace->GetWebFrame()->parent()->toWebRemoteFrame(); + web_frame = parent_web_frame->createRemoteChild("", proxy.get()); + } else { + web_frame = blink::WebRemoteFrame::create(proxy.get()); + } +#else + blink::WebFrame* web_frame = frame_to_replace->GetWebFrame(); +#endif + proxy->Init(web_frame, frame_to_replace->render_view()); + return proxy.release(); +} + +RenderFrameProxy* RenderFrameProxy::CreateFrameProxy( + int routing_id, + int parent_routing_id, + int render_view_routing_id) { + scoped_ptr<RenderFrameProxy> proxy( + new RenderFrameProxy(routing_id, MSG_ROUTING_NONE)); + RenderViewImpl* render_view = NULL; + blink::WebRemoteFrame* web_frame = NULL; + if (parent_routing_id == MSG_ROUTING_NONE) { + // Create a top level frame. + render_view = RenderViewImpl::FromRoutingID(render_view_routing_id); + web_frame = blink::WebRemoteFrame::create(proxy.get()); + render_view->webview()->setMainFrame(web_frame); + } else { + // Create a frame under an existing parent. The parent is always expected to + // be a RenderFrameProxy, because navigations initiated by local frames + // should not wind up here. + RenderFrameProxy* parent = + RenderFrameProxy::FromRoutingID(parent_routing_id); + CHECK(parent); + CHECK(parent->web_frame()->isWebRemoteFrame()); + web_frame = parent->web_frame()->toWebRemoteFrame()->createRemoteChild( + "", proxy.get()); + render_view = parent->render_view(); + } + + proxy->Init(web_frame, render_view); + + return proxy.release(); } // static @@ -40,27 +94,58 @@ RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32 routing_id) { return it == proxies->end() ? NULL : it->second; } +// static +RenderFrameProxy* RenderFrameProxy::FromWebFrame(blink::WebFrame* web_frame) { + FrameMap::iterator iter = g_frame_map.Get().find(web_frame); + if (iter != g_frame_map.Get().end()) { + RenderFrameProxy* proxy = iter->second; + DCHECK_EQ(web_frame, proxy->web_frame()); + return proxy; + } + return NULL; +} + RenderFrameProxy::RenderFrameProxy(int routing_id, int frame_routing_id) : routing_id_(routing_id), - frame_routing_id_(frame_routing_id) { + frame_routing_id_(frame_routing_id), + web_frame_(NULL), + render_view_(NULL) { std::pair<RoutingIDProxyMap::iterator, bool> result = - g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this)); + g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this)); CHECK(result.second) << "Inserting a duplicate item."; RenderThread::Get()->AddRoute(routing_id_, this); - - render_frame_ = RenderFrameImpl::FromRoutingID(frame_routing_id); - CHECK(render_frame_); - render_frame_->render_view()->RegisterRenderFrameProxy(this); } RenderFrameProxy::~RenderFrameProxy() { - render_frame_->render_view()->UnregisterRenderFrameProxy(this); + render_view()->UnregisterRenderFrameProxy(this); + + FrameMap::iterator it = g_frame_map.Get().find(web_frame_); + CHECK(it != g_frame_map.Get().end()); + CHECK_EQ(it->second, this); + g_frame_map.Get().erase(it); + RenderThread::Get()->RemoveRoute(routing_id_); g_routing_id_proxy_map.Get().erase(routing_id_); + + // TODO(nick): Call close unconditionally when web_frame() is always remote. + if (web_frame()->isWebRemoteFrame()) + web_frame()->close(); } -blink::WebFrame* RenderFrameProxy::GetWebFrame() { - return render_frame_->GetWebFrame(); +void RenderFrameProxy::Init(blink::WebFrame* web_frame, + RenderViewImpl* render_view) { + CHECK(web_frame); + CHECK(render_view); + + web_frame_ = web_frame; + render_view_ = render_view; + + // TODO(nick): Should all RenderFrameProxies remain observers of their views? + render_view_->RegisterRenderFrameProxy(this); + + std::pair<FrameMap::iterator, bool> result = + g_frame_map.Get().insert(std::make_pair(web_frame_, this)); + CHECK(result.second) << "Inserted a duplicate item."; } void RenderFrameProxy::DidCommitCompositorFrame() { @@ -79,10 +164,13 @@ bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() - if (!handled) - return render_frame_->OnMessageReceived(msg); + // If |handled| is true, |this| may have been deleted. + if (handled) + return true; - return handled; + RenderFrameImpl* render_frame = + RenderFrameImpl::FromRoutingID(frame_routing_id_); + return render_frame && render_frame->OnMessageReceived(msg); } bool RenderFrameProxy::Send(IPC::Message* message) { @@ -97,8 +185,9 @@ bool RenderFrameProxy::Send(IPC::Message* message) { void RenderFrameProxy::OnDeleteProxy() { RenderFrameImpl* render_frame = RenderFrameImpl::FromRoutingID(frame_routing_id_); - CHECK(render_frame); - render_frame->set_render_frame_proxy(NULL); + + if (render_frame) + render_frame->set_render_frame_proxy(NULL); delete this; } @@ -110,10 +199,9 @@ void RenderFrameProxy::OnChildFrameProcessGone() { void RenderFrameProxy::OnBuffersSwapped( const FrameMsg_BuffersSwapped_Params& params) { - if (!compositing_helper_.get()) { + if (!compositing_helper_) { compositing_helper_ = - ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( - GetWebFrame(), this, routing_id_); + ChildFrameCompositingHelper::CreateForRenderFrameProxy(this); compositing_helper_->EnableCompositing(true); } compositing_helper_->OnBuffersSwapped( @@ -121,7 +209,7 @@ void RenderFrameProxy::OnBuffersSwapped( params.mailbox, params.gpu_route_id, params.gpu_host_id, - render_frame_->render_view()->GetWebView()->deviceScaleFactor()); + web_frame()->view()->deviceScaleFactor()); } void RenderFrameProxy::OnCompositorFrameSwapped(const IPC::Message& message) { @@ -132,10 +220,9 @@ void RenderFrameProxy::OnCompositorFrameSwapped(const IPC::Message& message) { scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame); param.a.frame.AssignTo(frame.get()); - if (!compositing_helper_.get()) { + if (!compositing_helper_) { compositing_helper_ = - ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame( - GetWebFrame(), this, routing_id_); + ChildFrameCompositingHelper::CreateForRenderFrameProxy(this); compositing_helper_->EnableCompositing(true); } compositing_helper_->OnCompositorFrameSwapped(frame.Pass(), diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 54c6361..db396ec 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h @@ -48,28 +48,56 @@ class CONTENT_EXPORT RenderFrameProxy public IPC::Sender, NON_EXPORTED_BASE(public blink::WebFrameClient) { public: + // This method should be used to create a RenderFrameProxy, which will replace + // an existing RenderFrame during its cross-process navigation from the + // current process to a different one. |routing_id| will be ID of the newly + // created RenderFrameProxy. |frame_to_replace| is the frame that the new + // proxy will eventually swap places with. + static RenderFrameProxy* CreateProxyToReplaceFrame( + RenderFrameImpl* frame_to_replace, + int routing_id); + + // This method should be used to create a RenderFrameProxy, when there isn't + // an existing RenderFrame. It should be called to construct a local + // representation of a RenderFrame that has been created in another process -- + // for example, after a cross-process navigation or after the addition of a + // new frame local to some other process. |routing_id| will be the ID of the + // newly created RenderFrameProxy. |parent_routing_id| is the routing ID of + // the RenderFrameProxy to which the new frame is parented. + // |render_view_routing_id| identifies the RenderView to be associated with + // this frame. + // + // |parent_routing_id| always identifies a RenderFrameProxy (never a + // RenderFrame) because a new child of a local frame should always start out + // as a frame, not a proxy. static RenderFrameProxy* CreateFrameProxy(int routing_id, - int frame_routing_id); + int parent_routing_id, + int render_view_routing_id); // Returns the RenderFrameProxy for the given routing ID. static RenderFrameProxy* FromRoutingID(int routing_id); + // Returns the RenderFrameProxy given a WebFrame. + static RenderFrameProxy* FromWebFrame(blink::WebFrame* web_frame); + virtual ~RenderFrameProxy(); // IPC::Sender virtual bool Send(IPC::Message* msg) OVERRIDE; - RenderFrameImpl* render_frame() { - return render_frame_; - } - // Out-of-process child frames receive a signal from RenderWidgetCompositor // when a compositor frame has committed. void DidCommitCompositorFrame(); + int routing_id() const { return routing_id_; } + RenderViewImpl* render_view() const { return render_view_; } + blink::WebFrame* web_frame() const { return web_frame_; } + private: RenderFrameProxy(int routing_id, int frame_routing_id); + void Init(blink::WebFrame* frame, RenderViewImpl* render_view); + // IPC::Listener virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; @@ -79,14 +107,20 @@ class CONTENT_EXPORT RenderFrameProxy void OnBuffersSwapped(const FrameMsg_BuffersSwapped_Params& params); void OnCompositorFrameSwapped(const IPC::Message& message); - blink::WebFrame* GetWebFrame(); + // The routing ID by which this RenderFrameProxy is known. + const int routing_id_; - int routing_id_; - int frame_routing_id_; - RenderFrameImpl* render_frame_; + // The routing ID of the local RenderFrame (if any) which this + // RenderFrameProxy is meant to replace in the frame tree. + const int frame_routing_id_; + // Stores the WebFrame we are associated with. + // TODO(nick): Make this always a WebRemoteFrame. + blink::WebFrame* web_frame_; scoped_refptr<ChildFrameCompositingHelper> compositing_helper_; + RenderViewImpl* render_view_; + DISALLOW_COPY_AND_ASSIGN(RenderFrameProxy); }; diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 811f235..4aeb478 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -764,9 +764,8 @@ void RenderViewImpl::Initialize(RenderViewImplParams* params) { if (params->proxy_routing_id != MSG_ROUTING_NONE) { CHECK(params->swapped_out); - RenderFrameProxy* proxy = - RenderFrameProxy::CreateFrameProxy(params->proxy_routing_id, - params->main_frame_routing_id); + RenderFrameProxy* proxy = RenderFrameProxy::CreateProxyToReplaceFrame( + main_render_frame_.get(), params->proxy_routing_id); main_render_frame_->set_render_frame_proxy(proxy); } |