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

Side by Side Diff: content/browser/browser_plugin/browser_plugin_embedder.cc

Issue 11748034: Browser Plugin: Refactor BrowserPluginEmbedder to allow creating guests with openers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed nits Created 7 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 | Annotate | Revision Log
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/browser_plugin/browser_plugin_embedder.h" 5 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
6 6
7 #include "base/stl_util.h" 7 #include "base/stl_util.h"
8 #include "content/browser/browser_plugin/browser_plugin_guest.h" 8 #include "content/browser/browser_plugin/browser_plugin_guest.h"
9 #include "content/browser/browser_plugin/browser_plugin_host_factory.h" 9 #include "content/browser/browser_plugin/browser_plugin_host_factory.h"
10 #include "content/browser/renderer_host/render_view_host_impl.h" 10 #include "content/browser/renderer_host/render_view_host_impl.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 BrowserPluginEmbedder* BrowserPluginEmbedder::Create( 47 BrowserPluginEmbedder* BrowserPluginEmbedder::Create(
48 WebContentsImpl* web_contents, 48 WebContentsImpl* web_contents,
49 content::RenderViewHost* render_view_host) { 49 content::RenderViewHost* render_view_host) {
50 if (factory_) { 50 if (factory_) {
51 return factory_->CreateBrowserPluginEmbedder(web_contents, 51 return factory_->CreateBrowserPluginEmbedder(web_contents,
52 render_view_host); 52 render_view_host);
53 } 53 }
54 return new BrowserPluginEmbedder(web_contents, render_view_host); 54 return new BrowserPluginEmbedder(web_contents, render_view_host);
55 } 55 }
56 56
57 void BrowserPluginEmbedder::CreateGuest(
58 int instance_id,
59 int routing_id,
60 BrowserPluginGuest* guest_opener,
61 const BrowserPluginHostMsg_CreateGuest_Params& params) {
62 WebContentsImpl* guest_web_contents = NULL;
63 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
64 CHECK(!guest);
65
66 // Validate that the partition id coming from the renderer is valid UTF-8,
67 // since we depend on this in other parts of the code, such as FilePath
68 // creation. If the validation fails, treat it as a bad message and kill the
69 // renderer process.
70 if (!IsStringUTF8(params.storage_partition_id)) {
71 content::RecordAction(UserMetricsAction("BadMessageTerminate_BPE"));
72 base::KillProcess(render_view_host_->GetProcess()->GetHandle(),
73 content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
74 return;
75 }
76
77 const std::string& host =
78 render_view_host_->GetSiteInstance()->GetSiteURL().host();
79 std::string url_encoded_partition = net::EscapeQueryParamValue(
80 params.storage_partition_id, false);
81
82 SiteInstance* guest_site_instance = NULL;
83 if (guest_opener) {
84 guest_site_instance = guest_opener->GetWebContents()->GetSiteInstance();
85 } else {
86 // The SiteInstance of a given webview tag is based on the fact that it's a
87 // guest process in addition to which platform application the tag belongs
88 // to and what storage partition is in use, rather than the URL that the tag
89 // is being navigated to.
90 GURL guest_site(
91 base::StringPrintf("%s://%s/%s?%s", chrome::kGuestScheme,
92 host.c_str(), params.persist_storage ? "persist" : "",
93 url_encoded_partition.c_str()));
94
95 // If we already have a webview tag in the same app using the same storage
96 // partition, we should use the same SiteInstance so the existing tag and
97 // the new tag can script each other.
98 for (ContainerInstanceMap::const_iterator it =
99 guest_web_contents_by_instance_id_.begin();
100 it != guest_web_contents_by_instance_id_.end(); ++it) {
101 if (it->second->GetSiteInstance()->GetSiteURL() == guest_site) {
102 guest_site_instance = it->second->GetSiteInstance();
103 break;
104 }
105 }
106 if (!guest_site_instance) {
107 // Create the SiteInstance in a new BrowsingInstance, which will ensure
108 // that webview tags are also not allowed to send messages across
109 // different partitions.
110 guest_site_instance = SiteInstance::CreateForURL(
111 web_contents()->GetBrowserContext(), guest_site);
112 }
113 }
114 WebContentsImpl* opener_web_contents = static_cast<WebContentsImpl*>(
115 guest_opener ? guest_opener->GetWebContents() : NULL);
116 guest_web_contents = WebContentsImpl::CreateGuest(
117 web_contents()->GetBrowserContext(),
118 guest_site_instance,
119 routing_id,
120 opener_web_contents,
121 instance_id,
122 params);
123
124 guest = guest_web_contents->GetBrowserPluginGuest();
125 guest->set_embedder_web_contents(
126 static_cast<WebContentsImpl*>(web_contents()));
127
128 RendererPreferences* guest_renderer_prefs =
129 guest_web_contents->GetMutableRendererPrefs();
130 // Copy renderer preferences (and nothing else) from the embedder's
131 // TabContents to the guest.
132 //
133 // For GTK and Aura this is necessary to get proper renderer configuration
134 // values for caret blinking interval, colors related to selection and
135 // focus.
136 *guest_renderer_prefs = *web_contents()->GetMutableRendererPrefs();
137
138 guest_renderer_prefs->throttle_input_events = false;
139 // Navigation is disabled in Chrome Apps. We want to make sure guest-initiated
140 // navigations still continue to function inside the app.
141 guest_renderer_prefs->browser_handles_all_top_level_requests = false;
142 AddGuest(instance_id, guest_web_contents);
143 guest_web_contents->SetDelegate(guest);
144
145 // Create a swapped out RenderView for the guest in the embedder render
146 // process, so that the embedder can access the guest's window object.
147 int guest_routing_id =
148 static_cast<WebContentsImpl*>(guest->GetWebContents())->
149 CreateSwappedOutRenderView(web_contents()->GetSiteInstance());
150 render_view_host_->Send(new BrowserPluginMsg_GuestContentWindowReady(
151 render_view_host_->GetRoutingID(), instance_id, guest_routing_id));
152
153 guest->Initialize(params, guest_web_contents->GetRenderViewHost());
154 }
155
156 BrowserPluginGuest* BrowserPluginEmbedder::GetGuestByInstanceID(
157 int instance_id) const {
158 ContainerInstanceMap::const_iterator it =
159 guest_web_contents_by_instance_id_.find(instance_id);
160 if (it != guest_web_contents_by_instance_id_.end())
161 return static_cast<WebContentsImpl*>(it->second)->GetBrowserPluginGuest();
162 return NULL;
163 }
164
165 void BrowserPluginEmbedder::DestroyGuestByInstanceID(int instance_id) {
166 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
167 if (guest) {
168 WebContents* guest_web_contents = guest->GetWebContents();
169
170 // Destroy the guest's web_contents.
171 delete guest_web_contents;
172 guest_web_contents_by_instance_id_.erase(instance_id);
173 }
174 }
175
57 void BrowserPluginEmbedder::GetRenderViewHostAtPosition( 176 void BrowserPluginEmbedder::GetRenderViewHostAtPosition(
58 int x, int y, const WebContents::GetRenderViewHostCallback& callback) { 177 int x, int y, const WebContents::GetRenderViewHostCallback& callback) {
59 // Store the callback so we can call it later when we have the response. 178 // Store the callback so we can call it later when we have the response.
60 pending_get_render_view_callbacks_.insert( 179 pending_get_render_view_callbacks_.insert(
61 std::make_pair(next_get_render_view_request_id_, callback)); 180 std::make_pair(next_get_render_view_request_id_, callback));
62 render_view_host_->Send( 181 render_view_host_->Send(
63 new BrowserPluginMsg_PluginAtPositionRequest( 182 new BrowserPluginMsg_PluginAtPositionRequest(
64 render_view_host_->GetRoutingID(), 183 render_view_host_->GetRoutingID(),
65 next_get_render_view_request_id_, 184 next_get_render_view_request_id_,
66 gfx::Point(x, y))); 185 gfx::Point(x, y)));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 case NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED: { 229 case NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED: {
111 bool visible = *Details<bool>(details).ptr(); 230 bool visible = *Details<bool>(details).ptr();
112 WebContentsVisibilityChanged(visible); 231 WebContentsVisibilityChanged(visible);
113 break; 232 break;
114 } 233 }
115 default: 234 default:
116 NOTREACHED() << "Unexpected notification type: " << type; 235 NOTREACHED() << "Unexpected notification type: " << type;
117 } 236 }
118 } 237 }
119 238
120 BrowserPluginGuest* BrowserPluginEmbedder::GetGuestByInstanceID(
121 int instance_id) const {
122 ContainerInstanceMap::const_iterator it =
123 guest_web_contents_by_instance_id_.find(instance_id);
124 if (it != guest_web_contents_by_instance_id_.end())
125 return static_cast<WebContentsImpl*>(it->second)->GetBrowserPluginGuest();
126 return NULL;
127 }
128
129 void BrowserPluginEmbedder::AddGuest(int instance_id, 239 void BrowserPluginEmbedder::AddGuest(int instance_id,
130 WebContents* guest_web_contents) { 240 WebContents* guest_web_contents) {
131 DCHECK(guest_web_contents_by_instance_id_.find(instance_id) == 241 DCHECK(guest_web_contents_by_instance_id_.find(instance_id) ==
132 guest_web_contents_by_instance_id_.end()); 242 guest_web_contents_by_instance_id_.end());
133 guest_web_contents_by_instance_id_[instance_id] = guest_web_contents; 243 guest_web_contents_by_instance_id_[instance_id] = guest_web_contents;
134 } 244 }
135 245
136 void BrowserPluginEmbedder::DestroyGuestByInstanceID(int instance_id) {
137 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
138 if (guest) {
139 WebContents* guest_web_contents = guest->GetWebContents();
140
141 // Destroy the guest's web_contents.
142 delete guest_web_contents;
143 guest_web_contents_by_instance_id_.erase(instance_id);
144 }
145 }
146
147 void BrowserPluginEmbedder::CleanUp() { 246 void BrowserPluginEmbedder::CleanUp() {
148 // Destroy guests that are managed by the current embedder. 247 // Destroy guests that are managed by the current embedder.
149 STLDeleteContainerPairSecondPointers( 248 STLDeleteContainerPairSecondPointers(
150 guest_web_contents_by_instance_id_.begin(), 249 guest_web_contents_by_instance_id_.begin(),
151 guest_web_contents_by_instance_id_.end()); 250 guest_web_contents_by_instance_id_.end());
152 guest_web_contents_by_instance_id_.clear(); 251 guest_web_contents_by_instance_id_.clear();
153 252
154 // CleanUp gets called when BrowserPluginEmbedder's WebContents goes away 253 // CleanUp gets called when BrowserPluginEmbedder's WebContents goes away
155 // or the associated RenderViewHost is destroyed or swapped out. Therefore we 254 // or the associated RenderViewHost is destroyed or swapped out. Therefore we
156 // don't need to care about the pending callbacks anymore. 255 // don't need to care about the pending callbacks anymore.
(...skipping 30 matching lines...) Expand all
187 return true; 286 return true;
188 default: 287 default:
189 break; 288 break;
190 } 289 }
191 return false; 290 return false;
192 } 291 }
193 292
194 void BrowserPluginEmbedder::OnCreateGuest( 293 void BrowserPluginEmbedder::OnCreateGuest(
195 int instance_id, 294 int instance_id,
196 const BrowserPluginHostMsg_CreateGuest_Params& params) { 295 const BrowserPluginHostMsg_CreateGuest_Params& params) {
197 WebContentsImpl* guest_web_contents = NULL; 296 CreateGuest(instance_id, MSG_ROUTING_NONE, NULL, params);
198 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
199 CHECK(!guest);
200
201 // Validate that the partition id coming from the renderer is valid UTF-8,
202 // since we depend on this in other parts of the code, such as FilePath
203 // creation. If the validation fails, treat it as a bad message and kill the
204 // renderer process.
205 if (!IsStringUTF8(params.storage_partition_id)) {
206 content::RecordAction(UserMetricsAction("BadMessageTerminate_BPE"));
207 base::KillProcess(render_view_host_->GetProcess()->GetHandle(),
208 content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
209 return;
210 }
211
212 const std::string& host =
213 render_view_host_->GetSiteInstance()->GetSiteURL().host();
214 std::string url_encoded_partition = net::EscapeQueryParamValue(
215 params.storage_partition_id, false);
216
217 // The SiteInstance of a given webview tag is based on the fact that it's a
218 // guest process in addition to which platform application the tag belongs to
219 // and what storage partition is in use, rather than the URL that the tag is
220 // being navigated to.
221 GURL guest_site(
222 base::StringPrintf("%s://%s/%s?%s", chrome::kGuestScheme,
223 host.c_str(), params.persist_storage ? "persist" : "",
224 url_encoded_partition.c_str()));
225
226 // If we already have a webview tag in the same app using the same storage
227 // partition, we should use the same SiteInstance so the existing tag and
228 // the new tag can script each other.
229 SiteInstance* guest_site_instance = NULL;
230 for (ContainerInstanceMap::const_iterator it =
231 guest_web_contents_by_instance_id_.begin();
232 it != guest_web_contents_by_instance_id_.end(); ++it) {
233 if (it->second->GetSiteInstance()->GetSiteURL() == guest_site) {
234 guest_site_instance = it->second->GetSiteInstance();
235 break;
236 }
237 }
238 if (!guest_site_instance) {
239 // Create the SiteInstance in a new BrowsingInstance, which will ensure that
240 // webview tags are also not allowed to send messages across different
241 // partitions.
242 guest_site_instance = SiteInstance::CreateForURL(
243 web_contents()->GetBrowserContext(), guest_site);
244 }
245
246 guest_web_contents = WebContentsImpl::CreateGuest(
247 web_contents()->GetBrowserContext(),
248 guest_site_instance,
249 instance_id,
250 params);
251
252 guest = guest_web_contents->GetBrowserPluginGuest();
253 guest->set_embedder_web_contents(
254 static_cast<WebContentsImpl*>(web_contents()));
255
256 RendererPreferences* guest_renderer_prefs =
257 guest_web_contents->GetMutableRendererPrefs();
258 // Copy renderer preferences (and nothing else) from the embedder's
259 // TabContents to the guest.
260 //
261 // For GTK and Aura this is necessary to get proper renderer configuration
262 // values for caret blinking interval, colors related to selection and
263 // focus.
264 *guest_renderer_prefs = *web_contents()->GetMutableRendererPrefs();
265
266 guest_renderer_prefs->throttle_input_events = false;
267 // Navigation is disabled in Chrome Apps. We want to make sure guest-initiated
268 // navigations still continue to function inside the app.
269 guest_renderer_prefs->browser_handles_all_top_level_requests = false;
270 AddGuest(instance_id, guest_web_contents);
271 guest_web_contents->SetDelegate(guest);
272
273 // Create a swapped out RenderView for the guest in the embedder render
274 // process, so that the embedder can access the guest's window object.
275 int guest_routing_id =
276 static_cast<WebContentsImpl*>(guest->GetWebContents())->
277 CreateSwappedOutRenderView(web_contents()->GetSiteInstance());
278 render_view_host_->Send(new BrowserPluginMsg_GuestContentWindowReady(
279 render_view_host_->GetRoutingID(), instance_id, guest_routing_id));
280
281 guest->Initialize(params, guest_web_contents->GetRenderViewHost());
282 } 297 }
283 298
284 void BrowserPluginEmbedder::OnNavigateGuest( 299 void BrowserPluginEmbedder::OnNavigateGuest(
285 int instance_id, 300 int instance_id,
286 const std::string& src) { 301 const std::string& src) {
287 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id); 302 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
288 CHECK(guest); 303 CHECK(guest);
289 GURL url(src); 304 GURL url(src);
290 WebContentsImpl* guest_web_contents = 305 WebContentsImpl* guest_web_contents =
291 static_cast<WebContentsImpl*>(guest->GetWebContents()); 306 static_cast<WebContentsImpl*>(guest->GetWebContents());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 uint32 sync_point) { 350 uint32 sync_point) {
336 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; 351 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
337 ack_params.mailbox_name = mailbox_name; 352 ack_params.mailbox_name = mailbox_name;
338 ack_params.sync_point = sync_point; 353 ack_params.sync_point = sync_point;
339 RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id, 354 RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id,
340 gpu_host_id, 355 gpu_host_id,
341 ack_params); 356 ack_params);
342 } 357 }
343 358
344 } // namespace content 359 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/browser_plugin/browser_plugin_embedder.h ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698