sandbox/linux/bpf_dsl: eliminate implicit dependency on C++ compiler behavior
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_helper.cc
blob51f5e3abe9ec0cd54d3fdd760bd85f16f274b4ac
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
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/render_widget_helper.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/lazy_instance.h"
10 #include "base/posix/eintr_wrapper.h"
11 #include "base/threading/thread.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
14 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
15 #include "content/browser/gpu/gpu_surface_tracker.h"
16 #include "content/browser/loader/resource_dispatcher_host_impl.h"
17 #include "content/browser/renderer_host/render_process_host_impl.h"
18 #include "content/browser/renderer_host/render_view_host_impl.h"
19 #include "content/common/view_messages.h"
21 namespace content {
22 namespace {
24 typedef std::map<int, RenderWidgetHelper*> WidgetHelperMap;
25 base::LazyInstance<WidgetHelperMap> g_widget_helpers =
26 LAZY_INSTANCE_INITIALIZER;
28 void AddWidgetHelper(int render_process_id,
29 const scoped_refptr<RenderWidgetHelper>& widget_helper) {
30 DCHECK_CURRENTLY_ON(BrowserThread::IO);
31 // We don't care if RenderWidgetHelpers overwrite an existing process_id. Just
32 // want this to be up to date.
33 g_widget_helpers.Get()[render_process_id] = widget_helper.get();
36 } // namespace
38 RenderWidgetHelper::RenderWidgetHelper()
39 : render_process_id_(-1),
40 resource_dispatcher_host_(NULL) {
43 RenderWidgetHelper::~RenderWidgetHelper() {
44 DCHECK_CURRENTLY_ON(BrowserThread::IO);
46 // Delete this RWH from the map if it is found.
47 WidgetHelperMap& widget_map = g_widget_helpers.Get();
48 WidgetHelperMap::iterator it = widget_map.find(render_process_id_);
49 if (it != widget_map.end() && it->second == this)
50 widget_map.erase(it);
53 void RenderWidgetHelper::Init(
54 int render_process_id,
55 ResourceDispatcherHostImpl* resource_dispatcher_host) {
56 render_process_id_ = render_process_id;
57 resource_dispatcher_host_ = resource_dispatcher_host;
59 BrowserThread::PostTask(
60 BrowserThread::IO, FROM_HERE,
61 base::Bind(&AddWidgetHelper,
62 render_process_id_, make_scoped_refptr(this)));
65 int RenderWidgetHelper::GetNextRoutingID() {
66 return next_routing_id_.GetNext() + 1;
69 // static
70 RenderWidgetHelper* RenderWidgetHelper::FromProcessHostID(
71 int render_process_host_id) {
72 DCHECK_CURRENTLY_ON(BrowserThread::IO);
73 WidgetHelperMap::const_iterator ci = g_widget_helpers.Get().find(
74 render_process_host_id);
75 return (ci == g_widget_helpers.Get().end())? NULL : ci->second;
78 void RenderWidgetHelper::ResumeDeferredNavigation(
79 const GlobalRequestID& request_id) {
80 BrowserThread::PostTask(
81 BrowserThread::IO, FROM_HERE,
82 base::Bind(&RenderWidgetHelper::OnResumeDeferredNavigation,
83 this,
84 request_id));
87 void RenderWidgetHelper::ResumeRequestsForView(int route_id) {
88 // We only need to resume blocked requests if we used a valid route_id.
89 // See CreateNewWindow.
90 if (route_id != MSG_ROUTING_NONE) {
91 BrowserThread::PostTask(
92 BrowserThread::IO, FROM_HERE,
93 base::Bind(&RenderWidgetHelper::OnResumeRequestsForView,
94 this, route_id));
98 void RenderWidgetHelper::OnResumeDeferredNavigation(
99 const GlobalRequestID& request_id) {
100 resource_dispatcher_host_->ResumeDeferredNavigation(request_id);
103 void RenderWidgetHelper::CreateNewWindow(
104 const ViewHostMsg_CreateWindow_Params& params,
105 bool no_javascript_access,
106 base::ProcessHandle render_process,
107 int* route_id,
108 int* main_frame_route_id,
109 int* surface_id,
110 SessionStorageNamespace* session_storage_namespace) {
111 if (params.opener_suppressed || no_javascript_access) {
112 // If the opener is supppressed or script access is disallowed, we should
113 // open the window in a new BrowsingInstance, and thus a new process. That
114 // means the current renderer process will not be able to route messages to
115 // it. Because of this, we will immediately show and navigate the window
116 // in OnCreateWindowOnUI, using the params provided here.
117 *route_id = MSG_ROUTING_NONE;
118 *main_frame_route_id = MSG_ROUTING_NONE;
119 *surface_id = 0;
120 } else {
121 *route_id = GetNextRoutingID();
122 *main_frame_route_id = GetNextRoutingID();
123 *surface_id = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
124 render_process_id_, *route_id);
125 // Block resource requests until the view is created, since the HWND might
126 // be needed if a response ends up creating a plugin.
127 resource_dispatcher_host_->BlockRequestsForRoute(
128 render_process_id_, *route_id);
129 resource_dispatcher_host_->BlockRequestsForRoute(
130 render_process_id_, *main_frame_route_id);
133 BrowserThread::PostTask(
134 BrowserThread::UI, FROM_HERE,
135 base::Bind(&RenderWidgetHelper::OnCreateWindowOnUI,
136 this, params, *route_id, *main_frame_route_id,
137 make_scoped_refptr(session_storage_namespace)));
140 void RenderWidgetHelper::OnCreateWindowOnUI(
141 const ViewHostMsg_CreateWindow_Params& params,
142 int route_id,
143 int main_frame_route_id,
144 SessionStorageNamespace* session_storage_namespace) {
145 RenderViewHostImpl* host =
146 RenderViewHostImpl::FromID(render_process_id_, params.opener_id);
147 if (host)
148 host->CreateNewWindow(route_id, main_frame_route_id, params,
149 session_storage_namespace);
152 void RenderWidgetHelper::OnResumeRequestsForView(int route_id) {
153 resource_dispatcher_host_->ResumeBlockedRequestsForRoute(
154 render_process_id_, route_id);
157 void RenderWidgetHelper::CreateNewWidget(int opener_id,
158 blink::WebPopupType popup_type,
159 int* route_id,
160 int* surface_id) {
161 *route_id = GetNextRoutingID();
162 *surface_id = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
163 render_process_id_, *route_id);
164 BrowserThread::PostTask(
165 BrowserThread::UI, FROM_HERE,
166 base::Bind(&RenderWidgetHelper::OnCreateWidgetOnUI, this, opener_id,
167 *route_id, *surface_id, popup_type));
170 void RenderWidgetHelper::CreateNewFullscreenWidget(int opener_id,
171 int* route_id,
172 int* surface_id) {
173 *route_id = GetNextRoutingID();
174 *surface_id = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
175 render_process_id_, *route_id);
176 BrowserThread::PostTask(
177 BrowserThread::UI, FROM_HERE,
178 base::Bind(&RenderWidgetHelper::OnCreateFullscreenWidgetOnUI, this,
179 opener_id, *route_id, *surface_id));
182 void RenderWidgetHelper::OnCreateWidgetOnUI(int32 opener_id,
183 int32 route_id,
184 int32 surface_id,
185 blink::WebPopupType popup_type) {
186 RenderViewHostImpl* host = RenderViewHostImpl::FromID(
187 render_process_id_, opener_id);
188 if (host)
189 host->CreateNewWidget(route_id, surface_id, popup_type);
192 void RenderWidgetHelper::OnCreateFullscreenWidgetOnUI(int32 opener_id,
193 int32 route_id,
194 int32 surface_id) {
195 RenderViewHostImpl* host = RenderViewHostImpl::FromID(
196 render_process_id_, opener_id);
197 if (host)
198 host->CreateNewFullscreenWidget(route_id, surface_id);
201 } // namespace content