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

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

Issue 272573005: <webview>: Move NewWindow API to chrome (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@guestview_manager_rename
Patch Set: Cleanup and fix tests Created 6 years, 7 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
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_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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698