 Chromium Code Reviews
 Chromium Code Reviews Issue 972313002:
  Make <webview> use out-of-process iframe architecture.  (Closed) 
  Base URL: ssh://saopaulo.wat/mnt/dev/shared/src@testoopif2z-better-chrome
    
  
    Issue 972313002:
  Make <webview> use out-of-process iframe architecture.  (Closed) 
  Base URL: ssh://saopaulo.wat/mnt/dev/shared/src@testoopif2z-better-chrome| Index: content/browser/web_contents/web_contents_impl.cc | 
| diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc | 
| index 2a8a92c6b93fc5ff7299201af9e88d660da46596..56dec4081a8112384a7340a19b6dccf6ed931f70 100644 | 
| --- a/content/browser/web_contents/web_contents_impl.cc | 
| +++ b/content/browser/web_contents/web_contents_impl.cc | 
| @@ -286,6 +286,33 @@ WebContentsImpl::ColorChooserInfo::ColorChooserInfo(int render_process_id, | 
| WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { | 
| } | 
| +// WebContentsImpl::WebContentsTreeNode ---------------------------------------- | 
| +WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() | 
| + : outer_web_contents_(nullptr) { | 
| +} | 
| + | 
| +WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { | 
| + // Remove child pointers from our parent. | 
| 
lfg
2015/05/26 19:18:15
Maybe we should have the outer WebContents own the
 
nasko
2015/05/28 22:13:46
This does seem a bit hacky. Can't we manage the li
 
lazyboy
2015/05/29 00:02:24
Right now <webview>s WebContents's lifetime depend
 | 
| + if (outer_web_contents_) { | 
| + std::set<WebContentsTreeNode*>& child_ptrs_in_parent = | 
| 
nasko
2015/05/28 22:13:46
nit: Why not typedef std::set<WebContentsTreeNode*
 
lazyboy
2015/05/29 00:02:24
Done.
 | 
| + outer_web_contents_->node_.inner_web_contents_tree_nodes_; | 
| + std::set<WebContentsTreeNode*>::iterator iter = | 
| + child_ptrs_in_parent.find(this); | 
| + DCHECK(iter != child_ptrs_in_parent.end()); | 
| + child_ptrs_in_parent.erase(this); | 
| + } | 
| + | 
| + // Remove parent pointers from our children. | 
| + for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) | 
| + child->outer_web_contents_ = nullptr; | 
| +} | 
| + | 
| +void WebContentsImpl::WebContentsTreeNode::SetOuterWebContents( | 
| + WebContentsImpl* outer_web_contents) { | 
| + outer_web_contents_ = outer_web_contents; | 
| + outer_web_contents_->node_.inner_web_contents_tree_nodes_.insert(this); | 
| +} | 
| + | 
| // WebContentsImpl ------------------------------------------------------------- | 
| WebContentsImpl::WebContentsImpl(BrowserContext* browser_context, | 
| @@ -1136,6 +1163,38 @@ void WebContentsImpl::DispatchBeforeUnload(bool for_cross_site_transition) { | 
| GetMainFrame()->DispatchBeforeUnload(for_cross_site_transition); | 
| } | 
| +void WebContentsImpl::AttachToOuterWebContentsFrame( | 
| + WebContents* outer_web_contents, | 
| + RenderFrameHost* outer_contents_frame) { | 
| + CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| + switches::kSitePerProcess)); | 
| + // Create a link to our outer WebContents. | 
| + node_.SetOuterWebContents(static_cast<WebContentsImpl*>(outer_web_contents)); | 
| + | 
| + DCHECK(outer_contents_frame); | 
| + | 
| + // Create a swapped out RVH and a proxy in our render manager, pointing | 
| + // to the SiteInstance of the outer WebContents. The swapped out RVH will be | 
| + // used to send postMessage to the inner WebContents. | 
| + // TODO(lazyboy): Use RenderFrameHostManager::CreateRenderFrameProxy() once | 
| + // we can a proxy without swapped out RV and RF. | 
| 
nasko
2015/05/28 22:13:46
nit: RenderView will stick around a bit longer, bu
 
lazyboy
2015/05/29 00:02:24
So remove the RV from the comment?
Done.
 | 
| + int proxy_to_outer_web_contents_routing_id = | 
| + GetRenderManager()->CreateOuterDelegateProxy( | 
| + outer_contents_frame->GetSiteInstance()); | 
| + | 
| + // Swap the outer WebContents's initial frame for the inner WebContents with | 
| + // the proxy we've created above. | 
| + // The proxy has a CPFC and it uses the swapped out RV as its RenderWidget, | 
| + // which gives us input and rendering. | 
| + static_cast<RenderFrameHostImpl*>(outer_contents_frame) | 
| + ->frame_tree_node() | 
| + ->render_manager() | 
| + ->SwapFrameWithProxy(proxy_to_outer_web_contents_routing_id); | 
| + | 
| + GetRenderManager()->SetRWHViewForInnerContents( | 
| + GetRenderManager()->GetRenderWidgetHostView()); | 
| +} | 
| + | 
| void WebContentsImpl::Stop() { | 
| GetRenderManager()->Stop(); | 
| FOR_EACH_OBSERVER(WebContentsObserver, observers_, NavigationStopped()); | 
| @@ -1208,7 +1267,9 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) { | 
| WebContentsViewDelegate* delegate = | 
| GetContentClient()->browser()->GetWebContentsViewDelegate(this); | 
| - if (browser_plugin_guest_) { | 
| + if (browser_plugin_guest_ && | 
| + !base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| + switches::kSitePerProcess)) { | 
| scoped_ptr<WebContentsView> platform_view(CreateWebContentsView( | 
| this, delegate, &render_view_host_delegate_view_)); | 
| @@ -1517,6 +1578,14 @@ void WebContentsImpl::CreateNewWindow( | 
| // SiteInstance in its own BrowsingInstance. | 
| bool is_guest = BrowserPluginGuest::IsGuest(this); | 
| + if (is_guest && | 
| + base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| + switches::kSitePerProcess)) { | 
| + // TODO(lazyboy): CreateNewWindow doesn't work for OOPIF-based <webview> | 
| + // yet. | 
| + NOTREACHED(); | 
| + } | 
| + | 
| // If the opener is to be suppressed, the new window can be in any process. | 
| // Since routing ids are process specific, we must not have one passed in | 
| // as argument here. | 
| @@ -4144,7 +4213,11 @@ bool WebContentsImpl::CreateRenderViewForRenderManager( | 
| // until RenderWidgetHost is attached to RenderFrameHost. We need to special | 
| // case this because RWH is still a base class of RenderViewHost, and child | 
| // frame RWHVs are unique in that they do not have their own WebContents. | 
| - if (!for_main_frame_navigation) { | 
| + bool is_guest_in_site_per_process = | 
| + !!browser_plugin_guest_.get() && | 
| + base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| + switches::kSitePerProcess); | 
| + if (!for_main_frame_navigation || is_guest_in_site_per_process) { | 
| RenderWidgetHostViewChildFrame* rwh_view_child = | 
| new RenderWidgetHostViewChildFrame(render_view_host); | 
| rwh_view = rwh_view_child; | 
| @@ -4288,6 +4361,16 @@ bool WebContentsImpl::IsHidden() { | 
| return capturer_count_ == 0 && !should_normally_be_visible_; | 
| } | 
| +int WebContentsImpl::GetOuterDelegateFrameTreeNodeID() { | 
| + if (node_.outer_web_contents()) { | 
| + return node_.outer_web_contents() | 
| + ->GetFrameTree() | 
| + ->root() | 
| + ->frame_tree_node_id(); | 
| + } | 
| + return -1; | 
| +} | 
| + | 
| RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { | 
| return frame_tree_.root()->render_manager(); | 
| } | 
| @@ -4298,6 +4381,7 @@ BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { | 
| void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { | 
| CHECK(!browser_plugin_guest_); | 
| + CHECK(guest); | 
| browser_plugin_guest_.reset(guest); | 
| } |