OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |