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

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

Issue 2506183002: Make window.open() IPCs be frame-based (Closed)
Patch Set: Compile fix. Created 4 years 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 1991 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 2002
2003 void WebContentsImpl::OnRenderFrameProxyVisibilityChanged(bool visible) { 2003 void WebContentsImpl::OnRenderFrameProxyVisibilityChanged(bool visible) {
2004 if (visible && !GetOuterWebContents()->IsHidden()) 2004 if (visible && !GetOuterWebContents()->IsHidden())
2005 WasShown(); 2005 WasShown();
2006 else if (!visible) 2006 else if (!visible)
2007 WasHidden(); 2007 WasHidden();
2008 } 2008 }
2009 2009
2010 void WebContentsImpl::CreateNewWindow( 2010 void WebContentsImpl::CreateNewWindow(
2011 SiteInstance* source_site_instance, 2011 SiteInstance* source_site_instance,
2012 int32_t route_id, 2012 int32_t render_view_route_id,
2013 int32_t main_frame_route_id, 2013 int32_t main_frame_route_id,
2014 int32_t main_frame_widget_route_id, 2014 int32_t main_frame_widget_route_id,
2015 const mojom::CreateNewWindowParams& params, 2015 const mojom::CreateNewWindowParams& params,
2016 SessionStorageNamespace* session_storage_namespace) { 2016 SessionStorageNamespace* session_storage_namespace) {
2017 int render_process_id = source_site_instance->GetProcess()->GetID();
2018 // The route IDs passed into this function can be trusted not to already be in
2019 // use; they were allocated by the RenderWidgetHelper on the IO thread.
2020 DCHECK(!RenderFrameHostImpl::FromID(render_process_id, main_frame_route_id));
2021
2017 // We usually create the new window in the same BrowsingInstance (group of 2022 // We usually create the new window in the same BrowsingInstance (group of
2018 // script-related windows), by passing in the current SiteInstance. However, 2023 // script-related windows), by passing in the current SiteInstance. However,
2019 // if the opener is being suppressed (in a non-guest), we create a new 2024 // if the opener is being suppressed (in a non-guest), we create a new
2020 // SiteInstance in its own BrowsingInstance. 2025 // SiteInstance in its own BrowsingInstance.
2021 bool is_guest = BrowserPluginGuest::IsGuest(this); 2026 bool is_guest = BrowserPluginGuest::IsGuest(this);
2022 2027
2023 // If the opener is to be suppressed, the new window can be in any process. 2028 // If the opener is to be suppressed, the new window can be in any process.
2024 // Since routing ids are process specific, we must not have one passed in 2029 // Since routing ids are process specific, we must not have one passed in
2025 // as argument here. 2030 // as argument here.
2026 DCHECK(!params.opener_suppressed || route_id == MSG_ROUTING_NONE); 2031 DCHECK(!params.opener_suppressed || render_view_route_id == MSG_ROUTING_NONE);
2027 2032
2028 scoped_refptr<SiteInstance> site_instance = 2033 scoped_refptr<SiteInstance> site_instance =
2029 params.opener_suppressed && !is_guest 2034 params.opener_suppressed && !is_guest
2030 ? SiteInstance::CreateForURL(GetBrowserContext(), params.target_url) 2035 ? SiteInstance::CreateForURL(GetBrowserContext(), params.target_url)
2031 : source_site_instance; 2036 : source_site_instance;
2032 2037
2033 // A message to create a new window can only come from a process for a frame
2034 // in this WebContents' FrameTree. If any other process sends the request, it
2035 // is invalid and the process must be terminated.
2036 int render_process_id = source_site_instance->GetProcess()->GetID();
2037 if (!HasMatchingProcess(&frame_tree_, render_process_id)) {
2038 RenderProcessHost* rph = source_site_instance->GetProcess();
2039 base::ProcessHandle process_handle = rph->GetHandle();
2040 if (process_handle != base::kNullProcessHandle) {
2041 RecordAction(
2042 base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWindow"));
2043 rph->Shutdown(RESULT_CODE_KILLED, false);
2044 }
2045 return;
2046 }
2047
2048 // We must assign the SessionStorageNamespace before calling Init(). 2038 // We must assign the SessionStorageNamespace before calling Init().
2049 // 2039 //
2050 // http://crbug.com/142685 2040 // http://crbug.com/142685
2051 const std::string& partition_id = 2041 const std::string& partition_id =
2052 GetContentClient()->browser()-> 2042 GetContentClient()->browser()->
2053 GetStoragePartitionIdForSite(GetBrowserContext(), 2043 GetStoragePartitionIdForSite(GetBrowserContext(),
2054 site_instance->GetSiteURL()); 2044 site_instance->GetSiteURL());
2055 StoragePartition* partition = BrowserContext::GetStoragePartition( 2045 StoragePartition* partition = BrowserContext::GetStoragePartition(
2056 GetBrowserContext(), site_instance.get()); 2046 GetBrowserContext(), site_instance.get());
2057 DOMStorageContextWrapper* dom_storage_context = 2047 DOMStorageContextWrapper* dom_storage_context =
2058 static_cast<DOMStorageContextWrapper*>(partition->GetDOMStorageContext()); 2048 static_cast<DOMStorageContextWrapper*>(partition->GetDOMStorageContext());
2059 SessionStorageNamespaceImpl* session_storage_namespace_impl = 2049 SessionStorageNamespaceImpl* session_storage_namespace_impl =
2060 static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace); 2050 static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace);
2061 CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context)); 2051 CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
2062 2052
2063 if (delegate_ && 2053 if (delegate_ &&
2064 !delegate_->ShouldCreateWebContents( 2054 !delegate_->ShouldCreateWebContents(
2065 this, source_site_instance, route_id, main_frame_route_id, 2055 this, source_site_instance, render_view_route_id, main_frame_route_id,
2066 main_frame_widget_route_id, params.window_container_type, 2056 main_frame_widget_route_id, params.window_container_type,
2067 params.opener_url, params.frame_name, params.target_url, partition_id, 2057 params.opener_url, params.frame_name, params.target_url, partition_id,
2068 session_storage_namespace)) { 2058 session_storage_namespace)) {
2069 if (route_id != MSG_ROUTING_NONE &&
2070 !RenderViewHost::FromID(render_process_id, route_id)) {
2071 // If the embedder didn't create a WebContents for this route, we need to
2072 // delete the RenderView that had already been created.
2073 Send(new ViewMsg_Close(route_id));
2074 }
2075 // Note: even though we're not creating a WebContents here, it could have 2059 // Note: even though we're not creating a WebContents here, it could have
2076 // been created by the embedder so ensure that the RenderFrameHost is 2060 // been created by the embedder so ensure that the RenderFrameHost is
2077 // properly initialized. 2061 // properly initialized.
2078 // It's safe to only target the frame because the render process will not 2062 // It's safe to only target the frame because the render process will not
2079 // have a chance to create more frames at this point. 2063 // have a chance to create more frames at this point.
2080 RenderFrameHostImpl* rfh = 2064 RenderFrameHostImpl* rfh =
2081 RenderFrameHostImpl::FromID(render_process_id, main_frame_route_id); 2065 RenderFrameHostImpl::FromID(render_process_id, main_frame_route_id);
2082 if (rfh) 2066 if (rfh) {
2067 DCHECK(rfh->IsRenderFrameLive());
2083 rfh->Init(); 2068 rfh->Init();
2069 }
2084 return; 2070 return;
2085 } 2071 }
2086 2072
2087 // Create the new web contents. This will automatically create the new 2073 // Create the new web contents. This will automatically create the new
2088 // WebContentsView. In the future, we may want to create the view separately. 2074 // WebContentsView. In the future, we may want to create the view separately.
2089 CreateParams create_params(GetBrowserContext(), site_instance.get()); 2075 CreateParams create_params(GetBrowserContext(), site_instance.get());
2090 create_params.routing_id = route_id; 2076 create_params.routing_id = render_view_route_id;
alexmos 2016/12/13 18:41:41 Something random and not for this CL, but it'd be
ncarter (slow) 2016/12/15 00:33:16 Acknowledged.
2091 create_params.main_frame_routing_id = main_frame_route_id; 2077 create_params.main_frame_routing_id = main_frame_route_id;
2092 create_params.main_frame_widget_routing_id = main_frame_widget_route_id; 2078 create_params.main_frame_widget_routing_id = main_frame_widget_route_id;
2093 create_params.main_frame_name = params.frame_name; 2079 create_params.main_frame_name = params.frame_name;
2094 create_params.opener_render_process_id = render_process_id; 2080 create_params.opener_render_process_id = render_process_id;
2095 create_params.opener_render_frame_id = params.opener_render_frame_id; 2081 create_params.opener_render_frame_id = params.opener_render_frame_id;
2096 create_params.opener_suppressed = params.opener_suppressed; 2082 create_params.opener_suppressed = params.opener_suppressed;
2097 if (params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB) 2083 if (params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB)
2098 create_params.initially_hidden = true; 2084 create_params.initially_hidden = true;
2099 create_params.renderer_initiated_creation = 2085 create_params.renderer_initiated_creation =
2100 main_frame_route_id != MSG_ROUTING_NONE; 2086 main_frame_route_id != MSG_ROUTING_NONE;
(...skipping 24 matching lines...) Expand all
2125 if (!is_guest) { 2111 if (!is_guest) {
2126 WebContentsView* new_view = new_contents->view_.get(); 2112 WebContentsView* new_view = new_contents->view_.get();
2127 2113
2128 // TODO(brettw): It seems bogus that we have to call this function on the 2114 // TODO(brettw): It seems bogus that we have to call this function on the
2129 // newly created object and give it one of its own member variables. 2115 // newly created object and give it one of its own member variables.
2130 new_view->CreateViewForWidget( 2116 new_view->CreateViewForWidget(
2131 new_contents->GetRenderViewHost()->GetWidget(), false); 2117 new_contents->GetRenderViewHost()->GetWidget(), false);
2132 } 2118 }
2133 // Save the created window associated with the route so we can show it 2119 // Save the created window associated with the route so we can show it
2134 // later. 2120 // later.
2135 DCHECK_NE(MSG_ROUTING_NONE, route_id); 2121 DCHECK_NE(MSG_ROUTING_NONE, main_frame_widget_route_id);
2136 pending_contents_[std::make_pair(render_process_id, route_id)] = 2122 pending_contents_[std::make_pair(
2137 new_contents; 2123 render_process_id, main_frame_widget_route_id)] = new_contents;
2138 AddDestructionObserver(new_contents); 2124 AddDestructionObserver(new_contents);
2139 } 2125 }
2140 2126
2141 if (delegate_) { 2127 if (delegate_) {
2142 delegate_->WebContentsCreated( 2128 delegate_->WebContentsCreated(
2143 this, render_process_id, params.opener_render_frame_id, 2129 this, render_process_id, params.opener_render_frame_id,
2144 params.frame_name, params.target_url, new_contents); 2130 params.frame_name, params.target_url, new_contents);
2145 } 2131 }
2146 2132
2147 if (params.opener_suppressed) { 2133 if (params.opener_suppressed) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 widget_view; 2205 widget_view;
2220 2206
2221 #if defined(OS_MACOSX) 2207 #if defined(OS_MACOSX)
2222 // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it 2208 // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it
2223 // to allow it to survive the trip without being hosted. 2209 // to allow it to survive the trip without being hosted.
2224 base::mac::NSObjectRetain(widget_view->GetNativeView()); 2210 base::mac::NSObjectRetain(widget_view->GetNativeView());
2225 #endif 2211 #endif
2226 } 2212 }
2227 2213
2228 void WebContentsImpl::ShowCreatedWindow(int process_id, 2214 void WebContentsImpl::ShowCreatedWindow(int process_id,
2229 int route_id, 2215 int main_frame_widget_route_id,
2230 WindowOpenDisposition disposition, 2216 WindowOpenDisposition disposition,
2231 const gfx::Rect& initial_rect, 2217 const gfx::Rect& initial_rect,
2232 bool user_gesture) { 2218 bool user_gesture) {
2233 WebContentsImpl* contents = GetCreatedWindow(process_id, route_id); 2219 WebContentsImpl* contents =
2220 GetCreatedWindow(process_id, main_frame_widget_route_id);
2234 if (contents) { 2221 if (contents) {
2235 WebContentsDelegate* delegate = GetDelegate(); 2222 WebContentsDelegate* delegate = GetDelegate();
2236 contents->is_resume_pending_ = true; 2223 contents->is_resume_pending_ = true;
2237 if (!delegate || delegate->ShouldResumeRequestsForCreatedWindow()) 2224 if (!delegate || delegate->ShouldResumeRequestsForCreatedWindow())
2238 contents->ResumeLoadingCreatedWebContents(); 2225 contents->ResumeLoadingCreatedWebContents();
2239 2226
2240 if (delegate) { 2227 if (delegate) {
2241 delegate->AddNewContents( 2228 delegate->AddNewContents(this, contents, disposition, initial_rect,
2242 this, contents, disposition, initial_rect, user_gesture, NULL); 2229 user_gesture, NULL);
2243 } 2230 }
2231
2232 RenderWidgetHostImpl* rwh = contents->GetMainFrame()->GetRenderWidgetHost();
2233 DCHECK_EQ(main_frame_widget_route_id, rwh->GetRoutingID());
2234 rwh->Send(new ViewMsg_Move_ACK(rwh->GetRoutingID()));
2244 } 2235 }
2245 } 2236 }
2246 2237
2247 void WebContentsImpl::ShowCreatedWidget(int process_id, 2238 void WebContentsImpl::ShowCreatedWidget(int process_id,
2248 int route_id, 2239 int route_id,
2249 const gfx::Rect& initial_rect) { 2240 const gfx::Rect& initial_rect) {
2250 ShowCreatedWidget(process_id, route_id, false, initial_rect); 2241 ShowCreatedWidget(process_id, route_id, false, initial_rect);
2251 } 2242 }
2252 2243
2253 void WebContentsImpl::ShowCreatedFullscreenWidget(int process_id, 2244 void WebContentsImpl::ShowCreatedFullscreenWidget(int process_id,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2300 render_widget_host_impl->set_allow_privileged_mouse_lock(is_fullscreen); 2291 render_widget_host_impl->set_allow_privileged_mouse_lock(is_fullscreen);
2301 2292
2302 #if defined(OS_MACOSX) 2293 #if defined(OS_MACOSX)
2303 // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's 2294 // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's
2304 // properly embedded (or purposefully ignored) we can release the retain we 2295 // properly embedded (or purposefully ignored) we can release the retain we
2305 // took in CreateNewWidget(). 2296 // took in CreateNewWidget().
2306 base::mac::NSObjectRelease(widget_host_view->GetNativeView()); 2297 base::mac::NSObjectRelease(widget_host_view->GetNativeView());
2307 #endif 2298 #endif
2308 } 2299 }
2309 2300
2310 WebContentsImpl* WebContentsImpl::GetCreatedWindow(int process_id, 2301 WebContentsImpl* WebContentsImpl::GetCreatedWindow(
2311 int route_id) { 2302 int process_id,
2312 auto iter = pending_contents_.find(std::make_pair(process_id, route_id)); 2303 int main_frame_widget_route_id) {
2304 auto key = std::make_pair(process_id, main_frame_widget_route_id);
2305 auto iter = pending_contents_.find(key);
2313 2306
2314 // Certain systems can block the creation of new windows. If we didn't succeed 2307 // Certain systems can block the creation of new windows. If we didn't succeed
2315 // in creating one, just return NULL. 2308 // in creating one, just return NULL.
2316 if (iter == pending_contents_.end()) 2309 if (iter == pending_contents_.end())
2317 return nullptr; 2310 return nullptr;
2318 2311
2319 WebContentsImpl* new_contents = iter->second; 2312 WebContentsImpl* new_contents = iter->second;
2320 pending_contents_.erase(std::make_pair(process_id, route_id)); 2313 pending_contents_.erase(key);
2321 RemoveDestructionObserver(new_contents); 2314 RemoveDestructionObserver(new_contents);
2322 2315
2323 // Don't initialize the guest WebContents immediately. 2316 // Don't initialize the guest WebContents immediately.
2324 if (BrowserPluginGuest::IsGuest(new_contents)) 2317 if (BrowserPluginGuest::IsGuest(new_contents))
2325 return new_contents; 2318 return new_contents;
2326 2319
2327 if (!new_contents->GetRenderProcessHost()->HasConnection() || 2320 if (!new_contents->GetMainFrame()->GetProcess()->HasConnection() ||
alexmos 2016/12/13 18:41:41 Thanks for cleaning these up!
ncarter (slow) 2016/12/15 00:33:17 Done.
2328 !new_contents->GetRenderViewHost()->GetWidget()->GetView()) 2321 !new_contents->GetMainFrame()->GetView()) {
2322 // TODO(nick): Who deletes |new_contents|?
alexmos 2016/12/13 18:41:41 Good point, I don't see who deletes it either. So
ncarter (slow) 2016/12/15 00:33:16 I filed a bug & left a breadcrumb here. The second
alexmos 2016/12/15 18:36:48 Acknowledged. Good find with the close case.
2329 return nullptr; 2323 return nullptr;
2324 }
2330 2325
2331 return new_contents; 2326 return new_contents;
2332 } 2327 }
2333 2328
2334 RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id, 2329 RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id,
2335 int route_id) { 2330 int route_id) {
2336 auto iter = pending_widget_views_.find(std::make_pair(process_id, route_id)); 2331 auto iter = pending_widget_views_.find(std::make_pair(process_id, route_id));
2337 if (iter == pending_widget_views_.end()) { 2332 if (iter == pending_widget_views_.end()) {
2338 DCHECK(false); 2333 DCHECK(false);
2339 return nullptr; 2334 return nullptr;
(...skipping 2940 matching lines...) Expand 10 before | Expand all | Expand 10 after
5280 dialog_manager_ = dialog_manager; 5275 dialog_manager_ = dialog_manager;
5281 } 5276 }
5282 5277
5283 void WebContentsImpl::RemoveBindingSet(const std::string& interface_name) { 5278 void WebContentsImpl::RemoveBindingSet(const std::string& interface_name) {
5284 auto it = binding_sets_.find(interface_name); 5279 auto it = binding_sets_.find(interface_name);
5285 if (it != binding_sets_.end()) 5280 if (it != binding_sets_.end())
5286 binding_sets_.erase(it); 5281 binding_sets_.erase(it);
5287 } 5282 }
5288 5283
5289 } // namespace content 5284 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698