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

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: Merge with ToT 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 } // namespace 60 } // namespace
157 61
158 class BrowserPluginGuest::EmbedderWebContentsObserver 62 class BrowserPluginGuest::EmbedderWebContentsObserver
159 : public WebContentsObserver { 63 : public WebContentsObserver {
160 public: 64 public:
161 explicit EmbedderWebContentsObserver(BrowserPluginGuest* guest) 65 explicit EmbedderWebContentsObserver(BrowserPluginGuest* guest)
162 : WebContentsObserver(guest->embedder_web_contents()), 66 : WebContentsObserver(guest->embedder_web_contents()),
163 browser_plugin_guest_(guest) { 67 browser_plugin_guest_(guest) {
164 } 68 }
(...skipping 29 matching lines...) Expand all
194 instance_id_(instance_id), 98 instance_id_(instance_id),
195 guest_device_scale_factor_(1.0f), 99 guest_device_scale_factor_(1.0f),
196 focused_(false), 100 focused_(false),
197 mouse_locked_(false), 101 mouse_locked_(false),
198 pending_lock_request_(false), 102 pending_lock_request_(false),
199 guest_visible_(false), 103 guest_visible_(false),
200 guest_opaque_(true), 104 guest_opaque_(true),
201 embedder_visible_(true), 105 embedder_visible_(true),
202 auto_size_enabled_(false), 106 auto_size_enabled_(false),
203 copy_request_id_(0), 107 copy_request_id_(0),
204 next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID),
205 has_render_view_(has_render_view), 108 has_render_view_(has_render_view),
206 last_seen_auto_size_enabled_(false), 109 last_seen_auto_size_enabled_(false),
207 is_in_destruction_(false), 110 is_in_destruction_(false),
208 last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE), 111 last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
209 last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT), 112 last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
210 last_can_compose_inline_(true), 113 last_can_compose_inline_(true),
211 weak_ptr_factory_(this) { 114 weak_ptr_factory_(this) {
212 DCHECK(web_contents); 115 DCHECK(web_contents);
213 web_contents->SetDelegate(this); 116 web_contents->SetDelegate(this);
214 } 117 }
215 118
216 bool BrowserPluginGuest::AddMessageToConsole(WebContents* source, 119 bool BrowserPluginGuest::AddMessageToConsole(WebContents* source,
217 int32 level, 120 int32 level,
218 const base::string16& message, 121 const base::string16& message,
219 int32 line_no, 122 int32 line_no,
220 const base::string16& source_id) { 123 const base::string16& source_id) {
221 if (!delegate_) 124 if (!delegate_)
222 return false; 125 return false;
223 126
224 delegate_->AddMessageToConsole(level, message, line_no, source_id); 127 delegate_->AddMessageToConsole(level, message, line_no, source_id);
225 return true; 128 return true;
226 } 129 }
227 130
228 void BrowserPluginGuest::DestroyUnattachedWindows() { 131 void BrowserPluginGuest::WillDestroy(WebContents* web_contents) {
229 // Destroy() reaches in and removes the BrowserPluginGuest from its opener's 132 DCHECK_EQ(web_contents, GetWebContents());
230 // pending_new_windows_ set. To avoid mutating the set while iterating, we 133 is_in_destruction_ = true;
231 // create a copy of the pending new windows set and iterate over the copy.
232 PendingWindowMap pending_new_windows(pending_new_windows_);
233 // Clean up unattached new windows opened by this guest.
234 for (PendingWindowMap::const_iterator it = pending_new_windows.begin();
235 it != pending_new_windows.end(); ++it) {
236 it->first->Destroy();
237 }
238 // All pending windows should be removed from the set after Destroy() is
239 // called on all of them.
240 DCHECK(pending_new_windows_.empty());
241 }
242
243 void BrowserPluginGuest::LoadURLWithParams(const GURL& url,
244 const Referrer& referrer,
245 PageTransition transition_type,
246 WebContents* web_contents) {
247 NavigationController::LoadURLParams load_url_params(url);
248 load_url_params.referrer = referrer;
249 load_url_params.transition_type = transition_type;
250 load_url_params.extra_headers = std::string();
251 if (delegate_ && delegate_->IsOverridingUserAgent()) {
252 load_url_params.override_user_agent =
253 NavigationController::UA_OVERRIDE_TRUE;
254 }
255 web_contents->GetController().LoadURLWithParams(load_url_params);
256 }
257
258 void BrowserPluginGuest::RespondToPermissionRequest(
259 int request_id,
260 bool should_allow,
261 const std::string& user_input) {
262 RequestMap::iterator request_itr = permission_request_map_.find(request_id);
263 if (request_itr == permission_request_map_.end()) {
264 VLOG(0) << "Not a valid request ID.";
265 return;
266 }
267 request_itr->second->Respond(should_allow, user_input);
268 permission_request_map_.erase(request_itr);
269 }
270
271 void BrowserPluginGuest::RequestPermission(
272 BrowserPluginPermissionType permission_type,
273 scoped_refptr<BrowserPluginGuest::PermissionRequest> request,
274 const base::DictionaryValue& request_info) {
275 if (!delegate_) {
276 // Let the stack unwind before we deny the permission request so that
277 // objects held by the permission request are not destroyed immediately
278 // after creation. This is to allow those same objects to be accessed again
279 // in the same scope without fear of use after freeing.
280 base::MessageLoop::current()->PostTask(
281 FROM_HERE,
282 base::Bind(&BrowserPluginGuest::PermissionRequest::Respond,
283 request, false, ""));
284 }
285
286 int request_id = ++next_permission_request_id_;
287 permission_request_map_[request_id] = request;
288
289 BrowserPluginGuestDelegate::PermissionResponseCallback callback =
290 base::Bind(&BrowserPluginGuest::RespondToPermissionRequest,
291 AsWeakPtr(),
292 request_id);
293 delegate_->RequestPermission(
294 permission_type, request_info, callback, request->AllowedByDefault());
295 }
296
297 BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow(
298 const OpenURLParams& params) {
299 BrowserPluginGuestManager* guest_manager =
300 GetBrowserPluginGuestManager();
301
302 // Allocate a new instance ID for the new guest.
303 int instance_id = guest_manager->GetNextInstanceID();
304
305 // Set the attach params to use the same partition as the opener.
306 // We pull the partition information from the site's URL, which is of the form
307 // guest://site/{persist}?{partition_name}.
308 const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL();
309
310 // The new guest gets a copy of this guest's extra params so that the content
311 // embedder exposes the same API for this guest as its opener.
312 scoped_ptr<base::DictionaryValue> extra_params(
313 extra_attach_params_->DeepCopy());
314 const std::string& storage_partition_id = site_url.query();
315 bool persist_storage =
316 site_url.path().find("persist") != std::string::npos;
317 WebContents* new_guest_web_contents =
318 guest_manager->CreateGuest(GetWebContents()->GetSiteInstance(),
319 instance_id,
320 storage_partition_id,
321 persist_storage,
322 extra_params.Pass());
323 BrowserPluginGuest* new_guest =
324 static_cast<WebContentsImpl*>(new_guest_web_contents)->
325 GetBrowserPluginGuest();
326 if (new_guest->delegate_)
327 new_guest->delegate_->SetOpener(GetWebContents());
328
329 // Take ownership of |new_guest|.
330 pending_new_windows_.insert(
331 std::make_pair(new_guest, NewWindowInfo(params.url, std::string())));
332
333 // Request permission to show the new window.
334 RequestNewWindowPermission(params.disposition, gfx::Rect(),
335 params.user_gesture, new_guest->GetWebContents());
336
337 return new_guest;
338 } 134 }
339 135
340 base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() { 136 base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() {
341 return weak_ptr_factory_.GetWeakPtr(); 137 return weak_ptr_factory_.GetWeakPtr();
342 } 138 }
343 139
344 bool BrowserPluginGuest::LockMouse(bool allowed) { 140 bool BrowserPluginGuest::LockMouse(bool allowed) {
345 if (!attached() || (mouse_locked_ == allowed)) 141 if (!attached() || (mouse_locked_ == allowed))
346 return false; 142 return false;
347 143
348 return embedder_web_contents()->GotResponseToLockMouseRequest(allowed); 144 return embedder_web_contents()->GotResponseToLockMouseRequest(allowed);
349 } 145 }
350 146
351 void BrowserPluginGuest::EmbedderDestroyed() { 147 void BrowserPluginGuest::EmbedderDestroyed() {
352 embedder_web_contents_ = NULL; 148 embedder_web_contents_ = NULL;
353 if (delegate_) 149 if (delegate_)
354 delegate_->EmbedderDestroyed(); 150 delegate_->EmbedderDestroyed();
355 Destroy(); 151 Destroy();
356 } 152 }
357 153
358 void BrowserPluginGuest::Destroy() { 154 void BrowserPluginGuest::Destroy() {
359 is_in_destruction_ = true; 155 if (!delegate_)
360 if (!attached() && GetOpener()) 156 return;
361 GetOpener()->pending_new_windows_.erase(this); 157 delegate_->Destroy();
362 DestroyUnattachedWindows();
363 delete GetWebContents();
364 } 158 }
365 159
366 bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( 160 bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
367 const IPC::Message& message) { 161 const IPC::Message& message) {
368 bool handled = true; 162 bool handled = true;
369 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message) 163 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
370 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameSwappedACK, 164 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameSwappedACK,
371 OnCompositorFrameSwappedACK) 165 OnCompositorFrameSwappedACK)
372 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck, 166 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck,
373 OnCopyFromCompositingSurfaceAck) 167 OnCopyFromCompositingSurfaceAck)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 int guest_routing_id = 251 int guest_routing_id =
458 GetWebContents()->CreateSwappedOutRenderView( 252 GetWebContents()->CreateSwappedOutRenderView(
459 embedder_web_contents_->GetSiteInstance()); 253 embedder_web_contents_->GetSiteInstance());
460 SendMessageToEmbedder( 254 SendMessageToEmbedder(
461 new BrowserPluginMsg_GuestContentWindowReady(instance_id_, 255 new BrowserPluginMsg_GuestContentWindowReady(instance_id_,
462 guest_routing_id)); 256 guest_routing_id));
463 257
464 if (!params.src.empty()) { 258 if (!params.src.empty()) {
465 // params.src will be validated in BrowserPluginGuest::OnNavigateGuest. 259 // params.src will be validated in BrowserPluginGuest::OnNavigateGuest.
466 OnNavigateGuest(instance_id_, params.src); 260 OnNavigateGuest(instance_id_, params.src);
261 has_render_view_ = true;
467 } 262 }
468 263
469 has_render_view_ = true;
470
471 WebPreferences prefs = GetWebContents()->GetWebkitPrefs(); 264 WebPreferences prefs = GetWebContents()->GetWebkitPrefs();
472 prefs.navigate_on_drag_drop = false; 265 prefs.navigate_on_drag_drop = false;
473 GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs); 266 GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs);
474 267
475 // Enable input method for guest if it's enabled for the embedder. 268 // Enable input method for guest if it's enabled for the embedder.
476 if (static_cast<RenderViewHostImpl*>( 269 if (static_cast<RenderViewHostImpl*>(
477 embedder_web_contents_->GetRenderViewHost())->input_method_active()) { 270 embedder_web_contents_->GetRenderViewHost())->input_method_active()) {
478 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( 271 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
479 GetWebContents()->GetRenderViewHost()); 272 GetWebContents()->GetRenderViewHost());
480 guest_rvh->SetInputMethodActive(true); 273 guest_rvh->SetInputMethodActive(true);
(...skipping 20 matching lines...) Expand all
501 delete pending_messages_.front(); 294 delete pending_messages_.front();
502 pending_messages_.pop(); 295 pending_messages_.pop();
503 } 296 }
504 } 297 }
505 298
506 // static 299 // static
507 BrowserPluginGuest* BrowserPluginGuest::Create( 300 BrowserPluginGuest* BrowserPluginGuest::Create(
508 int instance_id, 301 int instance_id,
509 SiteInstance* guest_site_instance, 302 SiteInstance* guest_site_instance,
510 WebContentsImpl* web_contents, 303 WebContentsImpl* web_contents,
511 scoped_ptr<base::DictionaryValue> extra_params) { 304 scoped_ptr<base::DictionaryValue> extra_params,
305 BrowserPluginGuest* opener) {
512 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create")); 306 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create"));
513 BrowserPluginGuest* guest = NULL; 307 BrowserPluginGuest* guest = NULL;
514 if (factory_) { 308 if (factory_) {
515 guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents); 309 guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents);
516 } else { 310 } else {
517 guest = new BrowserPluginGuest(instance_id, false, web_contents); 311 guest = new BrowserPluginGuest(instance_id,
312 web_contents->opener() != NULL,
313 web_contents);
518 } 314 }
519 guest->extra_attach_params_.reset(extra_params->DeepCopy());
520 web_contents->SetBrowserPluginGuest(guest); 315 web_contents->SetBrowserPluginGuest(guest);
316 WebContents* opener_web_contents = NULL;
317 if (opener) {
318 opener_web_contents = opener->GetWebContents();
319 guest_site_instance = opener_web_contents->GetSiteInstance();
320 }
521 BrowserPluginGuestDelegate* delegate = NULL; 321 BrowserPluginGuestDelegate* delegate = NULL;
522 GetContentClient()->browser()->GuestWebContentsCreated( 322 GetContentClient()->browser()->GuestWebContentsCreated(
523 guest_site_instance, web_contents, NULL, &delegate, extra_params.Pass()); 323 instance_id,
524 guest->SetDelegate(delegate); 324 guest_site_instance,
325 web_contents,
326 opener_web_contents,
327 &delegate,
328 extra_params.Pass());
329 if (delegate) {
330 delegate->RegisterDestructionCallback(
331 base::Bind(&BrowserPluginGuest::WillDestroy,
332 base::Unretained(guest)));
333 guest->SetDelegate(delegate);
334 }
525 return guest; 335 return guest;
526 } 336 }
527 337
528 // static
529 BrowserPluginGuest* BrowserPluginGuest::CreateWithOpener(
530 int instance_id,
531 bool has_render_view,
532 WebContentsImpl* web_contents,
533 BrowserPluginGuest* opener) {
534 BrowserPluginGuest* guest =
535 new BrowserPluginGuest(
536 instance_id, has_render_view, web_contents);
537 web_contents->SetBrowserPluginGuest(guest);
538 BrowserPluginGuestDelegate* delegate = NULL;
539 GetContentClient()->browser()->GuestWebContentsCreated(
540 opener->GetWebContents()->GetSiteInstance(),
541 web_contents, opener->GetWebContents(), &delegate,
542 scoped_ptr<base::DictionaryValue>());
543 guest->SetDelegate(delegate);
544 return guest;
545 }
546
547 RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() { 338 RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() {
548 if (!attached()) 339 if (!attached())
549 return NULL; 340 return NULL;
550 return embedder_web_contents_->GetRenderWidgetHostView(); 341 return embedder_web_contents_->GetRenderWidgetHostView();
551 } 342 }
552 343
553 BrowserPluginGuest* BrowserPluginGuest::GetOpener() const {
554 if (!delegate_)
555 return NULL;
556
557 WebContents* opener = delegate_->GetOpener();
558 if (!opener)
559 return NULL;
560
561 return static_cast<WebContentsImpl*>(opener)->GetBrowserPluginGuest();
562 }
563
564 void BrowserPluginGuest::UpdateVisibility() { 344 void BrowserPluginGuest::UpdateVisibility() {
565 OnSetVisibility(instance_id_, visible()); 345 OnSetVisibility(instance_id_, visible());
566 } 346 }
567 347
568 void BrowserPluginGuest::CopyFromCompositingSurface( 348 void BrowserPluginGuest::CopyFromCompositingSurface(
569 gfx::Rect src_subrect, 349 gfx::Rect src_subrect,
570 gfx::Size dst_size, 350 gfx::Size dst_size,
571 const base::Callback<void(bool, const SkBitmap&)>& callback) { 351 const base::Callback<void(bool, const SkBitmap&)>& callback) {
572 copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback)); 352 copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback));
573 SendMessageToEmbedder( 353 SendMessageToEmbedder(
(...skipping 17 matching lines...) Expand all
591 embedder_visible_ = visible; 371 embedder_visible_ = visible;
592 UpdateVisibility(); 372 UpdateVisibility();
593 } 373 }
594 374
595 void BrowserPluginGuest::AddNewContents(WebContents* source, 375 void BrowserPluginGuest::AddNewContents(WebContents* source,
596 WebContents* new_contents, 376 WebContents* new_contents,
597 WindowOpenDisposition disposition, 377 WindowOpenDisposition disposition,
598 const gfx::Rect& initial_pos, 378 const gfx::Rect& initial_pos,
599 bool user_gesture, 379 bool user_gesture,
600 bool* was_blocked) { 380 bool* was_blocked) {
601 if (was_blocked) 381 if (!delegate_)
602 *was_blocked = false; 382 return;
603 RequestNewWindowPermission(disposition, initial_pos, user_gesture, 383
604 static_cast<WebContentsImpl*>(new_contents)); 384 delegate_->AddNewContents(source, new_contents, disposition,
385 initial_pos, user_gesture, was_blocked);
605 } 386 }
606 387
607 void BrowserPluginGuest::CanDownload( 388 void BrowserPluginGuest::CanDownload(
608 RenderViewHost* render_view_host, 389 RenderViewHost* render_view_host,
609 const GURL& url, 390 const GURL& url,
610 const std::string& request_method, 391 const std::string& request_method,
611 const base::Callback<void(bool)>& callback) { 392 const base::Callback<void(bool)>& callback) {
612 if (!delegate_ || !url.is_valid()) { 393 if (!delegate_ || !url.is_valid()) {
613 callback.Run(false); 394 callback.Run(false);
614 return; 395 return;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 return; 469 return;
689 470
690 // |selection_rect| is updated to incorporate embedder coordinates. 471 // |selection_rect| is updated to incorporate embedder coordinates.
691 delegate_->FindReply(request_id, number_of_matches, 472 delegate_->FindReply(request_id, number_of_matches,
692 ToGuestRect(selection_rect), 473 ToGuestRect(selection_rect),
693 active_match_ordinal, final_update); 474 active_match_ordinal, final_update);
694 } 475 }
695 476
696 WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source, 477 WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source,
697 const OpenURLParams& params) { 478 const OpenURLParams& params) {
698 // If the guest wishes to navigate away prior to attachment then we save the 479 if (!delegate_)
699 // navigation to perform upon attachment. Navigation initializes a lot of
700 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest.
701 // Navigation also resumes resource loading which we don't want to allow
702 // until attachment.
703 if (!attached()) {
704 PendingWindowMap::iterator it =
705 GetOpener()->pending_new_windows_.find(this);
706 if (it == GetOpener()->pending_new_windows_.end())
707 return NULL;
708 const NewWindowInfo& old_target_url = it->second;
709 NewWindowInfo new_window_info(params.url, old_target_url.name);
710 new_window_info.changed = new_window_info.url != old_target_url.url;
711 it->second = new_window_info;
712 return NULL; 480 return NULL;
713 } 481 return delegate_->OpenURLFromTab(source, params);
714 if (params.disposition == CURRENT_TAB) {
715 // This can happen for cross-site redirects.
716 LoadURLWithParams(params.url, params.referrer, params.transition, source);
717 return source;
718 }
719
720 return CreateNewGuestWindow(params)->GetWebContents();
721 } 482 }
722 483
723 void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents, 484 void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents,
724 int opener_render_frame_id, 485 int opener_render_frame_id,
725 const base::string16& frame_name, 486 const base::string16& frame_name,
726 const GURL& target_url, 487 const GURL& target_url,
727 WebContents* new_contents) { 488 WebContents* new_contents) {
728 WebContentsImpl* new_contents_impl = 489 WebContentsImpl* new_contents_impl =
729 static_cast<WebContentsImpl*>(new_contents); 490 static_cast<WebContentsImpl*>(new_contents);
730 BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest(); 491 BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest();
731 if (guest->delegate_)
732 guest->delegate_->SetOpener(GetWebContents());
733 std::string guest_name = base::UTF16ToUTF8(frame_name); 492 std::string guest_name = base::UTF16ToUTF8(frame_name);
734 guest->name_ = guest_name; 493 guest->name_ = guest_name;
735 // Take ownership of the new guest until it is attached to the embedder's DOM 494
736 // tree to avoid leaking a guest if this guest is destroyed before attaching 495 if (!delegate_)
737 // the new guest. 496 return;
738 pending_new_windows_.insert( 497
739 std::make_pair(guest, NewWindowInfo(target_url, guest_name))); 498 delegate_->WebContentsCreated(source_contents,
499 opener_render_frame_id,
500 frame_name,
501 target_url,
502 new_contents);
740 } 503 }
741 504
742 void BrowserPluginGuest::RendererUnresponsive(WebContents* source) { 505 void BrowserPluginGuest::RendererUnresponsive(WebContents* source) {
743 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Hung")); 506 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Hung"));
744 if (!delegate_) 507 if (!delegate_)
745 return; 508 return;
746 delegate_->RendererUnresponsive(); 509 delegate_->RendererUnresponsive();
747 } 510 }
748 511
749 void BrowserPluginGuest::RendererResponsive(WebContents* source) { 512 void BrowserPluginGuest::RendererResponsive(WebContents* source) {
(...skipping 25 matching lines...) Expand all
775 gfx::Point screen_pos(relative_position); 538 gfx::Point screen_pos(relative_position);
776 screen_pos += guest_window_rect_.OffsetFromOrigin(); 539 screen_pos += guest_window_rect_.OffsetFromOrigin();
777 return screen_pos; 540 return screen_pos;
778 } 541 }
779 542
780 bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const { 543 bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const {
781 return size.width() <= max_auto_size_.width() && 544 return size.width() <= max_auto_size_.width() &&
782 size.height() <= max_auto_size_.height(); 545 size.height() <= max_auto_size_.height();
783 } 546 }
784 547
785 void BrowserPluginGuest::RequestNewWindowPermission(
786 WindowOpenDisposition disposition,
787 const gfx::Rect& initial_bounds,
788 bool user_gesture,
789 WebContentsImpl* new_contents) {
790 BrowserPluginGuest* guest = new_contents->GetBrowserPluginGuest();
791 PendingWindowMap::iterator it = pending_new_windows_.find(guest);
792 if (it == pending_new_windows_.end())
793 return;
794 const NewWindowInfo& new_window_info = it->second;
795
796 base::DictionaryValue request_info;
797 request_info.Set(browser_plugin::kInitialHeight,
798 base::Value::CreateIntegerValue(initial_bounds.height()));
799 request_info.Set(browser_plugin::kInitialWidth,
800 base::Value::CreateIntegerValue(initial_bounds.width()));
801 request_info.Set(browser_plugin::kTargetURL,
802 base::Value::CreateStringValue(new_window_info.url.spec()));
803 request_info.Set(browser_plugin::kName,
804 base::Value::CreateStringValue(new_window_info.name));
805 request_info.Set(browser_plugin::kWindowID,
806 base::Value::CreateIntegerValue(guest->instance_id()));
807 request_info.Set(browser_plugin::kWindowOpenDisposition,
808 base::Value::CreateStringValue(
809 WindowOpenDispositionToString(disposition)));
810
811 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW,
812 new NewWindowRequest(weak_ptr_factory_.GetWeakPtr(),
813 guest->instance_id()),
814 request_info);
815 }
816
817 void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) { 548 void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) {
818 if (!attached()) { 549 if (!attached()) {
819 // Some pages such as data URLs, javascript URLs, and about:blank 550 // Some pages such as data URLs, javascript URLs, and about:blank
820 // do not load external resources and so they load prior to attachment. 551 // do not load external resources and so they load prior to attachment.
821 // As a result, we must save all these IPCs until attachment and then 552 // As a result, we must save all these IPCs until attachment and then
822 // forward them so that the embedder gets a chance to see and process 553 // forward them so that the embedder gets a chance to see and process
823 // the load events. 554 // the load events.
824 pending_messages_.push(msg); 555 pending_messages_.push(msg);
825 return; 556 return;
826 } 557 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 case base::TERMINATION_STATUS_PROCESS_CRASHED: 640 case base::TERMINATION_STATUS_PROCESS_CRASHED:
910 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed")); 641 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed"));
911 break; 642 break;
912 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: 643 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
913 RecordAction( 644 RecordAction(
914 base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath")); 645 base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath"));
915 break; 646 break;
916 default: 647 default:
917 break; 648 break;
918 } 649 }
919 // TODO(fsamuel): Consider whether we should be clearing
920 // |permission_request_map_| here.
921 if (delegate_) 650 if (delegate_)
922 delegate_->GuestProcessGone(status); 651 delegate_->GuestProcessGone(status);
923 } 652 }
924 653
925 // static 654 // static
926 bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest( 655 bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(
927 const IPC::Message& message) { 656 const IPC::Message& message) {
928 switch (message.type()) { 657 switch (message.type()) {
929 case BrowserPluginHostMsg_CompositorFrameSwappedACK::ID: 658 case BrowserPluginHostMsg_CompositorFrameSwappedACK::ID:
930 case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID: 659 case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 return handled; 713 return handled;
985 } 714 }
986 715
987 void BrowserPluginGuest::Attach( 716 void BrowserPluginGuest::Attach(
988 WebContentsImpl* embedder_web_contents, 717 WebContentsImpl* embedder_web_contents,
989 BrowserPluginHostMsg_Attach_Params params, 718 BrowserPluginHostMsg_Attach_Params params,
990 const base::DictionaryValue& extra_params) { 719 const base::DictionaryValue& extra_params) {
991 if (attached()) 720 if (attached())
992 return; 721 return;
993 722
994 extra_attach_params_.reset(extra_params.DeepCopy());
995
996 // Clear parameters that get inherited from the opener. 723 // Clear parameters that get inherited from the opener.
997 params.storage_partition_id.clear(); 724 params.storage_partition_id.clear();
998 params.persist_storage = false; 725 params.persist_storage = false;
999 params.src.clear(); 726 params.src.clear();
1000 727
1001 // If a RenderView has already been created for this new window, then we need 728 // If a RenderView has already been created for this new window, then we need
1002 // to initialize the browser-side state now so that the RenderFrameHostManager 729 // to initialize the browser-side state now so that the RenderFrameHostManager
1003 // does not create a new RenderView on navigation. 730 // does not create a new RenderView on navigation.
1004 if (has_render_view_) { 731 if (has_render_view_) {
1005 static_cast<RenderViewHostImpl*>( 732 static_cast<RenderViewHostImpl*>(
1006 GetWebContents()->GetRenderViewHost())->Init(); 733 GetWebContents()->GetRenderViewHost())->Init();
1007 WebContentsViewGuest* new_view = 734 WebContentsViewGuest* new_view =
1008 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView()); 735 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
1009 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost()); 736 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost());
1010 } 737 }
1011 738
1012 // We need to do a navigation here if the target URL has changed between
1013 // the time the WebContents was created and the time it was attached.
1014 // We also need to do an initial navigation if a RenderView was never
1015 // created for the new window in cases where there is no referrer.
1016 PendingWindowMap::iterator it = GetOpener()->pending_new_windows_.find(this);
1017 if (it != GetOpener()->pending_new_windows_.end()) {
1018 const NewWindowInfo& new_window_info = it->second;
1019 if (new_window_info.changed || !has_render_view_)
1020 params.src = it->second.url.spec();
1021 } else {
1022 NOTREACHED();
1023 }
1024
1025 // Once a new guest is attached to the DOM of the embedder page, then the
1026 // lifetime of the new guest is no longer managed by the opener guest.
1027 GetOpener()->pending_new_windows_.erase(this);
1028
1029 // The guest's frame name takes precedence over the BrowserPlugin's name. 739 // The guest's frame name takes precedence over the BrowserPlugin's name.
1030 // The guest's frame name is assigned in 740 // The guest's frame name is assigned in
1031 // BrowserPluginGuest::WebContentsCreated. 741 // BrowserPluginGuest::WebContentsCreated.
1032 if (!name_.empty()) 742 if (!name_.empty())
1033 params.name.clear(); 743 params.name.clear();
1034 744
1035 Initialize(params, embedder_web_contents); 745 Initialize(params, embedder_web_contents);
1036 746
1037 SendQueuedMessages(); 747 SendQueuedMessages();
1038 748
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 weak_ptr_factory_.GetWeakPtr())); 908 weak_ptr_factory_.GetWeakPtr()));
1199 } 909 }
1200 910
1201 void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) { 911 void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) {
1202 Send(new ViewMsg_LockMouse_ACK(routing_id(), succeeded)); 912 Send(new ViewMsg_LockMouse_ACK(routing_id(), succeeded));
1203 pending_lock_request_ = false; 913 pending_lock_request_ = false;
1204 if (succeeded) 914 if (succeeded)
1205 mouse_locked_ = true; 915 mouse_locked_ = true;
1206 } 916 }
1207 917
1208 void BrowserPluginGuest::OnNavigateGuest( 918 void BrowserPluginGuest::OnNavigateGuest(int instance_id,
1209 int instance_id, 919 const std::string& src) {
1210 const std::string& src) { 920 if (!delegate_)
1211 GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src);
1212
1213 // Do not allow navigating a guest to schemes other than known safe schemes.
1214 // This will block the embedder trying to load unwanted schemes, e.g.
1215 // chrome://settings.
1216 bool scheme_is_blocked =
1217 (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme(
1218 url.scheme()) &&
1219 !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme(
1220 url.scheme())) ||
1221 url.SchemeIs(kJavaScriptScheme);
1222 if (scheme_is_blocked || !url.is_valid()) {
1223 if (delegate_) {
1224 std::string error_type;
1225 base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::",
1226 &error_type);
1227 delegate_->LoadAbort(true /* is_top_level */, url, error_type);
1228 }
1229 return; 921 return;
1230 } 922 delegate_->NavigateGuest(src);
1231
1232 GURL validated_url(url);
1233 GetWebContents()->GetRenderProcessHost()->FilterURL(false, &validated_url);
1234 // As guests do not swap processes on navigation, only navigations to
1235 // normal web URLs are supported. No protocol handlers are installed for
1236 // other schemes (e.g., WebUI or extensions), and no permissions or bindings
1237 // can be granted to the guest process.
1238 LoadURLWithParams(validated_url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL,
1239 GetWebContents());
1240 } 923 }
1241 924
1242 void BrowserPluginGuest::OnPluginDestroyed(int instance_id) { 925 void BrowserPluginGuest::OnPluginDestroyed(int instance_id) {
1243 Destroy(); 926 Destroy();
1244 } 927 }
1245 928
1246 void BrowserPluginGuest::OnResizeGuest( 929 void BrowserPluginGuest::OnResizeGuest(
1247 int instance_id, 930 int instance_id,
1248 const BrowserPluginHostMsg_ResizeGuest_Params& params) { 931 const BrowserPluginHostMsg_ResizeGuest_Params& params) {
1249 if (!params.size_changed) 932 if (!params.size_changed)
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 void BrowserPluginGuest::OnImeCompositionRangeChanged( 1182 void BrowserPluginGuest::OnImeCompositionRangeChanged(
1500 const gfx::Range& range, 1183 const gfx::Range& range,
1501 const std::vector<gfx::Rect>& character_bounds) { 1184 const std::vector<gfx::Rect>& character_bounds) {
1502 static_cast<RenderWidgetHostViewBase*>( 1185 static_cast<RenderWidgetHostViewBase*>(
1503 web_contents()->GetRenderWidgetHostView())->ImeCompositionRangeChanged( 1186 web_contents()->GetRenderWidgetHostView())->ImeCompositionRangeChanged(
1504 range, character_bounds); 1187 range, character_bounds);
1505 } 1188 }
1506 #endif 1189 #endif
1507 1190
1508 } // namespace content 1191 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698