blob: 3ec1a0a5157e5db5692d7a3c3ff32d94d8fe77a1 [file] [log] [blame]
[email protected]7a846df2012-09-20 19:17:391// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/browser_plugin/browser_plugin_guest.h"
6
7#include <algorithm>
8
[email protected]95f861e2013-07-18 02:07:179#include "base/message_loop/message_loop.h"
[email protected]10994d132013-06-11 07:16:1810#include "base/strings/string_util.h"
[email protected]74ebfb12013-06-07 20:48:0011#include "base/strings/utf_string_conversions.h"
[email protected]c88b2a562012-10-27 03:36:5612#include "content/browser/browser_plugin/browser_plugin_embedder.h"
[email protected]8eb04562013-03-06 03:41:1413#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
[email protected]7a846df2012-09-20 19:17:3914#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
[email protected]f85f5032013-04-03 09:01:5415#include "content/browser/browser_thread_impl.h"
[email protected]4b499622013-08-22 02:25:5916#include "content/browser/child_process_security_policy_impl.h"
[email protected]e5e438d62014-03-27 21:47:1617#include "content/browser/frame_host/render_frame_host_impl.h"
[email protected]63c33bd62014-02-08 04:45:4018#include "content/browser/frame_host/render_widget_host_view_guest.h"
[email protected]f85f5032013-04-03 09:01:5419#include "content/browser/loader/resource_dispatcher_host_impl.h"
[email protected]7a846df2012-09-20 19:17:3920#include "content/browser/renderer_host/render_view_host_impl.h"
21#include "content/browser/renderer_host/render_widget_host_impl.h"
22#include "content/browser/web_contents/web_contents_impl.h"
[email protected]c4538072013-03-18 02:17:5523#include "content/browser/web_contents/web_contents_view_guest.h"
[email protected]8eb04562013-03-06 03:41:1424#include "content/common/browser_plugin/browser_plugin_constants.h"
[email protected]703dd662013-03-05 07:37:4225#include "content/common/browser_plugin/browser_plugin_messages.h"
[email protected]f8501b12012-12-07 04:55:4326#include "content/common/content_constants_internal.h"
[email protected]a7fac9a2012-12-18 23:26:0727#include "content/common/drag_messages.h"
[email protected]cc8ed212013-02-07 22:31:0328#include "content/common/gpu/gpu_messages.h"
[email protected]c084330e02013-04-27 01:08:1529#include "content/common/input_messages.h"
[email protected]c006fb52013-03-01 09:36:4530#include "content/common/view_messages.h"
[email protected]972cdd82012-10-12 00:19:0331#include "content/port/browser/render_view_host_delegate_view.h"
[email protected]d260f042013-12-14 01:31:3632#include "content/port/browser/render_widget_host_view_port.h"
[email protected]8eb04562013-03-06 03:41:1433#include "content/public/browser/browser_context.h"
[email protected]44703cc72013-01-24 04:56:0634#include "content/public/browser/content_browser_client.h"
[email protected]0d2f55e92013-09-26 03:13:1735#include "content/public/browser/navigation_controller.h"
[email protected]7a846df2012-09-20 19:17:3936#include "content/public/browser/render_process_host.h"
37#include "content/public/browser/render_widget_host_view.h"
[email protected]31942c82012-10-05 17:01:5438#include "content/public/browser/resource_request_details.h"
[email protected]2fae2c42012-10-03 21:20:0439#include "content/public/browser/user_metrics.h"
[email protected]e0c6dc92013-10-10 21:17:5140#include "content/public/browser/web_contents_observer.h"
[email protected]1a0c0052012-11-05 21:06:2641#include "content/public/browser/web_contents_view.h"
[email protected]dc293a72013-07-01 11:11:2242#include "content/public/common/drop_data.h"
[email protected]c006fb52013-03-01 09:36:4543#include "content/public/common/media_stream_request.h"
[email protected]7a846df2012-09-20 19:17:3944#include "content/public/common/result_codes.h"
[email protected]737540d92013-09-20 16:38:2145#include "content/public/common/url_constants.h"
[email protected]4b499622013-08-22 02:25:5946#include "content/public/common/url_utils.h"
[email protected]f85f5032013-04-03 09:01:5447#include "net/url_request/url_request.h"
[email protected]ec173b522013-11-14 11:01:1848#include "third_party/WebKit/public/platform/WebCursorInfo.h"
[email protected]7e9acd082013-09-17 23:31:1649#include "ui/events/keycodes/keyboard_codes.h"
[email protected]7a846df2012-09-20 19:17:3950#include "ui/surface/transport_dib.h"
[email protected]d0fcff72013-07-23 02:45:4351#include "webkit/common/resource_type.h"
[email protected]7a846df2012-09-20 19:17:3952
[email protected]4f89d9d2012-12-12 01:38:4853#if defined(OS_MACOSX)
54#include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h"
55#endif
56
[email protected]7a846df2012-09-20 19:17:3957namespace content {
58
59// static
60BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL;
61
[email protected]cf4c9e052013-05-04 04:53:4462// Parent class for the various types of permission requests, each of which
63// should be able to handle the response to their permission request.
[email protected]291dcf32013-07-28 08:02:1464class BrowserPluginGuest::PermissionRequest :
65 public base::RefCounted<BrowserPluginGuest::PermissionRequest> {
[email protected]cf4c9e052013-05-04 04:53:4466 public:
[email protected]bfb9e9a2014-01-29 22:36:1867 void Respond(bool should_allow, const std::string& user_input) {
68 if (!guest_)
69 return;
70 RespondImpl(should_allow, user_input);
71 }
[email protected]cf013512013-10-16 06:33:0572 virtual bool AllowedByDefault() const {
[email protected]c61b317c72013-11-14 06:40:4673 return false;
[email protected]cf013512013-10-16 06:33:0574 }
[email protected]cf4c9e052013-05-04 04:53:4475 protected:
[email protected]bfb9e9a2014-01-29 22:36:1876 explicit PermissionRequest(const base::WeakPtr<BrowserPluginGuest>& guest)
77 : guest_(guest) {
[email protected]e6e30ac2014-01-13 21:24:3978 RecordAction(
79 base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest"));
[email protected]abc7d5c2013-05-15 09:19:2580 }
[email protected]291dcf32013-07-28 08:02:1481 virtual ~PermissionRequest() {}
[email protected]bfb9e9a2014-01-29 22:36:1882
83 virtual void RespondImpl(bool should_allow,
84 const std::string& user_input) = 0;
[email protected]291dcf32013-07-28 08:02:1485 // Friend RefCounted so that the dtor can be non-public.
86 friend class base::RefCounted<BrowserPluginGuest::PermissionRequest>;
[email protected]bfb9e9a2014-01-29 22:36:1887
88 base::WeakPtr<BrowserPluginGuest> guest_;
[email protected]cf4c9e052013-05-04 04:53:4489};
90
[email protected]cf4c9e052013-05-04 04:53:4491class BrowserPluginGuest::NewWindowRequest : public PermissionRequest {
92 public:
[email protected]bfb9e9a2014-01-29 22:36:1893 NewWindowRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
94 int instance_id)
95 : PermissionRequest(guest),
96 instance_id_(instance_id) {
[email protected]dadac572013-06-12 22:52:0297 RecordAction(
[email protected]e6e30ac2014-01-13 21:24:3998 base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.NewWindow"));
[email protected]dadac572013-06-12 22:52:0299 }
[email protected]cf4c9e052013-05-04 04:53:44100
[email protected]bfb9e9a2014-01-29 22:36:18101 virtual void RespondImpl(bool should_allow,
102 const std::string& user_input) OVERRIDE {
[email protected]cf4c9e052013-05-04 04:53:44103 int embedder_render_process_id =
104 guest_->embedder_web_contents()->GetRenderProcessHost()->GetID();
105 BrowserPluginGuest* guest =
106 guest_->GetWebContents()->GetBrowserPluginGuestManager()->
107 GetGuestByInstanceID(instance_id_, embedder_render_process_id);
108 if (!guest) {
[email protected]efde84b02013-11-23 04:18:20109 VLOG(0) << "Guest not found. Instance ID: " << instance_id_;
[email protected]cf4c9e052013-05-04 04:53:44110 return;
111 }
112
113 // If we do not destroy the guest then we allow the new window.
114 if (!should_allow)
115 guest->Destroy();
116 }
[email protected]b60b88942013-07-20 05:58:42117
[email protected]cf4c9e052013-05-04 04:53:44118 private:
[email protected]291dcf32013-07-28 08:02:14119 virtual ~NewWindowRequest() {}
[email protected]cf4c9e052013-05-04 04:53:44120 int instance_id_;
[email protected]cf4c9e052013-05-04 04:53:44121};
122
[email protected]1c514fc2013-07-24 07:30:53123class BrowserPluginGuest::JavaScriptDialogRequest : public PermissionRequest {
124 public:
[email protected]bfb9e9a2014-01-29 22:36:18125 JavaScriptDialogRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
126 const DialogClosedCallback& callback)
127 : PermissionRequest(guest),
128 callback_(callback) {
[email protected]1c514fc2013-07-24 07:30:53129 RecordAction(
[email protected]e6e30ac2014-01-13 21:24:39130 base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.JSDialog"));
[email protected]1c514fc2013-07-24 07:30:53131 }
132
[email protected]bfb9e9a2014-01-29 22:36:18133 virtual void RespondImpl(bool should_allow,
134 const std::string& user_input) OVERRIDE {
[email protected]32956122013-12-25 07:29:24135 callback_.Run(should_allow, base::UTF8ToUTF16(user_input));
[email protected]1c514fc2013-07-24 07:30:53136 }
137
[email protected]1c514fc2013-07-24 07:30:53138 private:
[email protected]291dcf32013-07-28 08:02:14139 virtual ~JavaScriptDialogRequest() {}
140 DialogClosedCallback callback_;
[email protected]1c514fc2013-07-24 07:30:53141};
142
[email protected]c006fb52013-03-01 09:36:45143namespace {
[email protected]1c514fc2013-07-24 07:30:53144std::string WindowOpenDispositionToString(
[email protected]c4538072013-03-18 02:17:55145 WindowOpenDisposition window_open_disposition) {
146 switch (window_open_disposition) {
[email protected]1c514fc2013-07-24 07:30:53147 case IGNORE_ACTION:
148 return "ignore";
149 case SAVE_TO_DISK:
150 return "save_to_disk";
151 case CURRENT_TAB:
152 return "current_tab";
153 case NEW_BACKGROUND_TAB:
154 return "new_background_tab";
155 case NEW_FOREGROUND_TAB:
156 return "new_foreground_tab";
157 case NEW_WINDOW:
158 return "new_window";
159 case NEW_POPUP:
160 return "new_popup";
161 default:
162 NOTREACHED() << "Unknown Window Open Disposition";
163 return "ignore";
164 }
165}
166
167std::string JavaScriptMessageTypeToString(JavaScriptMessageType message_type) {
168 switch (message_type) {
169 case JAVASCRIPT_MESSAGE_TYPE_ALERT:
170 return "alert";
171 case JAVASCRIPT_MESSAGE_TYPE_CONFIRM:
172 return "confirm";
173 case JAVASCRIPT_MESSAGE_TYPE_PROMPT:
174 return "prompt";
175 default:
176 NOTREACHED() << "Unknown JavaScript Message Type.";
177 return "unknown";
[email protected]c4538072013-03-18 02:17:55178 }
179}
180
[email protected]f85f5032013-04-03 09:01:54181// Called on IO thread.
[email protected]922bd4ab2014-04-16 05:02:38182static GURL RetrieveDownloadURLFromRequestId(
183 int render_process_id,
[email protected]f85f5032013-04-03 09:01:54184 int url_request_id) {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
186
[email protected]f85f5032013-04-03 09:01:54187 GlobalRequestID global_id(render_process_id, url_request_id);
188 net::URLRequest* url_request =
189 ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
190 if (url_request)
[email protected]922bd4ab2014-04-16 05:02:38191 return url_request->url();
192 return GURL();
[email protected]f85f5032013-04-03 09:01:54193}
194
[email protected]cf4c9e052013-05-04 04:53:44195} // namespace
[email protected]c006fb52013-03-01 09:36:45196
[email protected]e0c6dc92013-10-10 21:17:51197class BrowserPluginGuest::EmbedderWebContentsObserver
198 : public WebContentsObserver {
[email protected]ce0e2602013-03-15 20:53:27199 public:
[email protected]e0c6dc92013-10-10 21:17:51200 explicit EmbedderWebContentsObserver(BrowserPluginGuest* guest)
201 : WebContentsObserver(guest->embedder_web_contents()),
[email protected]ce0e2602013-03-15 20:53:27202 browser_plugin_guest_(guest) {
203 }
204
[email protected]e0c6dc92013-10-10 21:17:51205 virtual ~EmbedderWebContentsObserver() {
[email protected]ce0e2602013-03-15 20:53:27206 }
207
[email protected]e0c6dc92013-10-10 21:17:51208 // WebContentsObserver:
209 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
[email protected]8f6727ec2013-09-14 00:03:17210 browser_plugin_guest_->EmbedderDestroyed();
[email protected]ce0e2602013-03-15 20:53:27211 }
212
[email protected]e0c6dc92013-10-10 21:17:51213 virtual void WasShown() OVERRIDE {
214 browser_plugin_guest_->EmbedderVisibilityChanged(true);
215 }
216
217 virtual void WasHidden() OVERRIDE {
218 browser_plugin_guest_->EmbedderVisibilityChanged(false);
219 }
220
[email protected]ce0e2602013-03-15 20:53:27221 private:
222 BrowserPluginGuest* browser_plugin_guest_;
223
[email protected]e0c6dc92013-10-10 21:17:51224 DISALLOW_COPY_AND_ASSIGN(EmbedderWebContentsObserver);
[email protected]ce0e2602013-03-15 20:53:27225};
226
[email protected]dd8c8232012-11-03 00:49:36227BrowserPluginGuest::BrowserPluginGuest(
228 int instance_id,
[email protected]c61b317c72013-11-14 06:40:46229 bool has_render_view,
[email protected]0c6d41752013-05-01 15:49:09230 WebContentsImpl* web_contents,
[email protected]c61b317c72013-11-14 06:40:46231 BrowserPluginGuest* opener)
[email protected]7a846df2012-09-20 19:17:39232 : WebContentsObserver(web_contents),
[email protected]8eb04562013-03-06 03:41:14233 embedder_web_contents_(NULL),
[email protected]7a846df2012-09-20 19:17:39234 instance_id_(instance_id),
[email protected]4d1afd62012-12-21 03:09:40235 damage_buffer_sequence_id_(0),
[email protected]7a846df2012-09-20 19:17:39236 damage_buffer_size_(0),
[email protected]fda17082012-10-04 00:25:21237 damage_buffer_scale_factor_(1.0f),
[email protected]caaf2482013-05-01 20:33:32238 guest_device_scale_factor_(1.0f),
[email protected]7a846df2012-09-20 19:17:39239 guest_hang_timeout_(
[email protected]f8501b12012-12-07 04:55:43240 base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
[email protected]c4538072013-03-18 02:17:55241 focused_(false),
[email protected]861f9782013-03-05 03:29:54242 mouse_locked_(false),
[email protected]a25acea72013-03-10 23:41:28243 pending_lock_request_(false),
[email protected]93564f72013-02-15 13:26:19244 embedder_visible_(true),
[email protected]5d797b82014-03-14 22:36:03245 auto_size_enabled_(false),
[email protected]73405fb2013-12-11 04:59:37246 copy_request_id_(0),
[email protected]af1718c2013-08-12 19:59:19247 next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID),
[email protected]63449722013-08-13 02:31:32248 has_render_view_(has_render_view),
[email protected]3f6fa6d42013-08-16 21:19:49249 last_seen_auto_size_enabled_(false),
[email protected]f21d36e2014-01-16 19:24:04250 is_in_destruction_(false),
[email protected]63c33bd62014-02-08 04:45:40251 last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
252 last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
253 last_can_compose_inline_(true),
[email protected]f21d36e2014-01-16 19:24:04254 weak_ptr_factory_(this) {
[email protected]7a846df2012-09-20 19:17:39255 DCHECK(web_contents);
[email protected]93564f72013-02-15 13:26:19256 web_contents->SetDelegate(this);
[email protected]0c6d41752013-05-01 15:49:09257 if (opener)
258 opener_ = opener->AsWeakPtr();
[email protected]8eb04562013-03-06 03:41:14259 GetWebContents()->GetBrowserPluginGuestManager()->AddGuest(instance_id_,
260 GetWebContents());
[email protected]b5a40842012-11-28 15:26:11261}
262
[email protected]eb72af632013-04-30 01:05:21263bool BrowserPluginGuest::AddMessageToConsole(WebContents* source,
264 int32 level,
[email protected]fcf75d42013-12-03 20:11:26265 const base::string16& message,
[email protected]eb72af632013-04-30 01:05:21266 int32 line_no,
[email protected]fcf75d42013-12-03 20:11:26267 const base::string16& source_id) {
[email protected]4c0e8272013-07-03 23:39:22268 if (!delegate_)
269 return false;
270
271 delegate_->AddMessageToConsole(level, message, line_no, source_id);
272 return true;
[email protected]eb72af632013-04-30 01:05:21273}
274
[email protected]c4538072013-03-18 02:17:55275void BrowserPluginGuest::DestroyUnattachedWindows() {
276 // Destroy() reaches in and removes the BrowserPluginGuest from its opener's
277 // pending_new_windows_ set. To avoid mutating the set while iterating, we
278 // create a copy of the pending new windows set and iterate over the copy.
279 PendingWindowMap pending_new_windows(pending_new_windows_);
280 // Clean up unattached new windows opened by this guest.
281 for (PendingWindowMap::const_iterator it = pending_new_windows.begin();
282 it != pending_new_windows.end(); ++it) {
283 it->first->Destroy();
284 }
285 // All pending windows should be removed from the set after Destroy() is
286 // called on all of them.
[email protected]c61b317c72013-11-14 06:40:46287 DCHECK(pending_new_windows_.empty());
[email protected]c4538072013-03-18 02:17:55288}
289
[email protected]c61b317c72013-11-14 06:40:46290void BrowserPluginGuest::LoadURLWithParams(const GURL& url,
[email protected]0d2f55e92013-09-26 03:13:17291 const Referrer& referrer,
[email protected]c61b317c72013-11-14 06:40:46292 PageTransition transition_type,
293 WebContents* web_contents) {
[email protected]7fdb6ac2014-02-07 18:33:32294 NavigationController::LoadURLParams load_url_params(url);
[email protected]0d2f55e92013-09-26 03:13:17295 load_url_params.referrer = referrer;
296 load_url_params.transition_type = transition_type;
297 load_url_params.extra_headers = std::string();
298 if (delegate_ && delegate_->IsOverridingUserAgent()) {
299 load_url_params.override_user_agent =
300 NavigationController::UA_OVERRIDE_TRUE;
301 }
302 web_contents->GetController().LoadURLWithParams(load_url_params);
303}
304
[email protected]af1718c2013-08-12 19:59:19305void BrowserPluginGuest::RespondToPermissionRequest(
306 int request_id,
307 bool should_allow,
308 const std::string& user_input) {
309 RequestMap::iterator request_itr = permission_request_map_.find(request_id);
310 if (request_itr == permission_request_map_.end()) {
[email protected]efde84b02013-11-23 04:18:20311 VLOG(0) << "Not a valid request ID.";
[email protected]af1718c2013-08-12 19:59:19312 return;
313 }
314 request_itr->second->Respond(should_allow, user_input);
315 permission_request_map_.erase(request_itr);
316}
317
[email protected]f9966b02014-04-15 18:19:45318void BrowserPluginGuest::RequestPermission(
[email protected]291dcf32013-07-28 08:02:14319 BrowserPluginPermissionType permission_type,
320 scoped_refptr<BrowserPluginGuest::PermissionRequest> request,
321 const base::DictionaryValue& request_info) {
[email protected]af1718c2013-08-12 19:59:19322 if (!delegate_) {
[email protected]bfb9e9a2014-01-29 22:36:18323 // Let the stack unwind before we deny the permission request so that
324 // objects held by the permission request are not destroyed immediately
325 // after creation. This is to allow those same objects to be accessed again
326 // in the same scope without fear of use after freeing.
327 base::MessageLoop::current()->PostTask(
328 FROM_HERE,
329 base::Bind(&BrowserPluginGuest::PermissionRequest::Respond,
330 request, false, ""));
[email protected]af1718c2013-08-12 19:59:19331 }
332
333 int request_id = ++next_permission_request_id_;
[email protected]291dcf32013-07-28 08:02:14334 permission_request_map_[request_id] = request;
335
[email protected]af1718c2013-08-12 19:59:19336 BrowserPluginGuestDelegate::PermissionResponseCallback callback =
337 base::Bind(&BrowserPluginGuest::RespondToPermissionRequest,
338 AsWeakPtr(),
339 request_id);
[email protected]f9966b02014-04-15 18:19:45340 delegate_->RequestPermission(
341 permission_type, request_info, callback, request->AllowedByDefault());
[email protected]291dcf32013-07-28 08:02:14342}
343
[email protected]538334712013-09-14 21:29:01344BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow(
345 const OpenURLParams& params) {
346 BrowserPluginGuestManager* guest_manager =
347 GetWebContents()->GetBrowserPluginGuestManager();
348
349 // Allocate a new instance ID for the new guest.
350 int instance_id = guest_manager->get_next_instance_id();
351
352 // Set the attach params to use the same partition as the opener.
353 // We pull the partition information from the site's URL, which is of the form
354 // guest://site/{persist}?{partition_name}.
355 const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL();
356 BrowserPluginHostMsg_Attach_Params attach_params;
357 attach_params.storage_partition_id = site_url.query();
358 attach_params.persist_storage =
359 site_url.path().find("persist") != std::string::npos;
360
361 // The new guest gets a copy of this guest's extra params so that the content
362 // embedder exposes the same API for this guest as its opener.
363 scoped_ptr<base::DictionaryValue> extra_params(
364 extra_attach_params_->DeepCopy());
365 BrowserPluginGuest* new_guest =
366 GetWebContents()->GetBrowserPluginGuestManager()->CreateGuest(
367 GetWebContents()->GetSiteInstance(), instance_id,
368 attach_params, extra_params.Pass());
369 new_guest->opener_ = AsWeakPtr();
370
371 // Take ownership of |new_guest|.
372 pending_new_windows_.insert(
373 std::make_pair(new_guest, NewWindowInfo(params.url, std::string())));
374
375 // Request permission to show the new window.
[email protected]c61b317c72013-11-14 06:40:46376 RequestNewWindowPermission(params.disposition, gfx::Rect(),
377 params.user_gesture, new_guest->GetWebContents());
[email protected]538334712013-09-14 21:29:01378
379 return new_guest;
380}
381
[email protected]8fb60c32014-02-02 17:46:40382base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() {
383 return weak_ptr_factory_.GetWeakPtr();
384}
385
[email protected]8f6727ec2013-09-14 00:03:17386void BrowserPluginGuest::EmbedderDestroyed() {
387 embedder_web_contents_ = NULL;
388 if (delegate_)
389 delegate_->EmbedderDestroyed();
390 Destroy();
391}
392
[email protected]b371a5652013-02-20 11:25:51393void BrowserPluginGuest::Destroy() {
[email protected]3f6fa6d42013-08-16 21:19:49394 is_in_destruction_ = true;
[email protected]c4538072013-03-18 02:17:55395 if (!attached() && opener())
396 opener()->pending_new_windows_.erase(this);
397 DestroyUnattachedWindows();
[email protected]8eb04562013-03-06 03:41:14398 GetWebContents()->GetBrowserPluginGuestManager()->RemoveGuest(instance_id_);
399 delete GetWebContents();
[email protected]b371a5652013-02-20 11:25:51400}
401
[email protected]3997b1b22012-12-20 01:02:54402bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
403 const IPC::Message& message) {
404 bool handled = true;
405 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
[email protected]95d31822014-01-03 22:21:55406 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameSwappedACK,
407 OnCompositorFrameSwappedACK)
[email protected]73405fb2013-12-11 04:59:37408 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck,
409 OnCopyFromCompositingSurfaceAck)
[email protected]3997b1b22012-12-20 01:02:54410 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_DragStatusUpdate,
411 OnDragStatusUpdate)
[email protected]6dd17a8a2013-05-01 05:50:10412 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExecuteEditCommand,
413 OnExecuteEditCommand)
[email protected]d260f042013-12-14 01:31:36414 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExtendSelectionAndDelete,
415 OnExtendSelectionAndDelete)
[email protected]3997b1b22012-12-20 01:02:54416 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_HandleInputEvent,
417 OnHandleInputEvent)
[email protected]d260f042013-12-14 01:31:36418 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ImeConfirmComposition,
419 OnImeConfirmComposition)
420 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ImeSetComposition,
421 OnImeSetComposition)
[email protected]861f9782013-03-05 03:29:54422 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_LockMouse_ACK, OnLockMouseAck)
[email protected]5e7967972013-01-15 22:45:33423 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateGuest, OnNavigateGuest)
[email protected]b371a5652013-02-20 11:25:51424 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_PluginDestroyed, OnPluginDestroyed)
[email protected]b0030b72013-11-15 20:35:53425 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ReclaimCompositorResources,
426 OnReclaimCompositorResources)
[email protected]3997b1b22012-12-20 01:02:54427 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ResizeGuest, OnResizeGuest)
428 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetAutoSize, OnSetSize)
[email protected]b77fac52013-06-01 01:03:46429 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent,
430 OnSetEditCommandsForNextKeyEvent)
[email protected]3997b1b22012-12-20 01:02:54431 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetFocus, OnSetFocus)
[email protected]25bcc8f2013-01-09 02:49:25432 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetName, OnSetName)
[email protected]c7fc429d2013-11-28 05:49:36433 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetContentsOpaque,
434 OnSetContentsOpaque)
[email protected]3997b1b22012-12-20 01:02:54435 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetVisibility, OnSetVisibility)
[email protected]861f9782013-03-05 03:29:54436 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UnlockMouse_ACK, OnUnlockMouseAck)
[email protected]32deec62013-05-15 23:55:04437 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateGeometry, OnUpdateGeometry)
[email protected]3997b1b22012-12-20 01:02:54438 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateRect_ACK, OnUpdateRectACK)
439 IPC_MESSAGE_UNHANDLED(handled = false)
440 IPC_END_MESSAGE_MAP()
441 return handled;
442}
443
444void BrowserPluginGuest::Initialize(
[email protected]c61b317c72013-11-14 06:40:46445 const BrowserPluginHostMsg_Attach_Params& params,
446 WebContentsImpl* embedder_web_contents) {
[email protected]c4538072013-03-18 02:17:55447 focused_ = params.focused;
448 guest_visible_ = params.visible;
[email protected]c7fc429d2013-11-28 05:49:36449 guest_opaque_ = params.opaque;
[email protected]32deec62013-05-15 23:55:04450 guest_window_rect_ = params.resize_guest_params.view_rect;
451
[email protected]50de3222013-03-20 15:36:13452 if (!params.name.empty())
453 name_ = params.name;
[email protected]c4538072013-03-18 02:17:55454 auto_size_enabled_ = params.auto_size_params.enable;
455 max_auto_size_ = params.auto_size_params.max_size;
456 min_auto_size_ = params.auto_size_params.min_size;
457
458 // Once a BrowserPluginGuest has an embedder WebContents, it's considered to
459 // be attached.
460 embedder_web_contents_ = embedder_web_contents;
461
[email protected]2b3c7b32013-07-24 23:47:42462 WebContentsViewGuest* new_view =
463 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
464 new_view->OnGuestInitialized(embedder_web_contents->GetView());
465
[email protected]8eb04562013-03-06 03:41:14466 RendererPreferences* renderer_prefs =
467 GetWebContents()->GetMutableRendererPrefs();
[email protected]0d2f55e92013-09-26 03:13:17468 std::string guest_user_agent_override = renderer_prefs->user_agent_override;
[email protected]8eb04562013-03-06 03:41:14469 // Copy renderer preferences (and nothing else) from the embedder's
470 // WebContents to the guest.
471 //
472 // For GTK and Aura this is necessary to get proper renderer configuration
473 // values for caret blinking interval, colors related to selection and
474 // focus.
475 *renderer_prefs = *embedder_web_contents_->GetMutableRendererPrefs();
[email protected]0d2f55e92013-09-26 03:13:17476 renderer_prefs->user_agent_override = guest_user_agent_override;
[email protected]8eb04562013-03-06 03:41:14477
[email protected]8eb04562013-03-06 03:41:14478 // We would like the guest to report changes to frame names so that we can
479 // update the BrowserPlugin's corresponding 'name' attribute.
480 // TODO(fsamuel): Remove this once http://crbug.com/169110 is addressed.
481 renderer_prefs->report_frame_name_changes = true;
[email protected]7fdb6ac2014-02-07 18:33:32482 // Navigation is disabled in Chrome Apps. We want to make sure guest-initiated
483 // navigations still continue to function inside the app.
484 renderer_prefs->browser_handles_all_top_level_requests = false;
[email protected]f677288e2013-09-18 02:11:00485 // Disable "client blocked" error page for browser plugin.
486 renderer_prefs->disable_client_blocked_error_page = true;
[email protected]31942c82012-10-05 17:01:54487
[email protected]e0c6dc92013-10-10 21:17:51488 embedder_web_contents_observer_.reset(new EmbedderWebContentsObserver(this));
[email protected]93564f72013-02-15 13:26:19489
[email protected]3997b1b22012-12-20 01:02:54490 OnSetSize(instance_id_, params.auto_size_params, params.resize_guest_params);
[email protected]44703cc72013-01-24 04:56:06491
[email protected]93564f72013-02-15 13:26:19492 // Create a swapped out RenderView for the guest in the embedder render
493 // process, so that the embedder can access the guest's window object.
494 int guest_routing_id =
[email protected]8eb04562013-03-06 03:41:14495 GetWebContents()->CreateSwappedOutRenderView(
496 embedder_web_contents_->GetSiteInstance());
[email protected]d752fe62013-03-01 03:46:01497 SendMessageToEmbedder(
498 new BrowserPluginMsg_GuestContentWindowReady(instance_id_,
499 guest_routing_id));
[email protected]93564f72013-02-15 13:26:19500
[email protected]09449dd52013-10-09 20:28:56501 if (!params.src.empty()) {
502 // params.src will be validated in BrowserPluginGuest::OnNavigateGuest.
[email protected]93564f72013-02-15 13:26:19503 OnNavigateGuest(instance_id_, params.src);
[email protected]09449dd52013-10-09 20:28:56504 }
[email protected]93564f72013-02-15 13:26:19505
[email protected]0c6d41752013-05-01 15:49:09506 has_render_view_ = true;
[email protected]d10bbddf2013-06-06 23:38:31507
[email protected]f1b6aa7c2014-02-20 22:10:26508 WebPreferences prefs = GetWebContents()->GetWebkitPrefs();
509 prefs.navigate_on_drag_drop = false;
[email protected]d10bbddf2013-06-06 23:38:31510 if (!embedder_web_contents_->
511 GetWebkitPrefs().accelerated_compositing_enabled) {
[email protected]d10bbddf2013-06-06 23:38:31512 prefs.accelerated_compositing_enabled = false;
[email protected]d10bbddf2013-06-06 23:38:31513 }
[email protected]f1b6aa7c2014-02-20 22:10:26514 GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs);
[email protected]523c89de2013-06-12 16:30:04515
516 // Enable input method for guest if it's enabled for the embedder.
517 if (static_cast<RenderViewHostImpl*>(
518 embedder_web_contents_->GetRenderViewHost())->input_method_active()) {
519 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
520 GetWebContents()->GetRenderViewHost());
521 guest_rvh->SetInputMethodActive(true);
522 }
[email protected]cefa2662013-08-22 23:29:13523
524 // Inform the embedder of the guest's information.
525 // We pull the partition information from the site's URL, which is of the form
526 // guest://site/{persist}?{partition_name}.
527 const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL();
528 BrowserPluginMsg_Attach_ACK_Params ack_params;
529 ack_params.storage_partition_id = site_url.query();
530 ack_params.persist_storage =
531 site_url.path().find("persist") != std::string::npos;
532 ack_params.name = name_;
533 SendMessageToEmbedder(
534 new BrowserPluginMsg_Attach_ACK(instance_id_, ack_params));
[email protected]a6bc27952013-12-06 00:48:19535
536 if (delegate_)
537 delegate_->DidAttach();
[email protected]7a846df2012-09-20 19:17:39538}
539
540BrowserPluginGuest::~BrowserPluginGuest() {
[email protected]697f16b52013-05-10 06:01:18541 while (!pending_messages_.empty()) {
542 delete pending_messages_.front();
543 pending_messages_.pop();
544 }
[email protected]7a846df2012-09-20 19:17:39545}
546
547// static
548BrowserPluginGuest* BrowserPluginGuest::Create(
549 int instance_id,
[email protected]dbbce92c2013-10-31 16:51:19550 SiteInstance* guest_site_instance,
[email protected]738f57a2013-06-29 21:06:54551 WebContentsImpl* web_contents,
552 scoped_ptr<base::DictionaryValue> extra_params) {
[email protected]e6e30ac2014-01-13 21:24:39553 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create"));
[email protected]738f57a2013-06-29 21:06:54554 BrowserPluginGuest* guest = NULL;
555 if (factory_) {
556 guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents);
557 } else {
[email protected]c61b317c72013-11-14 06:40:46558 guest = new BrowserPluginGuest(instance_id, false, web_contents, NULL);
[email protected]738f57a2013-06-29 21:06:54559 }
[email protected]538334712013-09-14 21:29:01560 guest->extra_attach_params_.reset(extra_params->DeepCopy());
[email protected]738f57a2013-06-29 21:06:54561 web_contents->SetBrowserPluginGuest(guest);
[email protected]4c0e8272013-07-03 23:39:22562 BrowserPluginGuestDelegate* delegate = NULL;
[email protected]738f57a2013-06-29 21:06:54563 GetContentClient()->browser()->GuestWebContentsCreated(
[email protected]dbbce92c2013-10-31 16:51:19564 guest_site_instance, web_contents, NULL, &delegate, extra_params.Pass());
[email protected]4c0e8272013-07-03 23:39:22565 guest->SetDelegate(delegate);
[email protected]738f57a2013-06-29 21:06:54566 return guest;
[email protected]0c6d41752013-05-01 15:49:09567}
568
569// static
570BrowserPluginGuest* BrowserPluginGuest::CreateWithOpener(
571 int instance_id,
[email protected]c61b317c72013-11-14 06:40:46572 bool has_render_view,
[email protected]0c6d41752013-05-01 15:49:09573 WebContentsImpl* web_contents,
[email protected]c61b317c72013-11-14 06:40:46574 BrowserPluginGuest* opener) {
[email protected]738f57a2013-06-29 21:06:54575 BrowserPluginGuest* guest =
576 new BrowserPluginGuest(
[email protected]c61b317c72013-11-14 06:40:46577 instance_id, has_render_view, web_contents, opener);
[email protected]738f57a2013-06-29 21:06:54578 web_contents->SetBrowserPluginGuest(guest);
[email protected]4c0e8272013-07-03 23:39:22579 BrowserPluginGuestDelegate* delegate = NULL;
[email protected]738f57a2013-06-29 21:06:54580 GetContentClient()->browser()->GuestWebContentsCreated(
[email protected]dbbce92c2013-10-31 16:51:19581 opener->GetWebContents()->GetSiteInstance(),
[email protected]4c0e8272013-07-03 23:39:22582 web_contents, opener->GetWebContents(), &delegate,
[email protected]738f57a2013-06-29 21:06:54583 scoped_ptr<base::DictionaryValue>());
[email protected]4c0e8272013-07-03 23:39:22584 guest->SetDelegate(delegate);
[email protected]738f57a2013-06-29 21:06:54585 return guest;
[email protected]7a846df2012-09-20 19:17:39586}
587
[email protected]44327692013-02-26 21:21:22588RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() {
[email protected]68d5ab72014-01-23 22:22:57589 if (!attached())
590 return NULL;
[email protected]44327692013-02-26 21:21:22591 return embedder_web_contents_->GetRenderWidgetHostView();
592}
593
[email protected]3997b1b22012-12-20 01:02:54594void BrowserPluginGuest::UpdateVisibility() {
595 OnSetVisibility(instance_id_, visible());
596}
597
[email protected]73405fb2013-12-11 04:59:37598void BrowserPluginGuest::CopyFromCompositingSurface(
599 gfx::Rect src_subrect,
600 gfx::Size dst_size,
601 const base::Callback<void(bool, const SkBitmap&)>& callback) {
602 copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback));
603 SendMessageToEmbedder(
604 new BrowserPluginMsg_CopyFromCompositingSurface(instance_id(),
605 copy_request_id_, src_subrect, dst_size));
606}
607
[email protected]32deec62013-05-15 23:55:04608// screen.
609gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) {
610 gfx::Rect guest_rect(bounds);
611 guest_rect.Offset(guest_window_rect_.OffsetFromOrigin());
612 return guest_rect;
613}
614
[email protected]e0c6dc92013-10-10 21:17:51615void BrowserPluginGuest::EmbedderVisibilityChanged(bool visible) {
616 embedder_visible_ = visible;
617 UpdateVisibility();
[email protected]31942c82012-10-05 17:01:54618}
619
[email protected]c4538072013-03-18 02:17:55620void BrowserPluginGuest::AddNewContents(WebContents* source,
621 WebContents* new_contents,
622 WindowOpenDisposition disposition,
623 const gfx::Rect& initial_pos,
624 bool user_gesture,
625 bool* was_blocked) {
[email protected]d70bea92013-04-05 04:23:34626 if (was_blocked)
627 *was_blocked = false;
[email protected]c61b317c72013-11-14 06:40:46628 RequestNewWindowPermission(disposition, initial_pos, user_gesture,
629 static_cast<WebContentsImpl*>(new_contents));
[email protected]c4538072013-03-18 02:17:55630}
631
[email protected]f85f5032013-04-03 09:01:54632void BrowserPluginGuest::CanDownload(
633 RenderViewHost* render_view_host,
634 int request_id,
635 const std::string& request_method,
636 const base::Callback<void(bool)>& callback) {
[email protected]922bd4ab2014-04-16 05:02:38637 if (!delegate_) {
638 callback.Run(false);
639 return;
640 }
641
[email protected]f85f5032013-04-03 09:01:54642 BrowserThread::PostTaskAndReplyWithResult(
643 BrowserThread::IO, FROM_HERE,
644 base::Bind(&RetrieveDownloadURLFromRequestId,
[email protected]922bd4ab2014-04-16 05:02:38645 render_view_host->GetProcess()->GetID(), request_id),
[email protected]f85f5032013-04-03 09:01:54646 base::Bind(&BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId,
647 weak_ptr_factory_.GetWeakPtr(),
648 request_method,
[email protected]291dcf32013-07-28 08:02:14649 callback));
[email protected]4aefa0c2012-10-04 20:01:19650}
651
[email protected]0e9edbc2013-09-03 20:15:38652void BrowserPluginGuest::LoadProgressChanged(WebContents* contents,
653 double progress) {
654 if (delegate_)
655 delegate_->LoadProgressed(progress);
656}
657
[email protected]f9fb1032013-05-02 22:12:57658void BrowserPluginGuest::CloseContents(WebContents* source) {
[email protected]c84c6af2013-07-04 02:36:04659 if (!delegate_)
660 return;
661
662 delegate_->Close();
[email protected]f9fb1032013-05-02 22:12:57663}
664
[email protected]1c514fc2013-07-24 07:30:53665JavaScriptDialogManager* BrowserPluginGuest::GetJavaScriptDialogManager() {
666 return this;
667}
668
[email protected]90f41dbd2014-04-02 06:32:41669ColorChooser* BrowserPluginGuest::OpenColorChooser(
670 WebContents* web_contents,
671 SkColor color,
672 const std::vector<ColorSuggestion>& suggestions) {
673 if (!embedder_web_contents_ || !embedder_web_contents_->GetDelegate())
674 return NULL;
675 return embedder_web_contents_->GetDelegate()->OpenColorChooser(
676 web_contents, color, suggestions);
677}
678
[email protected]63028f52014-02-10 16:45:40679bool BrowserPluginGuest::HandleContextMenu(const ContextMenuParams& params) {
[email protected]cb8d7cf22013-06-19 04:16:43680 // TODO(fsamuel): We show the regular page context menu handler for now until
[email protected]14d59b332012-10-05 01:40:28681 // we implement the Apps Context Menu API for Browser Plugin (see
682 // http://crbug.com/140315).
[email protected]cb8d7cf22013-06-19 04:16:43683 return false; // Will be handled by WebContentsViewGuest.
[email protected]14d59b332012-10-05 01:40:28684}
685
[email protected]6dd17a8a2013-05-01 05:50:10686void BrowserPluginGuest::HandleKeyboardEvent(
687 WebContents* source,
688 const NativeWebKeyboardEvent& event) {
689 if (!attached())
690 return;
691
[email protected]6d5c060a2013-06-18 11:27:06692 if (UnlockMouseIfNecessary(event))
693 return;
694
[email protected]926d4f42013-07-12 23:11:17695 if (delegate_ && delegate_->HandleKeyboardEvent(event))
696 return;
697
[email protected]d131bd52013-12-11 03:52:36698 if (!embedder_web_contents_->GetDelegate())
699 return;
700
[email protected]6dd17a8a2013-05-01 05:50:10701 // Send the unhandled keyboard events back to the embedder to reprocess them.
702 // TODO(fsamuel): This introduces the possibility of out-of-order keyboard
703 // events because the guest may be arbitrarily delayed when responding to
704 // keyboard events. In that time, the embedder may have received and processed
705 // additional key events. This needs to be fixed as soon as possible.
706 // See http://crbug.com/229882.
707 embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(
708 web_contents(), event);
709}
710
[email protected]39415212014-02-12 17:29:45711void BrowserPluginGuest::SetZoom(double zoom_factor) {
712 if (delegate_)
713 delegate_->SetZoom(zoom_factor);
714}
715
[email protected]7a1280892014-04-16 17:18:25716void BrowserPluginGuest::PointerLockPermissionResponse(bool allow) {
717 SendMessageToEmbedder(
718 new BrowserPluginMsg_SetMouseLock(instance_id(), allow));
719}
720
[email protected]5e56b0142014-02-28 18:24:23721void BrowserPluginGuest::FindReply(WebContents* contents,
722 int request_id,
723 int number_of_matches,
724 const gfx::Rect& selection_rect,
725 int active_match_ordinal,
726 bool final_update) {
727 if (!delegate_)
728 return;
729
730 // |selection_rect| is updated to incorporate embedder coordinates.
731 delegate_->FindReply(request_id, number_of_matches,
732 ToGuestRect(selection_rect),
733 active_match_ordinal, final_update);
734}
735
[email protected]0c6d41752013-05-01 15:49:09736WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source,
737 const OpenURLParams& params) {
738 // If the guest wishes to navigate away prior to attachment then we save the
739 // navigation to perform upon attachment. Navigation initializes a lot of
740 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest.
741 // Navigation also resumes resource loading which we don't want to allow
742 // until attachment.
743 if (!attached()) {
744 PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
745 if (it == opener()->pending_new_windows_.end())
746 return NULL;
[email protected]7fdb6ac2014-02-07 18:33:32747 const NewWindowInfo& old_target_url = it->second;
748 NewWindowInfo new_window_info(params.url, old_target_url.name);
749 new_window_info.changed = new_window_info.url != old_target_url.url;
750 it->second = new_window_info;
[email protected]0c6d41752013-05-01 15:49:09751 return NULL;
752 }
[email protected]538334712013-09-14 21:29:01753 if (params.disposition == CURRENT_TAB) {
[email protected]7fdb6ac2014-02-07 18:33:32754 // This can happen for cross-site redirects.
[email protected]c61b317c72013-11-14 06:40:46755 LoadURLWithParams(params.url, params.referrer, params.transition, source);
[email protected]538334712013-09-14 21:29:01756 return source;
757 }
758
759 return CreateNewGuestWindow(params)->GetWebContents();
[email protected]0c6d41752013-05-01 15:49:09760}
761
[email protected]c4538072013-03-18 02:17:55762void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents,
[email protected]a7531d772014-03-25 16:15:07763 int opener_render_frame_id,
[email protected]fcf75d42013-12-03 20:11:26764 const base::string16& frame_name,
[email protected]c4538072013-03-18 02:17:55765 const GURL& target_url,
766 WebContents* new_contents) {
767 WebContentsImpl* new_contents_impl =
768 static_cast<WebContentsImpl*>(new_contents);
769 BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest();
[email protected]6dd17a8a2013-05-01 05:50:10770 guest->opener_ = AsWeakPtr();
[email protected]32956122013-12-25 07:29:24771 std::string guest_name = base::UTF16ToUTF8(frame_name);
[email protected]96584eec2013-05-07 13:25:32772 guest->name_ = guest_name;
[email protected]c4538072013-03-18 02:17:55773 // Take ownership of the new guest until it is attached to the embedder's DOM
774 // tree to avoid leaking a guest if this guest is destroyed before attaching
775 // the new guest.
[email protected]96584eec2013-05-07 13:25:32776 pending_new_windows_.insert(
777 std::make_pair(guest, NewWindowInfo(target_url, guest_name)));
[email protected]c4538072013-03-18 02:17:55778}
779
[email protected]7a846df2012-09-20 19:17:39780void BrowserPluginGuest::RendererUnresponsive(WebContents* source) {
[email protected]e6e30ac2014-01-13 21:24:39781 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Hung"));
[email protected]fcf5a7a2013-07-26 06:18:01782 if (!delegate_)
783 return;
784 delegate_->RendererUnresponsive();
[email protected]7a846df2012-09-20 19:17:39785}
786
[email protected]f8501b12012-12-07 04:55:43787void BrowserPluginGuest::RendererResponsive(WebContents* source) {
[email protected]e6e30ac2014-01-13 21:24:39788 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Responsive"));
[email protected]fcf5a7a2013-07-26 06:18:01789 if (!delegate_)
790 return;
791 delegate_->RendererResponsive();
[email protected]f8501b12012-12-07 04:55:43792}
793
[email protected]19c1c373e2012-10-17 14:12:18794void BrowserPluginGuest::RunFileChooser(WebContents* web_contents,
795 const FileChooserParams& params) {
[email protected]d131bd52013-12-11 03:52:36796 if (!attached())
797 return;
798
799 if (!embedder_web_contents_->GetDelegate())
800 return;
801
[email protected]19c1c373e2012-10-17 14:12:18802 embedder_web_contents_->GetDelegate()->RunFileChooser(web_contents, params);
803}
804
[email protected]6a121f22012-10-30 03:19:48805bool BrowserPluginGuest::ShouldFocusPageAfterCrash() {
806 // Rather than managing focus in WebContentsImpl::RenderViewReady, we will
807 // manage the focus ourselves.
808 return false;
809}
810
[email protected]8eb04562013-03-06 03:41:14811WebContentsImpl* BrowserPluginGuest::GetWebContents() {
812 return static_cast<WebContentsImpl*>(web_contents());
[email protected]e17b7c62012-09-21 21:05:46813}
814
[email protected]4d1afd62012-12-21 03:09:40815base::SharedMemory* BrowserPluginGuest::GetDamageBufferFromEmbedder(
[email protected]1a0c0052012-11-05 21:06:26816 const BrowserPluginHostMsg_ResizeGuest_Params& params) {
[email protected]8af7de9d2013-08-14 21:35:49817 if (!attached()) {
818 LOG(WARNING) << "Attempting to map a damage buffer prior to attachment.";
819 return NULL;
820 }
[email protected]1a0c0052012-11-05 21:06:26821#if defined(OS_WIN)
[email protected]4d1afd62012-12-21 03:09:40822 base::ProcessHandle handle =
823 embedder_web_contents_->GetRenderProcessHost()->GetHandle();
824 scoped_ptr<base::SharedMemory> shared_buf(
825 new base::SharedMemory(params.damage_buffer_handle, false, handle));
[email protected]1a0c0052012-11-05 21:06:26826#elif defined(OS_POSIX)
[email protected]4d1afd62012-12-21 03:09:40827 scoped_ptr<base::SharedMemory> shared_buf(
828 new base::SharedMemory(params.damage_buffer_handle, false));
829#endif
830 if (!shared_buf->Map(params.damage_buffer_size)) {
[email protected]c072073402013-06-04 21:53:59831 LOG(WARNING) << "Unable to map the embedder's damage buffer.";
[email protected]4d1afd62012-12-21 03:09:40832 return NULL;
833 }
834 return shared_buf.release();
[email protected]1a0c0052012-11-05 21:06:26835}
836
[email protected]7a846df2012-09-20 19:17:39837void BrowserPluginGuest::SetDamageBuffer(
[email protected]4d1afd62012-12-21 03:09:40838 const BrowserPluginHostMsg_ResizeGuest_Params& params) {
839 damage_buffer_.reset(GetDamageBufferFromEmbedder(params));
[email protected]7a846df2012-09-20 19:17:39840 // Sanity check: Verify that we've correctly shared the damage buffer memory
841 // between the embedder and browser processes.
[email protected]c072073402013-06-04 21:53:59842 DCHECK(!damage_buffer_ ||
843 *static_cast<unsigned int*>(damage_buffer_->memory()) == 0xdeadbeef);
[email protected]4d1afd62012-12-21 03:09:40844 damage_buffer_sequence_id_ = params.damage_buffer_sequence_id;
845 damage_buffer_size_ = params.damage_buffer_size;
[email protected]32deec62013-05-15 23:55:04846 damage_view_size_ = params.view_rect.size();
[email protected]4d1afd62012-12-21 03:09:40847 damage_buffer_scale_factor_ = params.scale_factor;
[email protected]7a846df2012-09-20 19:17:39848}
849
[email protected]ca61ce142012-11-27 21:32:57850gfx::Point BrowserPluginGuest::GetScreenCoordinates(
851 const gfx::Point& relative_position) const {
852 gfx::Point screen_pos(relative_position);
853 screen_pos += guest_window_rect_.OffsetFromOrigin();
854 return screen_pos;
855}
856
[email protected]240b5c32012-11-09 19:17:18857bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const {
858 return size.width() <= max_auto_size_.width() &&
859 size.height() <= max_auto_size_.height();
860}
861
[email protected]c4538072013-03-18 02:17:55862void BrowserPluginGuest::RequestNewWindowPermission(
[email protected]c4538072013-03-18 02:17:55863 WindowOpenDisposition disposition,
864 const gfx::Rect& initial_bounds,
[email protected]c61b317c72013-11-14 06:40:46865 bool user_gesture,
866 WebContentsImpl* new_contents) {
[email protected]c4538072013-03-18 02:17:55867 BrowserPluginGuest* guest = new_contents->GetBrowserPluginGuest();
868 PendingWindowMap::iterator it = pending_new_windows_.find(guest);
869 if (it == pending_new_windows_.end())
870 return;
[email protected]96584eec2013-05-07 13:25:32871 const NewWindowInfo& new_window_info = it->second;
[email protected]291dcf32013-07-28 08:02:14872
[email protected]c4538072013-03-18 02:17:55873 base::DictionaryValue request_info;
874 request_info.Set(browser_plugin::kInitialHeight,
875 base::Value::CreateIntegerValue(initial_bounds.height()));
876 request_info.Set(browser_plugin::kInitialWidth,
877 base::Value::CreateIntegerValue(initial_bounds.width()));
878 request_info.Set(browser_plugin::kTargetURL,
[email protected]96584eec2013-05-07 13:25:32879 base::Value::CreateStringValue(new_window_info.url.spec()));
880 request_info.Set(browser_plugin::kName,
881 base::Value::CreateStringValue(new_window_info.name));
[email protected]c4538072013-03-18 02:17:55882 request_info.Set(browser_plugin::kWindowID,
883 base::Value::CreateIntegerValue(guest->instance_id()));
884 request_info.Set(browser_plugin::kWindowOpenDisposition,
885 base::Value::CreateStringValue(
886 WindowOpenDispositionToString(disposition)));
[email protected]291dcf32013-07-28 08:02:14887
[email protected]af1718c2013-08-12 19:59:19888 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW,
[email protected]bfb9e9a2014-01-29 22:36:18889 new NewWindowRequest(weak_ptr_factory_.GetWeakPtr(),
890 guest->instance_id()),
[email protected]291dcf32013-07-28 08:02:14891 request_info);
[email protected]c4538072013-03-18 02:17:55892}
893
[email protected]6d5c060a2013-06-18 11:27:06894bool BrowserPluginGuest::UnlockMouseIfNecessary(
895 const NativeWebKeyboardEvent& event) {
896 if (!mouse_locked_)
897 return false;
898
899 embedder_web_contents()->GotResponseToLockMouseRequest(false);
900 return true;
901}
902
[email protected]a7fac9a2012-12-18 23:26:07903void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) {
[email protected]c4538072013-03-18 02:17:55904 if (!attached()) {
[email protected]697f16b52013-05-10 06:01:18905 // Some pages such as data URLs, javascript URLs, and about:blank
906 // do not load external resources and so they load prior to attachment.
907 // As a result, we must save all these IPCs until attachment and then
908 // forward them so that the embedder gets a chance to see and process
909 // the load events.
910 pending_messages_.push(msg);
[email protected]c4538072013-03-18 02:17:55911 return;
912 }
913 msg->set_routing_id(embedder_web_contents_->GetRoutingID());
[email protected]a7fac9a2012-12-18 23:26:07914 embedder_web_contents_->Send(msg);
915}
916
[email protected]cf200a562013-05-03 16:24:29917void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y,
[email protected]180ef242013-11-07 06:50:46918 int screen_x, int screen_y, blink::WebDragOperation operation) {
[email protected]cf200a562013-05-03 16:24:29919 web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y,
920 screen_x, screen_y, operation);
921}
922
[email protected]cf200a562013-05-03 16:24:29923void BrowserPluginGuest::EndSystemDrag() {
924 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
925 GetWebContents()->GetRenderViewHost());
926 guest_rvh->DragSourceSystemDragEnded();
[email protected]cf200a562013-05-03 16:24:29927}
928
[email protected]4c0e8272013-07-03 23:39:22929void BrowserPluginGuest::SetDelegate(BrowserPluginGuestDelegate* delegate) {
930 DCHECK(!delegate_);
931 delegate_.reset(delegate);
932}
933
[email protected]697f16b52013-05-10 06:01:18934void BrowserPluginGuest::SendQueuedMessages() {
935 if (!attached())
936 return;
937
938 while (!pending_messages_.empty()) {
939 IPC::Message* message = pending_messages_.front();
940 pending_messages_.pop();
941 SendMessageToEmbedder(message);
942 }
943}
944
[email protected]7a846df2012-09-20 19:17:39945void BrowserPluginGuest::DidCommitProvisionalLoadForFrame(
946 int64 frame_id,
[email protected]fcf75d42013-12-03 20:11:26947 const base::string16& frame_unique_name,
[email protected]7a846df2012-09-20 19:17:39948 bool is_main_frame,
949 const GURL& url,
950 PageTransition transition_type,
951 RenderViewHost* render_view_host) {
[email protected]e6e30ac2014-01-13 21:24:39952 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.DidNavigate"));
[email protected]7a846df2012-09-20 19:17:39953}
954
[email protected]eb92f632012-10-19 00:56:12955void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) {
[email protected]90cef0a2013-09-19 19:36:46956 bool enable_dragdrop = delegate_ && delegate_->IsDragAndDropEnabled();
957 if (!enable_dragdrop) {
[email protected]cf200a562013-05-03 16:24:29958 // Initiating a drag from inside a guest is currently not supported without
959 // the kEnableBrowserPluginDragDrop flag on a linux platform. So inject some
960 // JS to disable it. http://crbug.com/161112
961 const char script[] = "window.addEventListener('dragstart', function() { "
962 " window.event.preventDefault(); "
963 "});";
[email protected]f13ab892014-03-12 06:48:52964 render_view_host->GetMainFrame()->ExecuteJavaScript(
965 base::ASCIIToUTF16(script));
[email protected]cf200a562013-05-03 16:24:29966 }
[email protected]eb92f632012-10-19 00:56:12967}
968
[email protected]c88b2a562012-10-27 03:36:56969void BrowserPluginGuest::RenderViewReady() {
[email protected]543afaf2013-12-13 14:03:22970 RenderViewHost* rvh = GetWebContents()->GetRenderViewHost();
971 // The guest RenderView should always live in a guest process.
972 CHECK(rvh->GetProcess()->IsGuest());
[email protected]c88b2a562012-10-27 03:36:56973 // TODO(fsamuel): Investigate whether it's possible to update state earlier
[email protected]dba9bd22012-12-06 23:04:03974 // here (see http://crbug.com/158151).
[email protected]c084330e02013-04-27 01:08:15975 Send(new InputMsg_SetFocus(routing_id(), focused_));
[email protected]3997b1b22012-12-20 01:02:54976 UpdateVisibility();
[email protected]25bcc8f2013-01-09 02:49:25977 if (auto_size_enabled_)
978 rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
979 else
980 rvh->DisableAutoResize(damage_view_size_);
981
[email protected]8eb04562013-03-06 03:41:14982 Send(new ViewMsg_SetName(routing_id(), name_));
[email protected]c7fc429d2013-11-28 05:49:36983 OnSetContentsOpaque(instance_id_, guest_opaque_);
[email protected]bca6c2c2013-03-24 03:55:07984
985 RenderWidgetHostImpl::From(rvh)->
986 set_hung_renderer_delay_ms(guest_hang_timeout_);
[email protected]c88b2a562012-10-27 03:36:56987}
988
[email protected]58d5cfe2013-07-10 02:40:52989void BrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) {
[email protected]78d71912013-07-17 06:39:47990 SendMessageToEmbedder(new BrowserPluginMsg_GuestGone(instance_id()));
[email protected]2fae2c42012-10-03 21:20:04991 switch (status) {
992 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
[email protected]e6e30ac2014-01-13 21:24:39993 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Killed"));
[email protected]2fae2c42012-10-03 21:20:04994 break;
995 case base::TERMINATION_STATUS_PROCESS_CRASHED:
[email protected]e6e30ac2014-01-13 21:24:39996 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed"));
[email protected]2fae2c42012-10-03 21:20:04997 break;
998 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
[email protected]e6e30ac2014-01-13 21:24:39999 RecordAction(
1000 base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath"));
[email protected]2fae2c42012-10-03 21:20:041001 break;
1002 default:
1003 break;
1004 }
[email protected]291dcf32013-07-28 08:02:141005 // TODO(fsamuel): Consider whether we should be clearing
1006 // |permission_request_map_| here.
[email protected]78d71912013-07-17 06:39:471007 if (delegate_)
1008 delegate_->GuestProcessGone(status);
[email protected]7a846df2012-09-20 19:17:391009}
1010
[email protected]8eb04562013-03-06 03:41:141011// static
[email protected]8eb04562013-03-06 03:41:141012bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(
1013 const IPC::Message& message) {
1014 switch (message.type()) {
[email protected]95d31822014-01-03 22:21:551015 case BrowserPluginHostMsg_CompositorFrameSwappedACK::ID:
[email protected]73405fb2013-12-11 04:59:371016 case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID:
[email protected]8eb04562013-03-06 03:41:141017 case BrowserPluginHostMsg_DragStatusUpdate::ID:
[email protected]6dd17a8a2013-05-01 05:50:101018 case BrowserPluginHostMsg_ExecuteEditCommand::ID:
[email protected]d260f042013-12-14 01:31:361019 case BrowserPluginHostMsg_ExtendSelectionAndDelete::ID:
[email protected]8eb04562013-03-06 03:41:141020 case BrowserPluginHostMsg_HandleInputEvent::ID:
[email protected]d260f042013-12-14 01:31:361021 case BrowserPluginHostMsg_ImeConfirmComposition::ID:
1022 case BrowserPluginHostMsg_ImeSetComposition::ID:
[email protected]8eb04562013-03-06 03:41:141023 case BrowserPluginHostMsg_LockMouse_ACK::ID:
1024 case BrowserPluginHostMsg_NavigateGuest::ID:
1025 case BrowserPluginHostMsg_PluginDestroyed::ID:
[email protected]b0030b72013-11-15 20:35:531026 case BrowserPluginHostMsg_ReclaimCompositorResources::ID:
[email protected]8eb04562013-03-06 03:41:141027 case BrowserPluginHostMsg_ResizeGuest::ID:
[email protected]8eb04562013-03-06 03:41:141028 case BrowserPluginHostMsg_SetAutoSize::ID:
[email protected]b77fac52013-06-01 01:03:461029 case BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent::ID:
[email protected]8eb04562013-03-06 03:41:141030 case BrowserPluginHostMsg_SetFocus::ID:
1031 case BrowserPluginHostMsg_SetName::ID:
[email protected]c7fc429d2013-11-28 05:49:361032 case BrowserPluginHostMsg_SetContentsOpaque::ID:
[email protected]8eb04562013-03-06 03:41:141033 case BrowserPluginHostMsg_SetVisibility::ID:
[email protected]8eb04562013-03-06 03:41:141034 case BrowserPluginHostMsg_UnlockMouse_ACK::ID:
[email protected]32deec62013-05-15 23:55:041035 case BrowserPluginHostMsg_UpdateGeometry::ID:
[email protected]8eb04562013-03-06 03:41:141036 case BrowserPluginHostMsg_UpdateRect_ACK::ID:
1037 return true;
1038 default:
[email protected]c61b317c72013-11-14 06:40:461039 return false;
[email protected]8eb04562013-03-06 03:41:141040 }
[email protected]8eb04562013-03-06 03:41:141041}
1042
[email protected]a7fac9a2012-12-18 23:26:071043bool BrowserPluginGuest::OnMessageReceived(const IPC::Message& message) {
1044 bool handled = true;
1045 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
[email protected]a7fac9a2012-12-18 23:26:071046 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
1047 OnHasTouchEventHandlers)
[email protected]861f9782013-03-05 03:29:541048 IPC_MESSAGE_HANDLER(ViewHostMsg_LockMouse, OnLockMouse)
[email protected]a7fac9a2012-12-18 23:26:071049 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
1050 #if defined(OS_MACOSX)
1051 // MacOSX creates and populates platform-specific select drop-down menus
1052 // whereas other platforms merely create a popup window that the guest
1053 // renderer process paints inside.
1054 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnShowPopup)
1055 #endif
1056 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
1057 IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
[email protected]d260f042013-12-14 01:31:361058 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputTypeChanged,
1059 OnTextInputTypeChanged)
1060 IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCancelComposition,
1061 OnImeCancelComposition)
[email protected]f9db7d2d2014-04-11 16:07:111062#if defined(OS_MACOSX) || defined(USE_AURA)
[email protected]d260f042013-12-14 01:31:361063 IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCompositionRangeChanged,
1064 OnImeCompositionRangeChanged)
1065#endif
[email protected]861f9782013-03-05 03:29:541066 IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse)
[email protected]25bcc8f2013-01-09 02:49:251067 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFrameName, OnUpdateFrameName)
[email protected]a7fac9a2012-12-18 23:26:071068 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
1069 IPC_MESSAGE_UNHANDLED(handled = false)
1070 IPC_END_MESSAGE_MAP()
1071 return handled;
1072}
1073
[email protected]c4538072013-03-18 02:17:551074void BrowserPluginGuest::Attach(
1075 WebContentsImpl* embedder_web_contents,
[email protected]538334712013-09-14 21:29:011076 BrowserPluginHostMsg_Attach_Params params,
1077 const base::DictionaryValue& extra_params) {
[email protected]4b4ed582013-05-01 00:16:231078 if (attached())
1079 return;
1080
[email protected]538334712013-09-14 21:29:011081 extra_attach_params_.reset(extra_params.DeepCopy());
1082
[email protected]4b4ed582013-05-01 00:16:231083 // Clear parameters that get inherited from the opener.
1084 params.storage_partition_id.clear();
1085 params.persist_storage = false;
1086 params.src.clear();
1087
[email protected]0c6d41752013-05-01 15:49:091088 // If a RenderView has already been created for this new window, then we need
[email protected]b0936d22013-11-28 06:47:361089 // to initialize the browser-side state now so that the RenderFrameHostManager
[email protected]0c6d41752013-05-01 15:49:091090 // does not create a new RenderView on navigation.
1091 if (has_render_view_) {
1092 static_cast<RenderViewHostImpl*>(
1093 GetWebContents()->GetRenderViewHost())->Init();
[email protected]c4538072013-03-18 02:17:551094 WebContentsViewGuest* new_view =
1095 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
1096 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost());
[email protected]c4538072013-03-18 02:17:551097 }
[email protected]0c6d41752013-05-01 15:49:091098
[email protected]7fdb6ac2014-02-07 18:33:321099 // We need to do a navigation here if the target URL has changed between
1100 // the time the WebContents was created and the time it was attached.
1101 // We also need to do an initial navigation if a RenderView was never
1102 // created for the new window in cases where there is no referrer.
[email protected]0c6d41752013-05-01 15:49:091103 PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
1104 if (it != opener()->pending_new_windows_.end()) {
[email protected]7fdb6ac2014-02-07 18:33:321105 const NewWindowInfo& new_window_info = it->second;
1106 if (new_window_info.changed || !has_render_view_)
1107 params.src = it->second.url.spec();
[email protected]0c6d41752013-05-01 15:49:091108 } else {
1109 NOTREACHED();
1110 }
1111
[email protected]c4538072013-03-18 02:17:551112 // Once a new guest is attached to the DOM of the embedder page, then the
1113 // lifetime of the new guest is no longer managed by the opener guest.
1114 opener()->pending_new_windows_.erase(this);
1115
[email protected]50de3222013-03-20 15:36:131116 // The guest's frame name takes precedence over the BrowserPlugin's name.
1117 // The guest's frame name is assigned in
1118 // BrowserPluginGuest::WebContentsCreated.
1119 if (!name_.empty())
1120 params.name.clear();
1121
[email protected]c61b317c72013-11-14 06:40:461122 Initialize(params, embedder_web_contents);
[email protected]c4538072013-03-18 02:17:551123
[email protected]697f16b52013-05-10 06:01:181124 SendQueuedMessages();
[email protected]abc7d5c2013-05-15 09:19:251125
[email protected]e6e30ac2014-01-13 21:24:391126 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Attached"));
[email protected]c4538072013-03-18 02:17:551127}
1128
[email protected]95d31822014-01-03 22:21:551129void BrowserPluginGuest::OnCompositorFrameSwappedACK(
[email protected]f5b4b0f2013-04-02 18:16:281130 int instance_id,
[email protected]95d31822014-01-03 22:21:551131 const FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
1132 RenderWidgetHostImpl::SendSwapCompositorFrameAck(params.producing_route_id,
1133 params.output_surface_id,
1134 params.producing_host_id,
1135 params.ack);
[email protected]f5b4b0f2013-04-02 18:16:281136}
1137
[email protected]3997b1b22012-12-20 01:02:541138void BrowserPluginGuest::OnDragStatusUpdate(int instance_id,
[email protected]180ef242013-11-07 06:50:461139 blink::WebDragStatus drag_status,
[email protected]dc293a72013-07-01 11:11:221140 const DropData& drop_data,
[email protected]180ef242013-11-07 06:50:461141 blink::WebDragOperationsMask mask,
[email protected]3997b1b22012-12-20 01:02:541142 const gfx::Point& location) {
[email protected]8eb04562013-03-06 03:41:141143 RenderViewHost* host = GetWebContents()->GetRenderViewHost();
[email protected]3997b1b22012-12-20 01:02:541144 switch (drag_status) {
[email protected]180ef242013-11-07 06:50:461145 case blink::WebDragStatusEnter:
[email protected]cf200a562013-05-03 16:24:291146 embedder_web_contents_->GetBrowserPluginEmbedder()->DragEnteredGuest(
1147 this);
[email protected]3997b1b22012-12-20 01:02:541148 host->DragTargetDragEnter(drop_data, location, location, mask, 0);
1149 break;
[email protected]180ef242013-11-07 06:50:461150 case blink::WebDragStatusOver:
[email protected]3997b1b22012-12-20 01:02:541151 host->DragTargetDragOver(location, location, mask, 0);
1152 break;
[email protected]180ef242013-11-07 06:50:461153 case blink::WebDragStatusLeave:
[email protected]cf200a562013-05-03 16:24:291154 embedder_web_contents_->GetBrowserPluginEmbedder()->DragLeftGuest(this);
[email protected]3997b1b22012-12-20 01:02:541155 host->DragTargetDragLeave();
1156 break;
[email protected]180ef242013-11-07 06:50:461157 case blink::WebDragStatusDrop:
[email protected]3997b1b22012-12-20 01:02:541158 host->DragTargetDrop(location, location, 0);
[email protected]cf200a562013-05-03 16:24:291159 EndSystemDrag();
[email protected]3997b1b22012-12-20 01:02:541160 break;
[email protected]180ef242013-11-07 06:50:461161 case blink::WebDragStatusUnknown:
[email protected]3997b1b22012-12-20 01:02:541162 NOTREACHED();
1163 }
1164}
1165
[email protected]6dd17a8a2013-05-01 05:50:101166void BrowserPluginGuest::OnExecuteEditCommand(int instance_id,
1167 const std::string& name) {
1168 Send(new InputMsg_ExecuteEditCommand(routing_id(), name, std::string()));
1169}
1170
[email protected]d260f042013-12-14 01:31:361171void BrowserPluginGuest::OnImeSetComposition(
1172 int instance_id,
1173 const std::string& text,
1174 const std::vector<blink::WebCompositionUnderline>& underlines,
1175 int selection_start,
1176 int selection_end) {
1177 Send(new ViewMsg_ImeSetComposition(routing_id(),
[email protected]32956122013-12-25 07:29:241178 base::UTF8ToUTF16(text), underlines,
[email protected]d260f042013-12-14 01:31:361179 selection_start, selection_end));
1180}
1181
1182void BrowserPluginGuest::OnImeConfirmComposition(
1183 int instance_id,
1184 const std::string& text,
1185 bool keep_selection) {
1186 Send(new ViewMsg_ImeConfirmComposition(routing_id(),
[email protected]32956122013-12-25 07:29:241187 base::UTF8ToUTF16(text),
[email protected]d260f042013-12-14 01:31:361188 gfx::Range::InvalidRange(),
1189 keep_selection));
1190}
1191
1192void BrowserPluginGuest::OnExtendSelectionAndDelete(
1193 int instance_id,
1194 int before,
1195 int after) {
[email protected]e5e438d62014-03-27 21:47:161196 RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
1197 web_contents()->GetFocusedFrame());
1198 if (rfh)
1199 rfh->ExtendSelectionAndDelete(before, after);
[email protected]d260f042013-12-14 01:31:361200}
1201
[email protected]b0030b72013-11-15 20:35:531202void BrowserPluginGuest::OnReclaimCompositorResources(
1203 int instance_id,
[email protected]bffc8302014-01-23 20:52:161204 const FrameHostMsg_ReclaimCompositorResources_Params& params) {
1205 RenderWidgetHostImpl::SendReclaimCompositorResources(params.route_id,
1206 params.output_surface_id,
1207 params.renderer_host_id,
1208 params.ack);
[email protected]b0030b72013-11-15 20:35:531209}
1210
[email protected]3997b1b22012-12-20 01:02:541211void BrowserPluginGuest::OnHandleInputEvent(
1212 int instance_id,
1213 const gfx::Rect& guest_window_rect,
[email protected]180ef242013-11-07 06:50:461214 const blink::WebInputEvent* event) {
[email protected]3997b1b22012-12-20 01:02:541215 guest_window_rect_ = guest_window_rect;
[email protected]c6ea9212013-04-09 18:51:561216 // If the embedder's RWHV is destroyed then that means that the embedder's
1217 // window has been closed but the embedder's WebContents has not yet been
1218 // destroyed. Computing screen coordinates of a BrowserPlugin only makes sense
1219 // if there is a visible embedder.
1220 if (embedder_web_contents_->GetRenderWidgetHostView()) {
1221 guest_screen_rect_ = guest_window_rect;
1222 guest_screen_rect_.Offset(
1223 embedder_web_contents_->GetRenderWidgetHostView()->
1224 GetViewBounds().OffsetFromOrigin());
1225 }
[email protected]3997b1b22012-12-20 01:02:541226 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
[email protected]8eb04562013-03-06 03:41:141227 GetWebContents()->GetRenderViewHost());
[email protected]3997b1b22012-12-20 01:02:541228
[email protected]180ef242013-11-07 06:50:461229 if (blink::WebInputEvent::isMouseEventType(event->type)) {
[email protected]bca6c2c2013-03-24 03:55:071230 guest_rvh->ForwardMouseEvent(
[email protected]180ef242013-11-07 06:50:461231 *static_cast<const blink::WebMouseEvent*>(event));
[email protected]bca6c2c2013-03-24 03:55:071232 return;
[email protected]3997b1b22012-12-20 01:02:541233 }
1234
[email protected]180ef242013-11-07 06:50:461235 if (event->type == blink::WebInputEvent::MouseWheel) {
[email protected]bca6c2c2013-03-24 03:55:071236 guest_rvh->ForwardWheelEvent(
[email protected]180ef242013-11-07 06:50:461237 *static_cast<const blink::WebMouseWheelEvent*>(event));
[email protected]bca6c2c2013-03-24 03:55:071238 return;
1239 }
1240
[email protected]180ef242013-11-07 06:50:461241 if (blink::WebInputEvent::isKeyboardEventType(event->type)) {
[email protected]6dd17a8a2013-05-01 05:50:101242 RenderViewHostImpl* embedder_rvh = static_cast<RenderViewHostImpl*>(
1243 embedder_web_contents_->GetRenderViewHost());
1244 if (!embedder_rvh->GetLastKeyboardEvent())
1245 return;
1246 NativeWebKeyboardEvent keyboard_event(
1247 *embedder_rvh->GetLastKeyboardEvent());
[email protected]bca6c2c2013-03-24 03:55:071248 guest_rvh->ForwardKeyboardEvent(keyboard_event);
1249 return;
1250 }
1251
[email protected]180ef242013-11-07 06:50:461252 if (blink::WebInputEvent::isTouchEventType(event->type)) {
[email protected]de860e02013-06-18 23:48:311253 guest_rvh->ForwardTouchEventWithLatencyInfo(
[email protected]180ef242013-11-07 06:50:461254 *static_cast<const blink::WebTouchEvent*>(event),
[email protected]de860e02013-06-18 23:48:311255 ui::LatencyInfo());
[email protected]bca6c2c2013-03-24 03:55:071256 return;
1257 }
1258
[email protected]180ef242013-11-07 06:50:461259 if (blink::WebInputEvent::isGestureEventType(event->type)) {
[email protected]bca6c2c2013-03-24 03:55:071260 guest_rvh->ForwardGestureEvent(
[email protected]180ef242013-11-07 06:50:461261 *static_cast<const blink::WebGestureEvent*>(event));
[email protected]bca6c2c2013-03-24 03:55:071262 return;
1263 }
[email protected]3997b1b22012-12-20 01:02:541264}
1265
[email protected]861f9782013-03-05 03:29:541266void BrowserPluginGuest::OnLockMouse(bool user_gesture,
1267 bool last_unlocked_by_target,
1268 bool privileged) {
[email protected]02768b762013-10-02 20:39:341269 if (pending_lock_request_) {
[email protected]a25acea72013-03-10 23:41:281270 // Immediately reject the lock because only one pointerLock may be active
1271 // at a time.
1272 Send(new ViewMsg_LockMouse_ACK(routing_id(), false));
1273 return;
1274 }
[email protected]a25acea72013-03-10 23:41:281275
[email protected]7a1280892014-04-16 17:18:251276 if (!delegate_)
1277 return;
1278
1279 pending_lock_request_ = true;
1280
1281 delegate_->RequestPointerLockPermission(
1282 user_gesture,
1283 last_unlocked_by_target,
1284 base::Bind(&BrowserPluginGuest::PointerLockPermissionResponse,
1285 weak_ptr_factory_.GetWeakPtr()));
[email protected]861f9782013-03-05 03:29:541286}
1287
1288void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) {
1289 Send(new ViewMsg_LockMouse_ACK(routing_id(), succeeded));
[email protected]a25acea72013-03-10 23:41:281290 pending_lock_request_ = false;
[email protected]861f9782013-03-05 03:29:541291 if (succeeded)
1292 mouse_locked_ = true;
1293}
1294
[email protected]5e7967972013-01-15 22:45:331295void BrowserPluginGuest::OnNavigateGuest(
1296 int instance_id,
1297 const std::string& src) {
[email protected]f8d2abf2013-10-31 20:51:321298 GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src);
[email protected]4b499622013-08-22 02:25:591299
[email protected]7fdb6ac2014-02-07 18:33:321300 // Do not allow navigating a guest to schemes other than known safe schemes.
1301 // This will block the embedder trying to load unwanted schemes, e.g.
1302 // chrome://settings.
1303 bool scheme_is_blocked =
1304 (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme(
1305 url.scheme()) &&
1306 !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme(
1307 url.scheme())) ||
1308 url.SchemeIs(kJavaScriptScheme);
1309 if (scheme_is_blocked || !url.is_valid()) {
1310 if (delegate_) {
1311 std::string error_type;
1312 base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::",
1313 &error_type);
1314 delegate_->LoadAbort(true /* is_top_level */, url, error_type);
1315 }
1316 return;
1317 }
1318
1319 GURL validated_url(url);
1320 GetWebContents()->GetRenderProcessHost()->FilterURL(false, &validated_url);
[email protected]09449dd52013-10-09 20:28:561321 // As guests do not swap processes on navigation, only navigations to
1322 // normal web URLs are supported. No protocol handlers are installed for
1323 // other schemes (e.g., WebUI or extensions), and no permissions or bindings
1324 // can be granted to the guest process.
[email protected]7fdb6ac2014-02-07 18:33:321325 LoadURLWithParams(validated_url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL,
[email protected]c61b317c72013-11-14 06:40:461326 GetWebContents());
[email protected]5e7967972013-01-15 22:45:331327}
1328
[email protected]b371a5652013-02-20 11:25:511329void BrowserPluginGuest::OnPluginDestroyed(int instance_id) {
[email protected]b371a5652013-02-20 11:25:511330 Destroy();
1331}
1332
[email protected]3997b1b22012-12-20 01:02:541333void BrowserPluginGuest::OnResizeGuest(
1334 int instance_id,
1335 const BrowserPluginHostMsg_ResizeGuest_Params& params) {
[email protected]197ce112013-07-23 01:13:291336 if (!params.size_changed)
1337 return;
[email protected]3997b1b22012-12-20 01:02:541338 // BrowserPlugin manages resize flow control itself and does not depend
1339 // on RenderWidgetHost's mechanisms for flow control, so we reset those flags
1340 // here. If we are setting the size for the first time before navigating then
1341 // BrowserPluginGuest does not yet have a RenderViewHost.
[email protected]8eb04562013-03-06 03:41:141342 if (GetWebContents()->GetRenderViewHost()) {
[email protected]3997b1b22012-12-20 01:02:541343 RenderWidgetHostImpl* render_widget_host =
[email protected]8eb04562013-03-06 03:41:141344 RenderWidgetHostImpl::From(GetWebContents()->GetRenderViewHost());
[email protected]3997b1b22012-12-20 01:02:541345 render_widget_host->ResetSizeAndRepaintPendingFlags();
[email protected]caaf2482013-05-01 20:33:321346
1347 if (guest_device_scale_factor_ != params.scale_factor) {
1348 guest_device_scale_factor_ = params.scale_factor;
1349 render_widget_host->NotifyScreenInfoChanged();
1350 }
[email protected]3997b1b22012-12-20 01:02:541351 }
[email protected]63449722013-08-13 02:31:321352 // When autosize is turned off and as a result there is a layout change, we
1353 // send a sizechanged event.
1354 if (!auto_size_enabled_ && last_seen_auto_size_enabled_ &&
1355 !params.view_rect.size().IsEmpty() && delegate_) {
1356 delegate_->SizeChanged(last_seen_view_size_, params.view_rect.size());
1357 last_seen_auto_size_enabled_ = false;
1358 }
[email protected]caaf2482013-05-01 20:33:321359 // Invalid damage buffer means we are in HW compositing mode,
1360 // so just resize the WebContents and repaint if needed.
[email protected]685acc22013-12-03 21:10:021361 if (base::SharedMemory::IsHandleValid(params.damage_buffer_handle))
1362 SetDamageBuffer(params);
1363 if (!params.view_rect.size().IsEmpty())
1364 GetWebContents()->GetView()->SizeContents(params.view_rect.size());
[email protected]8eb04562013-03-06 03:41:141365 if (params.repaint)
[email protected]32deec62013-05-15 23:55:041366 Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size()));
[email protected]3997b1b22012-12-20 01:02:541367}
1368
[email protected]423838472013-01-09 00:16:461369void BrowserPluginGuest::OnSetFocus(int instance_id, bool focused) {
[email protected]423838472013-01-09 00:16:461370 focused_ = focused;
[email protected]c084330e02013-04-27 01:08:151371 Send(new InputMsg_SetFocus(routing_id(), focused));
[email protected]79733a02013-04-30 15:05:351372 if (!focused && mouse_locked_)
1373 OnUnlockMouse();
[email protected]63c33bd62014-02-08 04:45:401374
1375 // Restore the last seen state of text input to the view.
1376 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
1377 web_contents()->GetRenderWidgetHostView());
1378 if (rwhv) {
1379 rwhv->TextInputTypeChanged(last_text_input_type_, last_input_mode_,
1380 last_can_compose_inline_);
1381 }
[email protected]423838472013-01-09 00:16:461382}
1383
[email protected]25bcc8f2013-01-09 02:49:251384void BrowserPluginGuest::OnSetName(int instance_id, const std::string& name) {
1385 if (name == name_)
1386 return;
1387 name_ = name;
[email protected]8eb04562013-03-06 03:41:141388 Send(new ViewMsg_SetName(routing_id(), name));
[email protected]25bcc8f2013-01-09 02:49:251389}
1390
[email protected]3997b1b22012-12-20 01:02:541391void BrowserPluginGuest::OnSetSize(
1392 int instance_id,
1393 const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
1394 const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
1395 bool old_auto_size_enabled = auto_size_enabled_;
1396 gfx::Size old_max_size = max_auto_size_;
1397 gfx::Size old_min_size = min_auto_size_;
1398 auto_size_enabled_ = auto_size_params.enable;
1399 max_auto_size_ = auto_size_params.max_size;
1400 min_auto_size_ = auto_size_params.min_size;
1401 if (auto_size_enabled_ && (!old_auto_size_enabled ||
1402 (old_max_size != max_auto_size_) ||
1403 (old_min_size != min_auto_size_))) {
[email protected]e6e30ac2014-01-13 21:24:391404 RecordAction(
1405 base::UserMetricsAction("BrowserPlugin.Guest.EnableAutoResize"));
[email protected]8eb04562013-03-06 03:41:141406 GetWebContents()->GetRenderViewHost()->EnableAutoResize(
[email protected]3997b1b22012-12-20 01:02:541407 min_auto_size_, max_auto_size_);
1408 // TODO(fsamuel): If we're changing autosize parameters, then we force
1409 // the guest to completely repaint itself, because BrowserPlugin has
1410 // allocated a new damage buffer and expects a full frame of pixels.
1411 // Ideally, we shouldn't need to do this because we shouldn't need to
1412 // allocate a new damage buffer unless |max_auto_size_| has changed.
1413 // However, even in that case, layout may not change and so we may
1414 // not get a full frame worth of pixels.
[email protected]8eb04562013-03-06 03:41:141415 Send(new ViewMsg_Repaint(routing_id(), max_auto_size_));
[email protected]3997b1b22012-12-20 01:02:541416 } else if (!auto_size_enabled_ && old_auto_size_enabled) {
[email protected]8eb04562013-03-06 03:41:141417 GetWebContents()->GetRenderViewHost()->DisableAutoResize(
[email protected]32deec62013-05-15 23:55:041418 resize_guest_params.view_rect.size());
[email protected]3997b1b22012-12-20 01:02:541419 }
1420 OnResizeGuest(instance_id_, resize_guest_params);
1421}
1422
[email protected]b77fac52013-06-01 01:03:461423void BrowserPluginGuest::OnSetEditCommandsForNextKeyEvent(
1424 int instance_id,
1425 const std::vector<EditCommand>& edit_commands) {
1426 Send(new InputMsg_SetEditCommandsForNextKeyEvent(routing_id(),
1427 edit_commands));
1428}
1429
[email protected]c7fc429d2013-11-28 05:49:361430void BrowserPluginGuest::OnSetContentsOpaque(int instance_id, bool opaque) {
1431 guest_opaque_ = opaque;
1432
1433 SkBitmap background;
1434 if (!guest_opaque_) {
1435 background.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
1436 unsigned int color = 0;
1437 background.setPixels(&color);
1438 }
1439 Send(new ViewMsg_SetBackground(routing_id(), background));
1440}
1441
[email protected]3997b1b22012-12-20 01:02:541442void BrowserPluginGuest::OnSetVisibility(int instance_id, bool visible) {
[email protected]93564f72013-02-15 13:26:191443 guest_visible_ = visible;
1444 if (embedder_visible_ && guest_visible_)
[email protected]8eb04562013-03-06 03:41:141445 GetWebContents()->WasShown();
[email protected]3997b1b22012-12-20 01:02:541446 else
[email protected]8eb04562013-03-06 03:41:141447 GetWebContents()->WasHidden();
[email protected]3997b1b22012-12-20 01:02:541448}
1449
[email protected]861f9782013-03-05 03:29:541450void BrowserPluginGuest::OnUnlockMouse() {
[email protected]b60b88942013-07-20 05:58:421451 SendMessageToEmbedder(
1452 new BrowserPluginMsg_SetMouseLock(instance_id(), false));
[email protected]861f9782013-03-05 03:29:541453}
1454
1455void BrowserPluginGuest::OnUnlockMouseAck(int instance_id) {
1456 // mouse_locked_ could be false here if the lock attempt was cancelled due
1457 // to window focus, or for various other reasons before the guest was informed
1458 // of the lock's success.
1459 if (mouse_locked_)
1460 Send(new ViewMsg_MouseLockLost(routing_id()));
1461 mouse_locked_ = false;
1462}
1463
[email protected]3997b1b22012-12-20 01:02:541464void BrowserPluginGuest::OnUpdateRectACK(
1465 int instance_id,
[email protected]7c99b002013-08-01 23:58:211466 bool needs_ack,
[email protected]3997b1b22012-12-20 01:02:541467 const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
1468 const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
[email protected]7c99b002013-08-01 23:58:211469 // Only the software path expects an ACK.
1470 if (needs_ack)
1471 Send(new ViewMsg_UpdateRect_ACK(routing_id()));
[email protected]3997b1b22012-12-20 01:02:541472 OnSetSize(instance_id_, auto_size_params, resize_guest_params);
1473}
1474
[email protected]73405fb2013-12-11 04:59:371475void BrowserPluginGuest::OnCopyFromCompositingSurfaceAck(
1476 int instance_id,
1477 int request_id,
1478 const SkBitmap& bitmap) {
1479 CHECK(copy_request_callbacks_.count(request_id));
1480 if (!copy_request_callbacks_.count(request_id))
1481 return;
1482 const CopyRequestCallback& callback = copy_request_callbacks_[request_id];
1483 callback.Run(!bitmap.empty() && !bitmap.isNull(), bitmap);
1484 copy_request_callbacks_.erase(request_id);
1485}
1486
[email protected]32deec62013-05-15 23:55:041487void BrowserPluginGuest::OnUpdateGeometry(int instance_id,
1488 const gfx::Rect& view_rect) {
1489 // The plugin has moved within the embedder without resizing or the
1490 // embedder/container's view rect changing.
1491 guest_window_rect_ = view_rect;
1492 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
1493 GetWebContents()->GetRenderViewHost());
1494 if (rvh)
1495 rvh->SendScreenRects();
1496}
1497
[email protected]a7fac9a2012-12-18 23:26:071498void BrowserPluginGuest::OnHasTouchEventHandlers(bool accept) {
1499 SendMessageToEmbedder(
[email protected]d752fe62013-03-01 03:46:011500 new BrowserPluginMsg_ShouldAcceptTouchEvents(instance_id(), accept));
[email protected]a7fac9a2012-12-18 23:26:071501}
1502
1503void BrowserPluginGuest::OnSetCursor(const WebCursor& cursor) {
[email protected]d752fe62013-03-01 03:46:011504 SendMessageToEmbedder(new BrowserPluginMsg_SetCursor(instance_id(), cursor));
[email protected]a7fac9a2012-12-18 23:26:071505}
1506
1507#if defined(OS_MACOSX)
1508void BrowserPluginGuest::OnShowPopup(
1509 const ViewHostMsg_ShowPopup_Params& params) {
1510 gfx::Rect translated_bounds(params.bounds);
1511 translated_bounds.Offset(guest_window_rect_.OffsetFromOrigin());
1512 BrowserPluginPopupMenuHelper popup_menu_helper(
1513 embedder_web_contents_->GetRenderViewHost(),
[email protected]8eb04562013-03-06 03:41:141514 GetWebContents()->GetRenderViewHost());
[email protected]a7fac9a2012-12-18 23:26:071515 popup_menu_helper.ShowPopupMenu(translated_bounds,
1516 params.item_height,
1517 params.item_font_size,
1518 params.selected_item,
1519 params.popup_items,
1520 params.right_aligned,
1521 params.allow_multiple_selection);
1522}
1523#endif
1524
1525void BrowserPluginGuest::OnShowWidget(int route_id,
1526 const gfx::Rect& initial_pos) {
[email protected]32deec62013-05-15 23:55:041527 GetWebContents()->ShowCreatedWidget(route_id, initial_pos);
[email protected]a7fac9a2012-12-18 23:26:071528}
1529
1530void BrowserPluginGuest::OnTakeFocus(bool reverse) {
1531 SendMessageToEmbedder(
[email protected]d752fe62013-03-01 03:46:011532 new BrowserPluginMsg_AdvanceFocus(instance_id(), reverse));
[email protected]a7fac9a2012-12-18 23:26:071533}
1534
[email protected]25bcc8f2013-01-09 02:49:251535void BrowserPluginGuest::OnUpdateFrameName(int frame_id,
1536 bool is_top_level,
1537 const std::string& name) {
1538 if (!is_top_level)
1539 return;
1540
1541 name_ = name;
[email protected]d752fe62013-03-01 03:46:011542 SendMessageToEmbedder(new BrowserPluginMsg_UpdatedName(instance_id_, name));
[email protected]25bcc8f2013-01-09 02:49:251543}
1544
[email protected]c006fb52013-03-01 09:36:451545void BrowserPluginGuest::RequestMediaAccessPermission(
1546 WebContents* web_contents,
[email protected]ce0e2602013-03-15 20:53:271547 const MediaStreamRequest& request,
1548 const MediaResponseCallback& callback) {
[email protected]cecf8262014-04-15 23:05:551549 if (!delegate_) {
1550 callback.Run(MediaStreamDevices(),
1551 MEDIA_DEVICE_INVALID_STATE,
1552 scoped_ptr<MediaStreamUI>());
1553 return;
1554 }
[email protected]291dcf32013-07-28 08:02:141555
[email protected]cecf8262014-04-15 23:05:551556 delegate_->RequestMediaAccessPermission(request, callback);
[email protected]c006fb52013-03-01 09:36:451557}
1558
[email protected]04bce562014-01-30 05:34:541559bool BrowserPluginGuest::PreHandleGestureEvent(
1560 WebContents* source, const blink::WebGestureEvent& event) {
1561 return event.type == blink::WebGestureEvent::GesturePinchBegin ||
1562 event.type == blink::WebGestureEvent::GesturePinchUpdate ||
1563 event.type == blink::WebGestureEvent::GesturePinchEnd;
1564}
1565
[email protected]1c514fc2013-07-24 07:30:531566void BrowserPluginGuest::RunJavaScriptDialog(
1567 WebContents* web_contents,
1568 const GURL& origin_url,
1569 const std::string& accept_lang,
1570 JavaScriptMessageType javascript_message_type,
[email protected]fcf75d42013-12-03 20:11:261571 const base::string16& message_text,
1572 const base::string16& default_prompt_text,
[email protected]1c514fc2013-07-24 07:30:531573 const DialogClosedCallback& callback,
1574 bool* did_suppress_message) {
[email protected]1c514fc2013-07-24 07:30:531575 base::DictionaryValue request_info;
1576 request_info.Set(
1577 browser_plugin::kDefaultPromptText,
[email protected]32956122013-12-25 07:29:241578 base::Value::CreateStringValue(base::UTF16ToUTF8(default_prompt_text)));
[email protected]1c514fc2013-07-24 07:30:531579 request_info.Set(
1580 browser_plugin::kMessageText,
[email protected]32956122013-12-25 07:29:241581 base::Value::CreateStringValue(base::UTF16ToUTF8(message_text)));
[email protected]1c514fc2013-07-24 07:30:531582 request_info.Set(
1583 browser_plugin::kMessageType,
1584 base::Value::CreateStringValue(
1585 JavaScriptMessageTypeToString(javascript_message_type)));
1586 request_info.Set(
1587 browser_plugin::kURL,
1588 base::Value::CreateStringValue(origin_url.spec()));
[email protected]291dcf32013-07-28 08:02:141589
[email protected]af1718c2013-08-12 19:59:191590 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_JAVASCRIPT_DIALOG,
[email protected]bfb9e9a2014-01-29 22:36:181591 new JavaScriptDialogRequest(weak_ptr_factory_.GetWeakPtr(),
1592 callback),
[email protected]291dcf32013-07-28 08:02:141593 request_info);
[email protected]1c514fc2013-07-24 07:30:531594}
1595
1596void BrowserPluginGuest::RunBeforeUnloadDialog(
1597 WebContents* web_contents,
[email protected]fcf75d42013-12-03 20:11:261598 const base::string16& message_text,
[email protected]1c514fc2013-07-24 07:30:531599 bool is_reload,
1600 const DialogClosedCallback& callback) {
1601 // This is called if the guest has a beforeunload event handler.
1602 // This callback allows navigation to proceed.
[email protected]fcf75d42013-12-03 20:11:261603 callback.Run(true, base::string16());
[email protected]1c514fc2013-07-24 07:30:531604}
1605
1606bool BrowserPluginGuest::HandleJavaScriptDialog(
1607 WebContents* web_contents,
1608 bool accept,
[email protected]fcf75d42013-12-03 20:11:261609 const base::string16* prompt_override) {
[email protected]1c514fc2013-07-24 07:30:531610 return false;
1611}
1612
[email protected]4567f152013-07-31 13:20:111613void BrowserPluginGuest::CancelActiveAndPendingDialogs(
1614 WebContents* web_contents) {
1615}
1616
1617void BrowserPluginGuest::WebContentsDestroyed(WebContents* web_contents) {
[email protected]1c514fc2013-07-24 07:30:531618}
1619
[email protected]a7fac9a2012-12-18 23:26:071620void BrowserPluginGuest::OnUpdateRect(
1621 const ViewHostMsg_UpdateRect_Params& params) {
[email protected]a7fac9a2012-12-18 23:26:071622 BrowserPluginMsg_UpdateRect_Params relay_params;
1623 relay_params.view_size = params.view_size;
1624 relay_params.scale_factor = params.scale_factor;
1625 relay_params.is_resize_ack = ViewHostMsg_UpdateRect_Flags::is_resize_ack(
1626 params.flags);
[email protected]166f61a2013-01-09 23:54:491627 relay_params.needs_ack = params.needs_ack;
[email protected]a7fac9a2012-12-18 23:26:071628
[email protected]63449722013-08-13 02:31:321629 bool size_changed = last_seen_view_size_ != params.view_size;
1630 gfx::Size old_size = last_seen_view_size_;
1631 last_seen_view_size_ = params.view_size;
1632
1633 if ((auto_size_enabled_ || last_seen_auto_size_enabled_) &&
1634 size_changed && delegate_) {
1635 delegate_->SizeChanged(old_size, last_seen_view_size_);
1636 }
1637 last_seen_auto_size_enabled_ = auto_size_enabled_;
1638
[email protected]a7fac9a2012-12-18 23:26:071639 // HW accelerated case, acknowledge resize only
[email protected]61c555422013-01-31 19:31:061640 if (!params.needs_ack || !damage_buffer_) {
[email protected]4d1afd62012-12-21 03:09:401641 relay_params.damage_buffer_sequence_id = 0;
[email protected]d752fe62013-03-01 03:46:011642 SendMessageToEmbedder(
1643 new BrowserPluginMsg_UpdateRect(instance_id(), relay_params));
1644 return;
[email protected]a7fac9a2012-12-18 23:26:071645 }
1646
[email protected]a7fac9a2012-12-18 23:26:071647 // Only copy damage if the guest is in autosize mode and the guest's view size
1648 // is less than the maximum size or the guest's view size is equal to the
1649 // damage buffer's size and the guest's scale factor is equal to the damage
1650 // buffer's scale factor.
1651 // The scaling change can happen due to asynchronous updates of the DPI on a
1652 // resolution change.
1653 if (((auto_size_enabled_ && InAutoSizeBounds(params.view_size)) ||
[email protected]32deec62013-05-15 23:55:041654 (params.view_size == damage_view_size())) &&
[email protected]a7fac9a2012-12-18 23:26:071655 params.scale_factor == damage_buffer_scale_factor()) {
[email protected]8eb04562013-03-06 03:41:141656 TransportDIB* dib = GetWebContents()->GetRenderProcessHost()->
[email protected]a7fac9a2012-12-18 23:26:071657 GetTransportDIB(params.bitmap);
1658 if (dib) {
[email protected]4d1afd62012-12-21 03:09:401659 size_t guest_damage_buffer_size =
[email protected]a7fac9a2012-12-18 23:26:071660#if defined(OS_WIN)
[email protected]4d1afd62012-12-21 03:09:401661 params.bitmap_rect.width() *
1662 params.bitmap_rect.height() * 4;
[email protected]a7fac9a2012-12-18 23:26:071663#else
[email protected]4d1afd62012-12-21 03:09:401664 dib->size();
[email protected]a7fac9a2012-12-18 23:26:071665#endif
[email protected]4d1afd62012-12-21 03:09:401666 size_t embedder_damage_buffer_size = damage_buffer_size_;
[email protected]a7fac9a2012-12-18 23:26:071667 void* guest_memory = dib->memory();
1668 void* embedder_memory = damage_buffer_->memory();
1669 size_t size = std::min(guest_damage_buffer_size,
1670 embedder_damage_buffer_size);
1671 memcpy(embedder_memory, guest_memory, size);
1672 }
1673 }
[email protected]4d1afd62012-12-21 03:09:401674 relay_params.damage_buffer_sequence_id = damage_buffer_sequence_id_;
[email protected]a7fac9a2012-12-18 23:26:071675 relay_params.bitmap_rect = params.bitmap_rect;
1676 relay_params.scroll_delta = params.scroll_delta;
1677 relay_params.scroll_rect = params.scroll_rect;
1678 relay_params.copy_rects = params.copy_rects;
1679
[email protected]d752fe62013-03-01 03:46:011680 SendMessageToEmbedder(
1681 new BrowserPluginMsg_UpdateRect(instance_id(), relay_params));
[email protected]7a846df2012-09-20 19:17:391682}
1683
[email protected]d260f042013-12-14 01:31:361684void BrowserPluginGuest::OnTextInputTypeChanged(ui::TextInputType type,
1685 ui::TextInputMode input_mode,
1686 bool can_compose_inline) {
[email protected]63c33bd62014-02-08 04:45:401687 // Save the state of text input so we can restore it on focus.
1688 last_text_input_type_ = type;
1689 last_input_mode_ = input_mode;
1690 last_can_compose_inline_ = can_compose_inline;
1691
[email protected]d260f042013-12-14 01:31:361692 RenderWidgetHostViewPort::FromRWHV(
1693 web_contents()->GetRenderWidgetHostView())->TextInputTypeChanged(
1694 type, input_mode, can_compose_inline);
1695}
1696
1697void BrowserPluginGuest::OnImeCancelComposition() {
1698 RenderWidgetHostViewPort::FromRWHV(
1699 web_contents()->GetRenderWidgetHostView())->ImeCancelComposition();
1700}
1701
[email protected]f9db7d2d2014-04-11 16:07:111702#if defined(OS_MACOSX) || defined(USE_AURA)
[email protected]d260f042013-12-14 01:31:361703void BrowserPluginGuest::OnImeCompositionRangeChanged(
1704 const gfx::Range& range,
1705 const std::vector<gfx::Rect>& character_bounds) {
1706 RenderWidgetHostViewPort::FromRWHV(
1707 web_contents()->GetRenderWidgetHostView())->ImeCompositionRangeChanged(
1708 range, character_bounds);
1709}
1710#endif
1711
[email protected]f85f5032013-04-03 09:01:541712void BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId(
1713 const std::string& request_method,
[email protected]291dcf32013-07-28 08:02:141714 const base::Callback<void(bool)>& callback,
[email protected]922bd4ab2014-04-16 05:02:381715 const GURL& url) {
1716 if (!url.is_valid()) {
[email protected]291dcf32013-07-28 08:02:141717 callback.Run(false);
[email protected]f85f5032013-04-03 09:01:541718 return;
1719 }
1720
[email protected]922bd4ab2014-04-16 05:02:381721 delegate_->CanDownload(request_method, url, callback);
[email protected]f85f5032013-04-03 09:01:541722}
1723
[email protected]7a846df2012-09-20 19:17:391724} // namespace content