OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <memory> | |
6 #include <utility> | |
7 | |
8 #include "base/memory/ptr_util.h" | |
9 #include "content/browser/dom_storage/dom_storage_context_wrapper.h" | |
10 #include "content/browser/dom_storage/session_storage_namespace_impl.h" | |
11 #include "content/browser/frame_host/render_frame_host_impl.h" | |
12 #include "content/browser/loader/resource_dispatcher_host_impl.h" | |
13 #include "content/browser/renderer_host/render_message_filter_ui.h" | |
14 #include "content/browser/renderer_host/render_process_host_impl.h" | |
15 #include "content/common/view_messages.h" | |
16 #include "content/public/browser/content_browser_client.h" | |
17 #include "content/public/browser/render_view_host.h" | |
18 #include "content/public/browser/render_widget_host.h" | |
19 #include "content/public/common/content_client.h" | |
20 #include "ipc/ipc_message.h" | |
21 #include "mojo/public/cpp/bindings/strong_associated_binding.h" | |
22 | |
23 namespace content { | |
24 | |
25 void RenderMessageFilterUI::CreateFilter( | |
26 RenderProcessHost* rph, | |
27 DOMStorageContextWrapper* dom_storage_context, | |
28 mojom::RenderMessageFilterUIAssociatedRequest request) { | |
29 mojo::MakeStrongAssociatedBinding( | |
30 base::MakeUnique<RenderMessageFilterUI>(rph, dom_storage_context), | |
31 std::move(request)); | |
32 } | |
33 | |
34 RenderMessageFilterUI::RenderMessageFilterUI( | |
35 RenderProcessHost* render_process_host, | |
36 DOMStorageContextWrapper* dom_storage_context) | |
37 : render_process_host_(render_process_host), | |
38 dom_storage_context_(dom_storage_context) {} | |
39 | |
40 RenderMessageFilterUI::~RenderMessageFilterUI() {} | |
41 | |
42 void RenderMessageFilterUI::CreateNewWindow( | |
43 mojom::CreateNewWindowParamsPtr params, | |
44 const CreateNewWindowCallback& callback) { | |
45 bool no_javascript_access = false; | |
46 int render_process_id = render_process_host_->GetID(); | |
47 | |
48 bool can_create_window = GetContentClient()->browser()->CanCreateWindow( | |
49 render_process_id, params->opener_render_frame_id, params->opener_url, | |
50 params->opener_top_level_frame_url, params->opener_security_origin, | |
51 params->window_container_type, params->target_url, params->referrer, | |
52 params->frame_name, params->disposition, *params->features, | |
53 params->user_gesture, params->opener_suppressed, &no_javascript_access); | |
54 | |
55 mojom::CreateNewWindowReplyPtr reply = mojom::CreateNewWindowReply::New(); | |
56 if (!can_create_window) { | |
57 RunCreateWindowCompleteCallback(callback, std::move(reply), | |
58 MSG_ROUTING_NONE, MSG_ROUTING_NONE, | |
59 MSG_ROUTING_NONE, 0); | |
60 return; | |
61 } | |
62 | |
63 // This will clone the sessionStorage for namespace_id_to_clone. | |
64 scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace = | |
65 new SessionStorageNamespaceImpl(dom_storage_context_.get(), | |
66 params->session_storage_namespace_id); | |
67 reply->cloned_session_storage_namespace_id = cloned_namespace->id(); | |
68 | |
69 int render_view_route_id = MSG_ROUTING_NONE; | |
70 int main_frame_route_id = MSG_ROUTING_NONE; | |
71 int main_frame_widget_route_id = MSG_ROUTING_NONE; | |
72 if (params->opener_suppressed || no_javascript_access) { | |
73 // If the opener is supppressed or script access is disallowed, we should | |
74 // open the window in a new BrowsingInstance, and thus a new process. That | |
75 // means the current renderer process will not be able to route messages to | |
76 // it. Because of this, we will immediately show and navigate the window | |
77 // in OnCreateNewWindowOnUI, using the params provided here. | |
78 } else { | |
79 render_view_route_id = render_process_host_->GetNextRoutingID(); | |
80 main_frame_route_id = render_process_host_->GetNextRoutingID(); | |
81 // TODO(avi): When RenderViewHostImpl has-a RenderWidgetHostImpl, this | |
82 // should be updated to give the widget a distinct routing ID. | |
83 // https://crbug.com/545684 | |
84 main_frame_widget_route_id = render_view_route_id; | |
85 // Block resource requests until the frame is created, since the HWND might | |
86 // be needed if a response ends up creating a plugin. We'll only have a | |
87 // single frame at this point. These requests will be resumed either in | |
88 // WebContentsImpl::CreateNewWindow or RenderFrameHost::Init. | |
89 auto block_requests_for_route = base::Bind( | |
90 [](const GlobalFrameRoutingId& id) { | |
91 auto* rdh = ResourceDispatcherHostImpl::Get(); | |
92 if (rdh) | |
93 rdh->BlockRequestsForRoute(id); | |
94 }, | |
95 GlobalFrameRoutingId(render_process_id, main_frame_route_id)); | |
96 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
97 block_requests_for_route); | |
alexmos
2017/04/17 19:41:08
Is this ok from race conditions point of view? I
Charlie Harrison
2017/04/17 20:10:52
I filed crbug.com/581037 a while ago trying to rip
alexmos
2017/04/19 22:28:02
Acknowledged. Thanks for adding a comment with th
| |
98 } | |
99 | |
100 RenderFrameHostImpl* opener = RenderFrameHostImpl::FromID( | |
101 render_process_id, params->opener_render_frame_id); | |
102 if (opener && opener->IsRenderFrameLive()) { | |
103 opener->OnCreateNewWindow(render_view_route_id, main_frame_route_id, | |
104 main_frame_widget_route_id, *params, | |
105 cloned_namespace.get()); | |
106 } | |
107 | |
108 // If we did not create a WebContents to host the renderer-created | |
109 // RenderFrame/RenderView/RenderWidget objects, destroy them. | |
110 if (main_frame_route_id != MSG_ROUTING_NONE) { | |
111 bool succeeded = | |
112 RenderWidgetHost::FromID(render_process_id, | |
113 main_frame_widget_route_id) != nullptr; | |
114 if (!succeeded) { | |
115 DCHECK(!RenderFrameHost::FromID(render_process_id, main_frame_route_id)); | |
116 DCHECK(!RenderViewHost::FromID(render_process_id, render_view_route_id)); | |
117 | |
118 render_process_host_->Send(new ViewMsg_Close(render_view_route_id)); | |
119 } else { | |
120 // If a RWH was created, there should also be an RFH and RVH. | |
121 DCHECK(RenderFrameHost::FromID(render_process_id, main_frame_route_id)); | |
122 DCHECK(RenderViewHost::FromID(render_process_id, render_view_route_id)); | |
123 } | |
124 } | |
125 RunCreateWindowCompleteCallback( | |
126 callback, std::move(reply), render_view_route_id, main_frame_route_id, | |
127 main_frame_widget_route_id, cloned_namespace->id()); | |
128 } | |
129 | |
130 void RenderMessageFilterUI::RunCreateWindowCompleteCallback( | |
131 const CreateNewWindowCallback& callback, | |
132 mojom::CreateNewWindowReplyPtr reply, | |
133 int render_view_route_id, | |
134 int main_frame_route_id, | |
135 int main_frame_widget_route_id, | |
136 int cloned_session_storage_namespace_id) { | |
137 reply->route_id = render_view_route_id; | |
138 reply->main_frame_route_id = main_frame_route_id; | |
139 reply->main_frame_widget_route_id = main_frame_widget_route_id; | |
140 reply->cloned_session_storage_namespace_id = | |
141 cloned_session_storage_namespace_id; | |
142 callback.Run(std::move(reply)); | |
143 } | |
144 | |
145 } // namespace content | |
OLD | NEW |