Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: content/browser/web_contents/web_contents_impl.cc

Issue 2506183002: Make window.open() IPCs be frame-based (Closed)
Patch Set: Rebase. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/web_contents/web_contents_impl.h" 5 #include "content/browser/web_contents/web_contents_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <cmath> 9 #include <cmath>
10 #include <utility> 10 #include <utility>
(...skipping 1982 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 1993
1994 void WebContentsImpl::OnRenderFrameProxyVisibilityChanged(bool visible) { 1994 void WebContentsImpl::OnRenderFrameProxyVisibilityChanged(bool visible) {
1995 if (visible && !GetOuterWebContents()->IsHidden()) 1995 if (visible && !GetOuterWebContents()->IsHidden())
1996 WasShown(); 1996 WasShown();
1997 else if (!visible) 1997 else if (!visible)
1998 WasHidden(); 1998 WasHidden();
1999 } 1999 }
2000 2000
2001 void WebContentsImpl::CreateNewWindow( 2001 void WebContentsImpl::CreateNewWindow(
2002 SiteInstance* source_site_instance, 2002 SiteInstance* source_site_instance,
2003 int32_t route_id, 2003 int32_t render_view_route_id,
2004 int32_t main_frame_route_id, 2004 int32_t main_frame_route_id,
2005 int32_t main_frame_widget_route_id, 2005 int32_t main_frame_widget_route_id,
2006 const mojom::CreateNewWindowParams& params, 2006 const mojom::CreateNewWindowParams& params,
2007 SessionStorageNamespace* session_storage_namespace) { 2007 SessionStorageNamespace* session_storage_namespace) {
2008 // We should have zero valid routing ids, or three valid routing IDs.
2009 DCHECK_EQ((render_view_route_id == MSG_ROUTING_NONE),
2010 (main_frame_route_id == MSG_ROUTING_NONE));
2011 DCHECK_EQ((render_view_route_id == MSG_ROUTING_NONE),
2012 (main_frame_widget_route_id == MSG_ROUTING_NONE));
2013
2014 int render_process_id = source_site_instance->GetProcess()->GetID();
2015 // The route IDs passed into this function can be trusted not to already be in
2016 // use; they were allocated by the RenderWidgetHelper on the IO thread.
2017 DCHECK(!RenderFrameHostImpl::FromID(render_process_id, main_frame_route_id));
2018
2008 // We usually create the new window in the same BrowsingInstance (group of 2019 // We usually create the new window in the same BrowsingInstance (group of
2009 // script-related windows), by passing in the current SiteInstance. However, 2020 // script-related windows), by passing in the current SiteInstance. However,
2010 // if the opener is being suppressed (in a non-guest), we create a new 2021 // if the opener is being suppressed (in a non-guest), we create a new
2011 // SiteInstance in its own BrowsingInstance. 2022 // SiteInstance in its own BrowsingInstance.
2012 bool is_guest = BrowserPluginGuest::IsGuest(this); 2023 bool is_guest = BrowserPluginGuest::IsGuest(this);
2013 2024
2014 // If the opener is to be suppressed, the new window can be in any process. 2025 // If the opener is to be suppressed, the new window can be in any process.
2015 // Since routing ids are process specific, we must not have one passed in 2026 // Since routing ids are process specific, we must not have one passed in
2016 // as argument here. 2027 // as argument here.
2017 DCHECK(!params.opener_suppressed || route_id == MSG_ROUTING_NONE); 2028 DCHECK(!params.opener_suppressed || render_view_route_id == MSG_ROUTING_NONE);
2018 2029
2019 scoped_refptr<SiteInstance> site_instance = 2030 scoped_refptr<SiteInstance> site_instance =
2020 params.opener_suppressed && !is_guest 2031 params.opener_suppressed && !is_guest
2021 ? SiteInstance::CreateForURL(GetBrowserContext(), params.target_url) 2032 ? SiteInstance::CreateForURL(GetBrowserContext(), params.target_url)
2022 : source_site_instance; 2033 : source_site_instance;
2023 2034
2024 // A message to create a new window can only come from a process for a frame
2025 // in this WebContents' FrameTree. If any other process sends the request, it
2026 // is invalid and the process must be terminated.
2027 int render_process_id = source_site_instance->GetProcess()->GetID();
2028 if (!HasMatchingProcess(&frame_tree_, render_process_id)) {
2029 RenderProcessHost* rph = source_site_instance->GetProcess();
2030 base::ProcessHandle process_handle = rph->GetHandle();
2031 if (process_handle != base::kNullProcessHandle) {
2032 RecordAction(
2033 base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWindow"));
2034 rph->Shutdown(RESULT_CODE_KILLED, false);
2035 }
2036 return;
2037 }
2038
2039 // We must assign the SessionStorageNamespace before calling Init(). 2035 // We must assign the SessionStorageNamespace before calling Init().
2040 // 2036 //
2041 // http://crbug.com/142685 2037 // http://crbug.com/142685
2042 const std::string& partition_id = 2038 const std::string& partition_id =
2043 GetContentClient()->browser()-> 2039 GetContentClient()->browser()->
2044 GetStoragePartitionIdForSite(GetBrowserContext(), 2040 GetStoragePartitionIdForSite(GetBrowserContext(),
2045 site_instance->GetSiteURL()); 2041 site_instance->GetSiteURL());
2046 StoragePartition* partition = BrowserContext::GetStoragePartition( 2042 StoragePartition* partition = BrowserContext::GetStoragePartition(
2047 GetBrowserContext(), site_instance.get()); 2043 GetBrowserContext(), site_instance.get());
2048 DOMStorageContextWrapper* dom_storage_context = 2044 DOMStorageContextWrapper* dom_storage_context =
2049 static_cast<DOMStorageContextWrapper*>(partition->GetDOMStorageContext()); 2045 static_cast<DOMStorageContextWrapper*>(partition->GetDOMStorageContext());
2050 SessionStorageNamespaceImpl* session_storage_namespace_impl = 2046 SessionStorageNamespaceImpl* session_storage_namespace_impl =
2051 static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace); 2047 static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace);
2052 CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context)); 2048 CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
2053 2049
2054 if (delegate_ && 2050 if (delegate_ &&
2055 !delegate_->ShouldCreateWebContents( 2051 !delegate_->ShouldCreateWebContents(
2056 this, source_site_instance, route_id, main_frame_route_id, 2052 this, source_site_instance, render_view_route_id, main_frame_route_id,
2057 main_frame_widget_route_id, params.window_container_type, 2053 main_frame_widget_route_id, params.window_container_type,
2058 params.opener_url, params.frame_name, params.target_url, partition_id, 2054 params.opener_url, params.frame_name, params.target_url, partition_id,
2059 session_storage_namespace)) { 2055 session_storage_namespace)) {
2060 if (route_id != MSG_ROUTING_NONE &&
2061 !RenderViewHost::FromID(render_process_id, route_id)) {
2062 // If the embedder didn't create a WebContents for this route, we need to
2063 // delete the RenderView that had already been created.
2064 Send(new ViewMsg_Close(route_id));
2065 }
2066 // Note: even though we're not creating a WebContents here, it could have 2056 // Note: even though we're not creating a WebContents here, it could have
2067 // been created by the embedder so ensure that the RenderFrameHost is 2057 // been created by the embedder so ensure that the RenderFrameHost is
2068 // properly initialized. 2058 // properly initialized.
2069 // It's safe to only target the frame because the render process will not 2059 // It's safe to only target the frame because the render process will not
2070 // have a chance to create more frames at this point. 2060 // have a chance to create more frames at this point.
2071 RenderFrameHostImpl* rfh = 2061 RenderFrameHostImpl* rfh =
2072 RenderFrameHostImpl::FromID(render_process_id, main_frame_route_id); 2062 RenderFrameHostImpl::FromID(render_process_id, main_frame_route_id);
2073 if (rfh) 2063 if (rfh) {
2064 DCHECK(rfh->IsRenderFrameLive());
2074 rfh->Init(); 2065 rfh->Init();
2066 }
2075 return; 2067 return;
2076 } 2068 }
2077 2069
2078 // Create the new web contents. This will automatically create the new 2070 // Create the new web contents. This will automatically create the new
2079 // WebContentsView. In the future, we may want to create the view separately. 2071 // WebContentsView. In the future, we may want to create the view separately.
2080 CreateParams create_params(GetBrowserContext(), site_instance.get()); 2072 CreateParams create_params(GetBrowserContext(), site_instance.get());
2081 create_params.routing_id = route_id; 2073 create_params.routing_id = render_view_route_id;
2082 create_params.main_frame_routing_id = main_frame_route_id; 2074 create_params.main_frame_routing_id = main_frame_route_id;
2083 create_params.main_frame_widget_routing_id = main_frame_widget_route_id; 2075 create_params.main_frame_widget_routing_id = main_frame_widget_route_id;
2084 create_params.main_frame_name = params.frame_name; 2076 create_params.main_frame_name = params.frame_name;
2085 create_params.opener_render_process_id = render_process_id; 2077 create_params.opener_render_process_id = render_process_id;
2086 create_params.opener_render_frame_id = params.opener_render_frame_id; 2078 create_params.opener_render_frame_id = params.opener_render_frame_id;
2087 create_params.opener_suppressed = params.opener_suppressed; 2079 create_params.opener_suppressed = params.opener_suppressed;
2088 if (params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB) 2080 if (params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB)
2089 create_params.initially_hidden = true; 2081 create_params.initially_hidden = true;
2090 create_params.renderer_initiated_creation = 2082 create_params.renderer_initiated_creation =
2091 main_frame_route_id != MSG_ROUTING_NONE; 2083 main_frame_route_id != MSG_ROUTING_NONE;
(...skipping 24 matching lines...) Expand all
2116 if (!is_guest) { 2108 if (!is_guest) {
2117 WebContentsView* new_view = new_contents->view_.get(); 2109 WebContentsView* new_view = new_contents->view_.get();
2118 2110
2119 // TODO(brettw): It seems bogus that we have to call this function on the 2111 // TODO(brettw): It seems bogus that we have to call this function on the
2120 // newly created object and give it one of its own member variables. 2112 // newly created object and give it one of its own member variables.
2121 new_view->CreateViewForWidget( 2113 new_view->CreateViewForWidget(
2122 new_contents->GetRenderViewHost()->GetWidget(), false); 2114 new_contents->GetRenderViewHost()->GetWidget(), false);
2123 } 2115 }
2124 // Save the created window associated with the route so we can show it 2116 // Save the created window associated with the route so we can show it
2125 // later. 2117 // later.
2126 DCHECK_NE(MSG_ROUTING_NONE, route_id); 2118 DCHECK_NE(MSG_ROUTING_NONE, main_frame_widget_route_id);
2127 pending_contents_[std::make_pair(render_process_id, route_id)] = 2119 pending_contents_[std::make_pair(
2128 new_contents; 2120 render_process_id, main_frame_widget_route_id)] = new_contents;
2129 AddDestructionObserver(new_contents); 2121 AddDestructionObserver(new_contents);
2130 } 2122 }
2131 2123
2132 if (delegate_) { 2124 if (delegate_) {
2133 delegate_->WebContentsCreated( 2125 delegate_->WebContentsCreated(
2134 this, render_process_id, params.opener_render_frame_id, 2126 this, render_process_id, params.opener_render_frame_id,
2135 params.frame_name, params.target_url, new_contents); 2127 params.frame_name, params.target_url, new_contents);
2136 } 2128 }
2137 2129
2138 if (params.opener_suppressed) { 2130 if (params.opener_suppressed) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2210 widget_view; 2202 widget_view;
2211 2203
2212 #if defined(OS_MACOSX) 2204 #if defined(OS_MACOSX)
2213 // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it 2205 // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it
2214 // to allow it to survive the trip without being hosted. 2206 // to allow it to survive the trip without being hosted.
2215 base::mac::NSObjectRetain(widget_view->GetNativeView()); 2207 base::mac::NSObjectRetain(widget_view->GetNativeView());
2216 #endif 2208 #endif
2217 } 2209 }
2218 2210
2219 void WebContentsImpl::ShowCreatedWindow(int process_id, 2211 void WebContentsImpl::ShowCreatedWindow(int process_id,
2220 int route_id, 2212 int main_frame_widget_route_id,
2221 WindowOpenDisposition disposition, 2213 WindowOpenDisposition disposition,
2222 const gfx::Rect& initial_rect, 2214 const gfx::Rect& initial_rect,
2223 bool user_gesture) { 2215 bool user_gesture) {
2224 WebContentsImpl* contents = GetCreatedWindow(process_id, route_id); 2216 WebContentsImpl* contents =
2217 GetCreatedWindow(process_id, main_frame_widget_route_id);
2225 if (contents) { 2218 if (contents) {
2226 WebContentsDelegate* delegate = GetDelegate(); 2219 WebContentsDelegate* delegate = GetDelegate();
2227 contents->is_resume_pending_ = true; 2220 contents->is_resume_pending_ = true;
2228 if (!delegate || delegate->ShouldResumeRequestsForCreatedWindow()) 2221 if (!delegate || delegate->ShouldResumeRequestsForCreatedWindow())
2229 contents->ResumeLoadingCreatedWebContents(); 2222 contents->ResumeLoadingCreatedWebContents();
2230 2223
2231 if (delegate) { 2224 if (delegate) {
2232 delegate->AddNewContents( 2225 delegate->AddNewContents(this, contents, disposition, initial_rect,
2233 this, contents, disposition, initial_rect, user_gesture, NULL); 2226 user_gesture, NULL);
2234 } 2227 }
2228
2229 RenderWidgetHostImpl* rwh = contents->GetMainFrame()->GetRenderWidgetHost();
2230 DCHECK_EQ(main_frame_widget_route_id, rwh->GetRoutingID());
2231 rwh->Send(new ViewMsg_Move_ACK(rwh->GetRoutingID()));
2235 } 2232 }
2236 } 2233 }
2237 2234
2238 void WebContentsImpl::ShowCreatedWidget(int process_id, 2235 void WebContentsImpl::ShowCreatedWidget(int process_id,
2239 int route_id, 2236 int route_id,
2240 const gfx::Rect& initial_rect) { 2237 const gfx::Rect& initial_rect) {
2241 ShowCreatedWidget(process_id, route_id, false, initial_rect); 2238 ShowCreatedWidget(process_id, route_id, false, initial_rect);
2242 } 2239 }
2243 2240
2244 void WebContentsImpl::ShowCreatedFullscreenWidget(int process_id, 2241 void WebContentsImpl::ShowCreatedFullscreenWidget(int process_id,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 render_widget_host_impl->set_allow_privileged_mouse_lock(is_fullscreen); 2288 render_widget_host_impl->set_allow_privileged_mouse_lock(is_fullscreen);
2292 2289
2293 #if defined(OS_MACOSX) 2290 #if defined(OS_MACOSX)
2294 // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's 2291 // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's
2295 // properly embedded (or purposefully ignored) we can release the retain we 2292 // properly embedded (or purposefully ignored) we can release the retain we
2296 // took in CreateNewWidget(). 2293 // took in CreateNewWidget().
2297 base::mac::NSObjectRelease(widget_host_view->GetNativeView()); 2294 base::mac::NSObjectRelease(widget_host_view->GetNativeView());
2298 #endif 2295 #endif
2299 } 2296 }
2300 2297
2301 WebContentsImpl* WebContentsImpl::GetCreatedWindow(int process_id, 2298 WebContentsImpl* WebContentsImpl::GetCreatedWindow(
2302 int route_id) { 2299 int process_id,
2303 auto iter = pending_contents_.find(std::make_pair(process_id, route_id)); 2300 int main_frame_widget_route_id) {
2301 auto key = std::make_pair(process_id, main_frame_widget_route_id);
2302 auto iter = pending_contents_.find(key);
2304 2303
2305 // Certain systems can block the creation of new windows. If we didn't succeed 2304 // Certain systems can block the creation of new windows. If we didn't succeed
2306 // in creating one, just return NULL. 2305 // in creating one, just return NULL.
2307 if (iter == pending_contents_.end()) 2306 if (iter == pending_contents_.end())
2308 return nullptr; 2307 return nullptr;
2309 2308
2310 WebContentsImpl* new_contents = iter->second; 2309 WebContentsImpl* new_contents = iter->second;
2311 pending_contents_.erase(std::make_pair(process_id, route_id)); 2310 pending_contents_.erase(key);
2312 RemoveDestructionObserver(new_contents); 2311 RemoveDestructionObserver(new_contents);
2313 2312
2314 // Don't initialize the guest WebContents immediately. 2313 // Don't initialize the guest WebContents immediately.
2315 if (BrowserPluginGuest::IsGuest(new_contents)) 2314 if (BrowserPluginGuest::IsGuest(new_contents))
2316 return new_contents; 2315 return new_contents;
2317 2316
2318 if (!new_contents->GetRenderProcessHost()->HasConnection() || 2317 if (!new_contents->GetMainFrame()->GetProcess()->HasConnection() ||
2319 !new_contents->GetRenderViewHost()->GetWidget()->GetView()) 2318 !new_contents->GetMainFrame()->GetView()) {
2319 // TODO(nick): http://crbug.com/674318 -- Who deletes |new_contents|?
2320 return nullptr; 2320 return nullptr;
2321 }
2321 2322
2322 return new_contents; 2323 return new_contents;
2323 } 2324 }
2324 2325
2325 RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id, 2326 RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id,
2326 int route_id) { 2327 int route_id) {
2327 auto iter = pending_widget_views_.find(std::make_pair(process_id, route_id)); 2328 auto iter = pending_widget_views_.find(std::make_pair(process_id, route_id));
2328 if (iter == pending_widget_views_.end()) { 2329 if (iter == pending_widget_views_.end()) {
2329 DCHECK(false); 2330 DCHECK(false);
2330 return nullptr; 2331 return nullptr;
(...skipping 3087 matching lines...) Expand 10 before | Expand all | Expand 10 after
5418 GetMainFrame()->AddMessageToConsole( 5419 GetMainFrame()->AddMessageToConsole(
5419 content::CONSOLE_MESSAGE_LEVEL_WARNING, 5420 content::CONSOLE_MESSAGE_LEVEL_WARNING,
5420 base::StringPrintf("This site does not have a valid SSL " 5421 base::StringPrintf("This site does not have a valid SSL "
5421 "certificate! Without SSL, your site's and " 5422 "certificate! Without SSL, your site's and "
5422 "visitors' data is vulnerable to theft and " 5423 "visitors' data is vulnerable to theft and "
5423 "tampering. Get a valid SSL certificate before" 5424 "tampering. Get a valid SSL certificate before"
5424 " releasing your website to the public.")); 5425 " releasing your website to the public."));
5425 } 5426 }
5426 5427
5427 } // namespace content 5428 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | content/browser/web_contents/web_contents_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698