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/browser_plugin/browser_plugin_guest.h" | 5 #include "content/browser/browser_plugin/browser_plugin_guest.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 | 48 |
49 #if defined(OS_MACOSX) | 49 #if defined(OS_MACOSX) |
50 #include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h" | 50 #include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h" |
51 #endif | 51 #endif |
52 | 52 |
53 namespace content { | 53 namespace content { |
54 | 54 |
55 // static | 55 // static |
56 BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL; | 56 BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL; |
57 | 57 |
58 // Parent class for the various types of permission requests, each of which | |
59 // should be able to handle the response to their permission request. | |
60 class BrowserPluginGuest::PermissionRequest : | |
61 public base::RefCounted<BrowserPluginGuest::PermissionRequest> { | |
62 public: | |
63 void Respond(bool should_allow, const std::string& user_input) { | |
64 if (!guest_) | |
65 return; | |
66 RespondImpl(should_allow, user_input); | |
67 } | |
68 virtual bool AllowedByDefault() const { | |
69 return false; | |
70 } | |
71 protected: | |
72 explicit PermissionRequest(const base::WeakPtr<BrowserPluginGuest>& guest) | |
73 : guest_(guest) { | |
74 RecordAction( | |
75 base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest")); | |
76 } | |
77 virtual ~PermissionRequest() {} | |
78 | |
79 virtual void RespondImpl(bool should_allow, | |
80 const std::string& user_input) = 0; | |
81 // Friend RefCounted so that the dtor can be non-public. | |
82 friend class base::RefCounted<BrowserPluginGuest::PermissionRequest>; | |
83 | |
84 base::WeakPtr<BrowserPluginGuest> guest_; | |
85 }; | |
86 | |
87 class BrowserPluginGuest::NewWindowRequest : public PermissionRequest { | |
88 public: | |
89 NewWindowRequest(const base::WeakPtr<BrowserPluginGuest>& guest, | |
90 int instance_id) | |
91 : PermissionRequest(guest), | |
92 instance_id_(instance_id) { | |
93 RecordAction( | |
94 base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.NewWindow ")); | |
95 } | |
96 | |
97 virtual void RespondImpl(bool should_allow, | |
98 const std::string& user_input) OVERRIDE { | |
99 int embedder_render_process_id = | |
100 guest_->embedder_web_contents()->GetRenderProcessHost()->GetID(); | |
101 guest_->GetBrowserPluginGuestManager()-> | |
102 MaybeGetGuestByInstanceIDOrKill( | |
103 instance_id_, | |
104 embedder_render_process_id, | |
105 base::Bind(&BrowserPluginGuest::NewWindowRequest::RespondInternal, | |
106 base::Unretained(this), | |
107 should_allow)); | |
108 } | |
109 | |
110 private: | |
111 virtual ~NewWindowRequest() {} | |
112 | |
113 void RespondInternal(bool should_allow, | |
114 WebContents* guest_web_contents) { | |
115 if (!guest_web_contents) { | |
116 VLOG(0) << "Guest not found. Instance ID: " << instance_id_; | |
117 return; | |
118 } | |
119 | |
120 BrowserPluginGuest* guest = | |
121 static_cast<WebContentsImpl*>(guest_web_contents)-> | |
122 GetBrowserPluginGuest(); | |
123 DCHECK(guest); | |
124 // If we do not destroy the guest then we allow the new window. | |
125 if (!should_allow) | |
126 guest->Destroy(); | |
127 } | |
128 | |
129 int instance_id_; | |
130 }; | |
131 | |
132 namespace { | 58 namespace { |
133 std::string WindowOpenDispositionToString( | |
134 WindowOpenDisposition window_open_disposition) { | |
135 switch (window_open_disposition) { | |
136 case IGNORE_ACTION: | |
137 return "ignore"; | |
138 case SAVE_TO_DISK: | |
139 return "save_to_disk"; | |
140 case CURRENT_TAB: | |
141 return "current_tab"; | |
142 case NEW_BACKGROUND_TAB: | |
143 return "new_background_tab"; | |
144 case NEW_FOREGROUND_TAB: | |
145 return "new_foreground_tab"; | |
146 case NEW_WINDOW: | |
147 return "new_window"; | |
148 case NEW_POPUP: | |
149 return "new_popup"; | |
150 default: | |
151 NOTREACHED() << "Unknown Window Open Disposition"; | |
152 return "ignore"; | |
153 } | |
154 } | |
155 | 59 |
156 // Called on IO thread. | 60 // Called on IO thread. |
157 static GURL RetrieveDownloadURLFromRequestId( | 61 static GURL RetrieveDownloadURLFromRequestId( |
158 int render_process_id, | 62 int render_process_id, |
159 int url_request_id) { | 63 int url_request_id) { |
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
161 | 65 |
162 GlobalRequestID global_id(render_process_id, url_request_id); | 66 GlobalRequestID global_id(render_process_id, url_request_id); |
163 net::URLRequest* url_request = | 67 net::URLRequest* url_request = |
164 ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id); | 68 ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 instance_id_(instance_id), | 112 instance_id_(instance_id), |
209 guest_device_scale_factor_(1.0f), | 113 guest_device_scale_factor_(1.0f), |
210 guest_hang_timeout_( | 114 guest_hang_timeout_( |
211 base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)), | 115 base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)), |
212 focused_(false), | 116 focused_(false), |
213 mouse_locked_(false), | 117 mouse_locked_(false), |
214 pending_lock_request_(false), | 118 pending_lock_request_(false), |
215 embedder_visible_(true), | 119 embedder_visible_(true), |
216 auto_size_enabled_(false), | 120 auto_size_enabled_(false), |
217 copy_request_id_(0), | 121 copy_request_id_(0), |
218 next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID), | |
219 has_render_view_(has_render_view), | 122 has_render_view_(has_render_view), |
220 last_seen_auto_size_enabled_(false), | 123 last_seen_auto_size_enabled_(false), |
221 is_in_destruction_(false), | 124 is_in_destruction_(false), |
222 last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 125 last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
223 last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT), | 126 last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT), |
224 last_can_compose_inline_(true), | 127 last_can_compose_inline_(true), |
225 weak_ptr_factory_(this) { | 128 weak_ptr_factory_(this) { |
226 DCHECK(web_contents); | 129 DCHECK(web_contents); |
227 web_contents->SetDelegate(this); | 130 web_contents->SetDelegate(this); |
228 } | 131 } |
229 | 132 |
230 bool BrowserPluginGuest::AddMessageToConsole(WebContents* source, | 133 bool BrowserPluginGuest::AddMessageToConsole(WebContents* source, |
231 int32 level, | 134 int32 level, |
232 const base::string16& message, | 135 const base::string16& message, |
233 int32 line_no, | 136 int32 line_no, |
234 const base::string16& source_id) { | 137 const base::string16& source_id) { |
235 if (!delegate_) | 138 if (!delegate_) |
236 return false; | 139 return false; |
237 | 140 |
238 delegate_->AddMessageToConsole(level, message, line_no, source_id); | 141 delegate_->AddMessageToConsole(level, message, line_no, source_id); |
239 return true; | 142 return true; |
240 } | 143 } |
241 | 144 |
242 void BrowserPluginGuest::DestroyUnattachedWindows() { | 145 void BrowserPluginGuest::WillDestroy(WebContents* web_contents) { |
243 // Destroy() reaches in and removes the BrowserPluginGuest from its opener's | 146 DCHECK_EQ(web_contents, GetWebContents()); |
244 // pending_new_windows_ set. To avoid mutating the set while iterating, we | 147 is_in_destruction_ = true; |
245 // create a copy of the pending new windows set and iterate over the copy. | |
246 PendingWindowMap pending_new_windows(pending_new_windows_); | |
247 // Clean up unattached new windows opened by this guest. | |
248 for (PendingWindowMap::const_iterator it = pending_new_windows.begin(); | |
249 it != pending_new_windows.end(); ++it) { | |
250 it->first->Destroy(); | |
251 } | |
252 // All pending windows should be removed from the set after Destroy() is | |
253 // called on all of them. | |
254 DCHECK(pending_new_windows_.empty()); | |
255 } | |
256 | |
257 void BrowserPluginGuest::LoadURLWithParams(const GURL& url, | |
258 const Referrer& referrer, | |
259 PageTransition transition_type, | |
260 WebContents* web_contents) { | |
261 NavigationController::LoadURLParams load_url_params(url); | |
262 load_url_params.referrer = referrer; | |
263 load_url_params.transition_type = transition_type; | |
264 load_url_params.extra_headers = std::string(); | |
265 if (delegate_ && delegate_->IsOverridingUserAgent()) { | |
266 load_url_params.override_user_agent = | |
267 NavigationController::UA_OVERRIDE_TRUE; | |
268 } | |
269 web_contents->GetController().LoadURLWithParams(load_url_params); | |
270 } | |
271 | |
272 void BrowserPluginGuest::RespondToPermissionRequest( | |
273 int request_id, | |
274 bool should_allow, | |
275 const std::string& user_input) { | |
276 RequestMap::iterator request_itr = permission_request_map_.find(request_id); | |
277 if (request_itr == permission_request_map_.end()) { | |
278 VLOG(0) << "Not a valid request ID."; | |
279 return; | |
280 } | |
281 request_itr->second->Respond(should_allow, user_input); | |
282 permission_request_map_.erase(request_itr); | |
283 } | |
284 | |
285 void BrowserPluginGuest::RequestPermission( | |
286 BrowserPluginPermissionType permission_type, | |
287 scoped_refptr<BrowserPluginGuest::PermissionRequest> request, | |
288 const base::DictionaryValue& request_info) { | |
289 if (!delegate_) { | |
290 // Let the stack unwind before we deny the permission request so that | |
291 // objects held by the permission request are not destroyed immediately | |
292 // after creation. This is to allow those same objects to be accessed again | |
293 // in the same scope without fear of use after freeing. | |
294 base::MessageLoop::current()->PostTask( | |
295 FROM_HERE, | |
296 base::Bind(&BrowserPluginGuest::PermissionRequest::Respond, | |
297 request, false, "")); | |
298 } | |
299 | |
300 int request_id = ++next_permission_request_id_; | |
301 permission_request_map_[request_id] = request; | |
302 | |
303 BrowserPluginGuestDelegate::PermissionResponseCallback callback = | |
304 base::Bind(&BrowserPluginGuest::RespondToPermissionRequest, | |
305 AsWeakPtr(), | |
306 request_id); | |
307 delegate_->RequestPermission( | |
308 permission_type, request_info, callback, request->AllowedByDefault()); | |
309 } | |
310 | |
311 BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow( | |
312 const OpenURLParams& params) { | |
313 BrowserPluginGuestManager* guest_manager = | |
314 GetBrowserPluginGuestManager(); | |
315 | |
316 // Allocate a new instance ID for the new guest. | |
317 int instance_id = guest_manager->GetNextInstanceID(); | |
318 | |
319 // Set the attach params to use the same partition as the opener. | |
320 // We pull the partition information from the site's URL, which is of the form | |
321 // guest://site/{persist}?{partition_name}. | |
322 const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL(); | |
323 | |
324 // The new guest gets a copy of this guest's extra params so that the content | |
325 // embedder exposes the same API for this guest as its opener. | |
326 scoped_ptr<base::DictionaryValue> extra_params( | |
327 extra_attach_params_->DeepCopy()); | |
328 const std::string& storage_partition_id = site_url.query(); | |
329 bool persist_storage = | |
330 site_url.path().find("persist") != std::string::npos; | |
331 WebContents* new_guest_web_contents = | |
332 guest_manager->CreateGuest(GetWebContents()->GetSiteInstance(), | |
333 instance_id, | |
334 storage_partition_id, | |
335 persist_storage, | |
336 extra_params.Pass()); | |
337 BrowserPluginGuest* new_guest = | |
338 static_cast<WebContentsImpl*>(new_guest_web_contents)-> | |
339 GetBrowserPluginGuest(); | |
340 if (new_guest->delegate_) | |
341 new_guest->delegate_->SetOpener(GetWebContents()); | |
342 | |
343 // Take ownership of |new_guest|. | |
344 pending_new_windows_.insert( | |
345 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); | |
346 | |
347 // Request permission to show the new window. | |
348 RequestNewWindowPermission(params.disposition, gfx::Rect(), | |
349 params.user_gesture, new_guest->GetWebContents()); | |
350 | |
351 return new_guest; | |
352 } | 148 } |
353 | 149 |
354 base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() { | 150 base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() { |
355 return weak_ptr_factory_.GetWeakPtr(); | 151 return weak_ptr_factory_.GetWeakPtr(); |
356 } | 152 } |
357 | 153 |
358 void BrowserPluginGuest::EmbedderDestroyed() { | 154 void BrowserPluginGuest::EmbedderDestroyed() { |
359 embedder_web_contents_ = NULL; | 155 embedder_web_contents_ = NULL; |
360 if (delegate_) | 156 if (delegate_) |
361 delegate_->EmbedderDestroyed(); | 157 delegate_->EmbedderDestroyed(); |
362 Destroy(); | 158 Destroy(); |
363 } | 159 } |
364 | 160 |
365 void BrowserPluginGuest::Destroy() { | 161 void BrowserPluginGuest::Destroy() { |
366 is_in_destruction_ = true; | 162 if (!delegate_) |
367 if (!attached() && GetOpener()) | 163 return; |
368 GetOpener()->pending_new_windows_.erase(this); | 164 delegate_->Destroy(); |
369 DestroyUnattachedWindows(); | |
370 delete GetWebContents(); | |
371 } | 165 } |
372 | 166 |
373 bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( | 167 bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( |
374 const IPC::Message& message) { | 168 const IPC::Message& message) { |
375 bool handled = true; | 169 bool handled = true; |
376 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message) | 170 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message) |
377 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameSwappedACK, | 171 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameSwappedACK, |
378 OnCompositorFrameSwappedACK) | 172 OnCompositorFrameSwappedACK) |
379 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck, | 173 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck, |
380 OnCopyFromCompositingSurfaceAck) | 174 OnCopyFromCompositingSurfaceAck) |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 int guest_routing_id = | 258 int guest_routing_id = |
465 GetWebContents()->CreateSwappedOutRenderView( | 259 GetWebContents()->CreateSwappedOutRenderView( |
466 embedder_web_contents_->GetSiteInstance()); | 260 embedder_web_contents_->GetSiteInstance()); |
467 SendMessageToEmbedder( | 261 SendMessageToEmbedder( |
468 new BrowserPluginMsg_GuestContentWindowReady(instance_id_, | 262 new BrowserPluginMsg_GuestContentWindowReady(instance_id_, |
469 guest_routing_id)); | 263 guest_routing_id)); |
470 | 264 |
471 if (!params.src.empty()) { | 265 if (!params.src.empty()) { |
472 // params.src will be validated in BrowserPluginGuest::OnNavigateGuest. | 266 // params.src will be validated in BrowserPluginGuest::OnNavigateGuest. |
473 OnNavigateGuest(instance_id_, params.src); | 267 OnNavigateGuest(instance_id_, params.src); |
268 has_render_view_ = true; | |
474 } | 269 } |
475 | 270 |
476 has_render_view_ = true; | |
477 | |
478 WebPreferences prefs = GetWebContents()->GetWebkitPrefs(); | 271 WebPreferences prefs = GetWebContents()->GetWebkitPrefs(); |
479 prefs.navigate_on_drag_drop = false; | 272 prefs.navigate_on_drag_drop = false; |
480 GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs); | 273 GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs); |
481 | 274 |
482 // Enable input method for guest if it's enabled for the embedder. | 275 // Enable input method for guest if it's enabled for the embedder. |
483 if (static_cast<RenderViewHostImpl*>( | 276 if (static_cast<RenderViewHostImpl*>( |
484 embedder_web_contents_->GetRenderViewHost())->input_method_active()) { | 277 embedder_web_contents_->GetRenderViewHost())->input_method_active()) { |
485 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( | 278 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( |
486 GetWebContents()->GetRenderViewHost()); | 279 GetWebContents()->GetRenderViewHost()); |
487 guest_rvh->SetInputMethodActive(true); | 280 guest_rvh->SetInputMethodActive(true); |
(...skipping 20 matching lines...) Expand all Loading... | |
508 delete pending_messages_.front(); | 301 delete pending_messages_.front(); |
509 pending_messages_.pop(); | 302 pending_messages_.pop(); |
510 } | 303 } |
511 } | 304 } |
512 | 305 |
513 // static | 306 // static |
514 BrowserPluginGuest* BrowserPluginGuest::Create( | 307 BrowserPluginGuest* BrowserPluginGuest::Create( |
515 int instance_id, | 308 int instance_id, |
516 SiteInstance* guest_site_instance, | 309 SiteInstance* guest_site_instance, |
517 WebContentsImpl* web_contents, | 310 WebContentsImpl* web_contents, |
518 scoped_ptr<base::DictionaryValue> extra_params) { | 311 scoped_ptr<base::DictionaryValue> extra_params, |
312 BrowserPluginGuest* opener) { | |
519 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create")); | 313 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create")); |
520 BrowserPluginGuest* guest = NULL; | 314 BrowserPluginGuest* guest = NULL; |
521 if (factory_) { | 315 if (factory_) { |
522 guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents); | 316 guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents); |
523 } else { | 317 } else { |
524 guest = new BrowserPluginGuest(instance_id, false, web_contents); | 318 guest = new BrowserPluginGuest(instance_id, |
319 web_contents->opener() != NULL, | |
320 web_contents); | |
525 } | 321 } |
526 guest->extra_attach_params_.reset(extra_params->DeepCopy()); | |
527 web_contents->SetBrowserPluginGuest(guest); | 322 web_contents->SetBrowserPluginGuest(guest); |
323 WebContents* opener_web_contents = NULL; | |
324 if (opener) { | |
325 opener_web_contents = opener->GetWebContents(); | |
326 guest_site_instance = opener_web_contents->GetSiteInstance(); | |
327 } | |
528 BrowserPluginGuestDelegate* delegate = NULL; | 328 BrowserPluginGuestDelegate* delegate = NULL; |
529 GetContentClient()->browser()->GuestWebContentsCreated( | 329 GetContentClient()->browser()->GuestWebContentsCreated( |
530 guest_site_instance, web_contents, NULL, &delegate, extra_params.Pass()); | 330 guest_site_instance, |
531 guest->SetDelegate(delegate); | 331 web_contents, |
332 opener_web_contents, | |
333 &delegate, | |
334 extra_params.Pass()); | |
335 if (delegate) { | |
336 delegate->RegisterDestructionCallback( | |
337 base::Bind(&BrowserPluginGuest::WillDestroy, | |
338 base::Unretained(guest))); | |
339 guest->SetDelegate(delegate); | |
340 } | |
532 return guest; | 341 return guest; |
533 } | 342 } |
534 | 343 |
535 // static | |
536 BrowserPluginGuest* BrowserPluginGuest::CreateWithOpener( | |
537 int instance_id, | |
538 bool has_render_view, | |
539 WebContentsImpl* web_contents, | |
540 BrowserPluginGuest* opener) { | |
541 BrowserPluginGuest* guest = | |
542 new BrowserPluginGuest( | |
543 instance_id, has_render_view, web_contents); | |
544 web_contents->SetBrowserPluginGuest(guest); | |
545 BrowserPluginGuestDelegate* delegate = NULL; | |
546 GetContentClient()->browser()->GuestWebContentsCreated( | |
547 opener->GetWebContents()->GetSiteInstance(), | |
548 web_contents, opener->GetWebContents(), &delegate, | |
549 scoped_ptr<base::DictionaryValue>()); | |
550 guest->SetDelegate(delegate); | |
551 return guest; | |
552 } | |
553 | |
554 RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() { | 344 RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() { |
555 if (!attached()) | 345 if (!attached()) |
556 return NULL; | 346 return NULL; |
557 return embedder_web_contents_->GetRenderWidgetHostView(); | 347 return embedder_web_contents_->GetRenderWidgetHostView(); |
558 } | 348 } |
559 | 349 |
560 BrowserPluginGuest* BrowserPluginGuest::GetOpener() const { | |
561 if (!delegate_) | |
562 return NULL; | |
563 | |
564 WebContents* opener = delegate_->GetOpener(); | |
565 if (!opener) | |
566 return NULL; | |
567 | |
568 return static_cast<WebContentsImpl*>(opener)->GetBrowserPluginGuest(); | |
569 } | |
570 | |
571 void BrowserPluginGuest::UpdateVisibility() { | 350 void BrowserPluginGuest::UpdateVisibility() { |
572 OnSetVisibility(instance_id_, visible()); | 351 OnSetVisibility(instance_id_, visible()); |
573 } | 352 } |
574 | 353 |
575 void BrowserPluginGuest::CopyFromCompositingSurface( | 354 void BrowserPluginGuest::CopyFromCompositingSurface( |
576 gfx::Rect src_subrect, | 355 gfx::Rect src_subrect, |
577 gfx::Size dst_size, | 356 gfx::Size dst_size, |
578 const base::Callback<void(bool, const SkBitmap&)>& callback) { | 357 const base::Callback<void(bool, const SkBitmap&)>& callback) { |
579 copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback)); | 358 copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback)); |
580 SendMessageToEmbedder( | 359 SendMessageToEmbedder( |
(...skipping 17 matching lines...) Expand all Loading... | |
598 embedder_visible_ = visible; | 377 embedder_visible_ = visible; |
599 UpdateVisibility(); | 378 UpdateVisibility(); |
600 } | 379 } |
601 | 380 |
602 void BrowserPluginGuest::AddNewContents(WebContents* source, | 381 void BrowserPluginGuest::AddNewContents(WebContents* source, |
603 WebContents* new_contents, | 382 WebContents* new_contents, |
604 WindowOpenDisposition disposition, | 383 WindowOpenDisposition disposition, |
605 const gfx::Rect& initial_pos, | 384 const gfx::Rect& initial_pos, |
606 bool user_gesture, | 385 bool user_gesture, |
607 bool* was_blocked) { | 386 bool* was_blocked) { |
608 if (was_blocked) | 387 if (!delegate_) |
609 *was_blocked = false; | 388 return; |
610 RequestNewWindowPermission(disposition, initial_pos, user_gesture, | 389 |
611 static_cast<WebContentsImpl*>(new_contents)); | 390 delegate_->AddNewContents(source, new_contents, disposition, |
391 initial_pos, user_gesture, was_blocked); | |
612 } | 392 } |
613 | 393 |
614 void BrowserPluginGuest::CanDownload( | 394 void BrowserPluginGuest::CanDownload( |
615 RenderViewHost* render_view_host, | 395 RenderViewHost* render_view_host, |
616 int request_id, | 396 int request_id, |
617 const std::string& request_method, | 397 const std::string& request_method, |
618 const base::Callback<void(bool)>& callback) { | 398 const base::Callback<void(bool)>& callback) { |
619 if (!delegate_) { | 399 if (!delegate_) { |
620 callback.Run(false); | 400 callback.Run(false); |
621 return; | 401 return; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
719 return; | 499 return; |
720 | 500 |
721 // |selection_rect| is updated to incorporate embedder coordinates. | 501 // |selection_rect| is updated to incorporate embedder coordinates. |
722 delegate_->FindReply(request_id, number_of_matches, | 502 delegate_->FindReply(request_id, number_of_matches, |
723 ToGuestRect(selection_rect), | 503 ToGuestRect(selection_rect), |
724 active_match_ordinal, final_update); | 504 active_match_ordinal, final_update); |
725 } | 505 } |
726 | 506 |
727 WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source, | 507 WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source, |
728 const OpenURLParams& params) { | 508 const OpenURLParams& params) { |
729 // If the guest wishes to navigate away prior to attachment then we save the | 509 if (!delegate_) |
730 // navigation to perform upon attachment. Navigation initializes a lot of | |
731 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest. | |
732 // Navigation also resumes resource loading which we don't want to allow | |
733 // until attachment. | |
734 if (!attached()) { | |
735 PendingWindowMap::iterator it = | |
736 GetOpener()->pending_new_windows_.find(this); | |
737 if (it == GetOpener()->pending_new_windows_.end()) | |
738 return NULL; | |
739 const NewWindowInfo& old_target_url = it->second; | |
740 NewWindowInfo new_window_info(params.url, old_target_url.name); | |
741 new_window_info.changed = new_window_info.url != old_target_url.url; | |
742 it->second = new_window_info; | |
743 return NULL; | 510 return NULL; |
744 } | 511 return delegate_->OpenURLFromTab(source, params); |
745 if (params.disposition == CURRENT_TAB) { | |
746 // This can happen for cross-site redirects. | |
747 LoadURLWithParams(params.url, params.referrer, params.transition, source); | |
748 return source; | |
749 } | |
750 | |
751 return CreateNewGuestWindow(params)->GetWebContents(); | |
752 } | 512 } |
753 | 513 |
754 void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents, | 514 void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents, |
755 int opener_render_frame_id, | 515 int opener_render_frame_id, |
756 const base::string16& frame_name, | 516 const base::string16& frame_name, |
757 const GURL& target_url, | 517 const GURL& target_url, |
758 WebContents* new_contents) { | 518 WebContents* new_contents) { |
759 WebContentsImpl* new_contents_impl = | 519 WebContentsImpl* new_contents_impl = |
760 static_cast<WebContentsImpl*>(new_contents); | 520 static_cast<WebContentsImpl*>(new_contents); |
761 BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest(); | 521 BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest(); |
762 if (guest->delegate_) | |
763 guest->delegate_->SetOpener(GetWebContents()); | |
764 std::string guest_name = base::UTF16ToUTF8(frame_name); | 522 std::string guest_name = base::UTF16ToUTF8(frame_name); |
765 guest->name_ = guest_name; | 523 guest->name_ = guest_name; |
766 // Take ownership of the new guest until it is attached to the embedder's DOM | 524 |
767 // tree to avoid leaking a guest if this guest is destroyed before attaching | 525 if (!delegate_) |
768 // the new guest. | 526 return; |
769 pending_new_windows_.insert( | 527 |
770 std::make_pair(guest, NewWindowInfo(target_url, guest_name))); | 528 delegate_->WebContentsCreated(source_contents, |
529 opener_render_frame_id, | |
530 frame_name, | |
531 target_url, | |
532 new_contents); | |
771 } | 533 } |
772 | 534 |
773 void BrowserPluginGuest::RendererUnresponsive(WebContents* source) { | 535 void BrowserPluginGuest::RendererUnresponsive(WebContents* source) { |
774 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Hung")); | 536 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Hung")); |
775 if (!delegate_) | 537 if (!delegate_) |
776 return; | 538 return; |
777 delegate_->RendererUnresponsive(); | 539 delegate_->RendererUnresponsive(); |
778 } | 540 } |
779 | 541 |
780 void BrowserPluginGuest::RendererResponsive(WebContents* source) { | 542 void BrowserPluginGuest::RendererResponsive(WebContents* source) { |
(...skipping 29 matching lines...) Expand all Loading... | |
810 gfx::Point screen_pos(relative_position); | 572 gfx::Point screen_pos(relative_position); |
811 screen_pos += guest_window_rect_.OffsetFromOrigin(); | 573 screen_pos += guest_window_rect_.OffsetFromOrigin(); |
812 return screen_pos; | 574 return screen_pos; |
813 } | 575 } |
814 | 576 |
815 bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const { | 577 bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const { |
816 return size.width() <= max_auto_size_.width() && | 578 return size.width() <= max_auto_size_.width() && |
817 size.height() <= max_auto_size_.height(); | 579 size.height() <= max_auto_size_.height(); |
818 } | 580 } |
819 | 581 |
820 void BrowserPluginGuest::RequestNewWindowPermission( | |
821 WindowOpenDisposition disposition, | |
822 const gfx::Rect& initial_bounds, | |
823 bool user_gesture, | |
824 WebContentsImpl* new_contents) { | |
825 BrowserPluginGuest* guest = new_contents->GetBrowserPluginGuest(); | |
826 PendingWindowMap::iterator it = pending_new_windows_.find(guest); | |
827 if (it == pending_new_windows_.end()) | |
828 return; | |
829 const NewWindowInfo& new_window_info = it->second; | |
830 | |
831 base::DictionaryValue request_info; | |
832 request_info.Set(browser_plugin::kInitialHeight, | |
lazyboy
2014/05/12 23:00:20
Remove these from browser_plugin_constants.cc
Fady Samuel
2014/05/13 18:59:02
Done.
| |
833 base::Value::CreateIntegerValue(initial_bounds.height())); | |
834 request_info.Set(browser_plugin::kInitialWidth, | |
835 base::Value::CreateIntegerValue(initial_bounds.width())); | |
836 request_info.Set(browser_plugin::kTargetURL, | |
837 base::Value::CreateStringValue(new_window_info.url.spec())); | |
838 request_info.Set(browser_plugin::kName, | |
839 base::Value::CreateStringValue(new_window_info.name)); | |
840 request_info.Set(browser_plugin::kWindowID, | |
841 base::Value::CreateIntegerValue(guest->instance_id())); | |
842 request_info.Set(browser_plugin::kWindowOpenDisposition, | |
843 base::Value::CreateStringValue( | |
844 WindowOpenDispositionToString(disposition))); | |
845 | |
846 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW, | |
847 new NewWindowRequest(weak_ptr_factory_.GetWeakPtr(), | |
848 guest->instance_id()), | |
849 request_info); | |
850 } | |
851 | |
852 bool BrowserPluginGuest::UnlockMouseIfNecessary( | 582 bool BrowserPluginGuest::UnlockMouseIfNecessary( |
853 const NativeWebKeyboardEvent& event) { | 583 const NativeWebKeyboardEvent& event) { |
854 if (!mouse_locked_) | 584 if (!mouse_locked_) |
855 return false; | 585 return false; |
856 | 586 |
857 embedder_web_contents()->GotResponseToLockMouseRequest(false); | 587 embedder_web_contents()->GotResponseToLockMouseRequest(false); |
858 return true; | 588 return true; |
859 } | 589 } |
860 | 590 |
861 void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) { | 591 void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
953 case base::TERMINATION_STATUS_PROCESS_CRASHED: | 683 case base::TERMINATION_STATUS_PROCESS_CRASHED: |
954 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed")); | 684 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed")); |
955 break; | 685 break; |
956 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: | 686 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: |
957 RecordAction( | 687 RecordAction( |
958 base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath")); | 688 base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath")); |
959 break; | 689 break; |
960 default: | 690 default: |
961 break; | 691 break; |
962 } | 692 } |
963 // TODO(fsamuel): Consider whether we should be clearing | |
964 // |permission_request_map_| here. | |
965 if (delegate_) | 693 if (delegate_) |
966 delegate_->GuestProcessGone(status); | 694 delegate_->GuestProcessGone(status); |
967 } | 695 } |
968 | 696 |
969 // static | 697 // static |
970 bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest( | 698 bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest( |
971 const IPC::Message& message) { | 699 const IPC::Message& message) { |
972 switch (message.type()) { | 700 switch (message.type()) { |
973 case BrowserPluginHostMsg_CompositorFrameSwappedACK::ID: | 701 case BrowserPluginHostMsg_CompositorFrameSwappedACK::ID: |
974 case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID: | 702 case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID: |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1028 return handled; | 756 return handled; |
1029 } | 757 } |
1030 | 758 |
1031 void BrowserPluginGuest::Attach( | 759 void BrowserPluginGuest::Attach( |
1032 WebContentsImpl* embedder_web_contents, | 760 WebContentsImpl* embedder_web_contents, |
1033 BrowserPluginHostMsg_Attach_Params params, | 761 BrowserPluginHostMsg_Attach_Params params, |
1034 const base::DictionaryValue& extra_params) { | 762 const base::DictionaryValue& extra_params) { |
1035 if (attached()) | 763 if (attached()) |
1036 return; | 764 return; |
1037 | 765 |
1038 extra_attach_params_.reset(extra_params.DeepCopy()); | |
1039 | |
1040 // Clear parameters that get inherited from the opener. | 766 // Clear parameters that get inherited from the opener. |
1041 params.storage_partition_id.clear(); | 767 params.storage_partition_id.clear(); |
1042 params.persist_storage = false; | 768 params.persist_storage = false; |
1043 params.src.clear(); | 769 params.src.clear(); |
1044 | 770 |
1045 // If a RenderView has already been created for this new window, then we need | 771 // If a RenderView has already been created for this new window, then we need |
1046 // to initialize the browser-side state now so that the RenderFrameHostManager | 772 // to initialize the browser-side state now so that the RenderFrameHostManager |
1047 // does not create a new RenderView on navigation. | 773 // does not create a new RenderView on navigation. |
1048 if (has_render_view_) { | 774 if (has_render_view_) { |
1049 static_cast<RenderViewHostImpl*>( | 775 static_cast<RenderViewHostImpl*>( |
1050 GetWebContents()->GetRenderViewHost())->Init(); | 776 GetWebContents()->GetRenderViewHost())->Init(); |
1051 WebContentsViewGuest* new_view = | 777 WebContentsViewGuest* new_view = |
1052 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView()); | 778 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView()); |
1053 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost()); | 779 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost()); |
1054 } | 780 } |
1055 | 781 |
1056 // We need to do a navigation here if the target URL has changed between | |
1057 // the time the WebContents was created and the time it was attached. | |
1058 // We also need to do an initial navigation if a RenderView was never | |
1059 // created for the new window in cases where there is no referrer. | |
1060 PendingWindowMap::iterator it = GetOpener()->pending_new_windows_.find(this); | |
1061 if (it != GetOpener()->pending_new_windows_.end()) { | |
1062 const NewWindowInfo& new_window_info = it->second; | |
1063 if (new_window_info.changed || !has_render_view_) | |
1064 params.src = it->second.url.spec(); | |
1065 } else { | |
1066 NOTREACHED(); | |
1067 } | |
1068 | |
1069 // Once a new guest is attached to the DOM of the embedder page, then the | |
1070 // lifetime of the new guest is no longer managed by the opener guest. | |
1071 GetOpener()->pending_new_windows_.erase(this); | |
1072 | |
1073 // The guest's frame name takes precedence over the BrowserPlugin's name. | 782 // The guest's frame name takes precedence over the BrowserPlugin's name. |
1074 // The guest's frame name is assigned in | 783 // The guest's frame name is assigned in |
1075 // BrowserPluginGuest::WebContentsCreated. | 784 // BrowserPluginGuest::WebContentsCreated. |
1076 if (!name_.empty()) | 785 if (!name_.empty()) |
1077 params.name.clear(); | 786 params.name.clear(); |
1078 | 787 |
1079 Initialize(params, embedder_web_contents); | 788 Initialize(params, embedder_web_contents); |
1080 | 789 |
1081 SendQueuedMessages(); | 790 SendQueuedMessages(); |
1082 | 791 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1242 weak_ptr_factory_.GetWeakPtr())); | 951 weak_ptr_factory_.GetWeakPtr())); |
1243 } | 952 } |
1244 | 953 |
1245 void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) { | 954 void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) { |
1246 Send(new ViewMsg_LockMouse_ACK(routing_id(), succeeded)); | 955 Send(new ViewMsg_LockMouse_ACK(routing_id(), succeeded)); |
1247 pending_lock_request_ = false; | 956 pending_lock_request_ = false; |
1248 if (succeeded) | 957 if (succeeded) |
1249 mouse_locked_ = true; | 958 mouse_locked_ = true; |
1250 } | 959 } |
1251 | 960 |
1252 void BrowserPluginGuest::OnNavigateGuest( | 961 void BrowserPluginGuest::OnNavigateGuest(int instance_id, |
1253 int instance_id, | 962 const std::string& src) { |
1254 const std::string& src) { | 963 if (!delegate_) |
1255 GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src); | |
1256 | |
1257 // Do not allow navigating a guest to schemes other than known safe schemes. | |
1258 // This will block the embedder trying to load unwanted schemes, e.g. | |
1259 // chrome://settings. | |
1260 bool scheme_is_blocked = | |
1261 (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme( | |
1262 url.scheme()) && | |
1263 !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme( | |
1264 url.scheme())) || | |
1265 url.SchemeIs(kJavaScriptScheme); | |
1266 if (scheme_is_blocked || !url.is_valid()) { | |
1267 if (delegate_) { | |
1268 std::string error_type; | |
1269 base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::", | |
1270 &error_type); | |
1271 delegate_->LoadAbort(true /* is_top_level */, url, error_type); | |
1272 } | |
1273 return; | 964 return; |
1274 } | 965 delegate_->NavigateGuest(src); |
1275 | |
1276 GURL validated_url(url); | |
1277 GetWebContents()->GetRenderProcessHost()->FilterURL(false, &validated_url); | |
1278 // As guests do not swap processes on navigation, only navigations to | |
1279 // normal web URLs are supported. No protocol handlers are installed for | |
1280 // other schemes (e.g., WebUI or extensions), and no permissions or bindings | |
1281 // can be granted to the guest process. | |
1282 LoadURLWithParams(validated_url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL, | |
1283 GetWebContents()); | |
1284 } | 966 } |
1285 | 967 |
1286 void BrowserPluginGuest::OnPluginDestroyed(int instance_id) { | 968 void BrowserPluginGuest::OnPluginDestroyed(int instance_id) { |
1287 Destroy(); | 969 Destroy(); |
1288 } | 970 } |
1289 | 971 |
1290 void BrowserPluginGuest::OnResizeGuest( | 972 void BrowserPluginGuest::OnResizeGuest( |
1291 int instance_id, | 973 int instance_id, |
1292 const BrowserPluginHostMsg_ResizeGuest_Params& params) { | 974 const BrowserPluginHostMsg_ResizeGuest_Params& params) { |
1293 if (!params.size_changed) | 975 if (!params.size_changed) |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1562 const GURL& url) { | 1244 const GURL& url) { |
1563 if (!url.is_valid()) { | 1245 if (!url.is_valid()) { |
1564 callback.Run(false); | 1246 callback.Run(false); |
1565 return; | 1247 return; |
1566 } | 1248 } |
1567 | 1249 |
1568 delegate_->CanDownload(request_method, url, callback); | 1250 delegate_->CanDownload(request_method, url, callback); |
1569 } | 1251 } |
1570 | 1252 |
1571 } // namespace content | 1253 } // namespace content |
OLD | NEW |