Message forwarding code for for webview compositing.
[chromium-blink-merge.git] / content / browser / browser_plugin / browser_plugin_guest.cc
blobbf1e2f7789716345edc4e090d499e4cbb9ed6689
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/browser_plugin/browser_plugin_guest.h"
7 #include <algorithm>
9 #include "base/string_util.h"
10 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
11 #include "content/browser/browser_plugin/browser_plugin_guest_helper.h"
12 #include "content/browser/browser_plugin/browser_plugin_host_factory.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/renderer_host/render_widget_host_impl.h"
15 #include "content/browser/web_contents/web_contents_impl.h"
16 #include "content/common/browser_plugin_messages.h"
17 #include "content/common/content_constants_internal.h"
18 #include "content/common/view_messages.h"
19 #include "content/port/browser/render_view_host_delegate_view.h"
20 #include "content/public/browser/notification_service.h"
21 #include "content/public/browser/notification_types.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/render_widget_host_view.h"
24 #include "content/public/browser/resource_request_details.h"
25 #include "content/public/browser/user_metrics.h"
26 #include "content/public/browser/web_contents_view.h"
27 #include "content/public/common/result_codes.h"
28 #include "content/browser/browser_plugin/browser_plugin_host_factory.h"
29 #include "net/base/net_errors.h"
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
31 #include "ui/surface/transport_dib.h"
32 #include "webkit/glue/webdropdata.h"
33 #include "webkit/glue/resource_type.h"
35 #if defined(OS_MACOSX)
36 #include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h"
37 #endif
39 namespace content {
41 // static
42 BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL;
44 BrowserPluginGuest::BrowserPluginGuest(
45 int instance_id,
46 WebContentsImpl* web_contents,
47 const BrowserPluginHostMsg_CreateGuest_Params& params)
48 : WebContentsObserver(web_contents),
49 embedder_web_contents_(NULL),
50 instance_id_(instance_id),
51 #if defined(OS_WIN)
52 damage_buffer_size_(0),
53 remote_damage_buffer_handle_(0),
54 #endif
55 damage_buffer_scale_factor_(1.0f),
56 pending_update_counter_(0),
57 guest_hang_timeout_(
58 base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
59 focused_(params.focused),
60 visible_(params.visible),
61 auto_size_enabled_(params.auto_size_params.enable),
62 max_auto_size_(params.auto_size_params.max_size),
63 min_auto_size_(params.auto_size_params.min_size) {
64 DCHECK(web_contents);
67 void BrowserPluginGuest::InstallHelper(
68 content::RenderViewHost* render_view_host) {
69 // |render_view_host| manages the ownership of this BrowserPluginGuestHelper.
70 new BrowserPluginGuestHelper(this, render_view_host);
72 notification_registrar_.Add(
73 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
74 content::Source<content::WebContents>(web_contents()));
77 BrowserPluginGuest::~BrowserPluginGuest() {
80 // static
81 BrowserPluginGuest* BrowserPluginGuest::Create(
82 int instance_id,
83 WebContentsImpl* web_contents,
84 const BrowserPluginHostMsg_CreateGuest_Params& params) {
85 RecordAction(UserMetricsAction("BrowserPlugin.Guest.Create"));
86 if (factory_) {
87 return factory_->CreateBrowserPluginGuest(instance_id,
88 web_contents,
89 params);
91 return new BrowserPluginGuest(instance_id, web_contents,params);
94 void BrowserPluginGuest::Observe(int type,
95 const NotificationSource& source,
96 const NotificationDetails& details) {
97 switch (type) {
98 case NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: {
99 DCHECK_EQ(Source<WebContents>(source).ptr(), web_contents());
100 ResourceRedirectDetails* resource_redirect_details =
101 Details<ResourceRedirectDetails>(details).ptr();
102 bool is_top_level =
103 resource_redirect_details->resource_type == ResourceType::MAIN_FRAME;
104 LoadRedirect(resource_redirect_details->url,
105 resource_redirect_details->new_url,
106 is_top_level);
107 break;
109 default:
110 NOTREACHED() << "Unexpected notification sent.";
111 break;
115 bool BrowserPluginGuest::ViewTakeFocus(bool reverse) {
116 SendMessageToEmbedder(
117 new BrowserPluginMsg_AdvanceFocus(embedder_routing_id(),
118 instance_id(),
119 reverse));
120 return true;
123 void BrowserPluginGuest::Go(int relative_index) {
124 web_contents()->GetController().GoToOffset(relative_index);
127 bool BrowserPluginGuest::CanDownload(RenderViewHost* render_view_host,
128 int request_id,
129 const std::string& request_method) {
130 // TODO(fsamuel): We disable downloads in guests for now, but we will later
131 // expose API to allow embedders to handle them.
132 // Note: it seems content_shell ignores this. This should be fixed
133 // for debugging and test purposes.
134 return false;
137 bool BrowserPluginGuest::HandleContextMenu(
138 const ContextMenuParams& params) {
139 // TODO(fsamuel): We have a do nothing context menu handler for now until
140 // we implement the Apps Context Menu API for Browser Plugin (see
141 // http://crbug.com/140315).
142 return true;
145 void BrowserPluginGuest::RendererUnresponsive(WebContents* source) {
146 int process_id =
147 web_contents()->GetRenderProcessHost()->GetID();
148 SendMessageToEmbedder(
149 new BrowserPluginMsg_GuestUnresponsive(embedder_routing_id(),
150 instance_id(),
151 process_id));
152 RecordAction(UserMetricsAction("BrowserPlugin.Guest.Hung"));
155 void BrowserPluginGuest::RendererResponsive(WebContents* source) {
156 int process_id =
157 web_contents()->GetRenderProcessHost()->GetID();
158 SendMessageToEmbedder(
159 new BrowserPluginMsg_GuestResponsive(embedder_routing_id(),
160 instance_id(),
161 process_id));
162 RecordAction(UserMetricsAction("BrowserPlugin.Guest.Responsive"));
165 void BrowserPluginGuest::RunFileChooser(WebContents* web_contents,
166 const FileChooserParams& params) {
167 embedder_web_contents_->GetDelegate()->RunFileChooser(web_contents, params);
170 bool BrowserPluginGuest::ShouldFocusPageAfterCrash() {
171 // Rather than managing focus in WebContentsImpl::RenderViewReady, we will
172 // manage the focus ourselves.
173 return false;
176 void BrowserPluginGuest::SetIsAcceptingTouchEvents(bool accept) {
177 SendMessageToEmbedder(
178 new BrowserPluginMsg_ShouldAcceptTouchEvents(embedder_routing_id(),
179 instance_id(),
180 accept));
183 void BrowserPluginGuest::SetVisibility(bool embedder_visible, bool visible) {
184 visible_ = visible;
185 if (embedder_visible && visible)
186 web_contents()->WasShown();
187 else
188 web_contents()->WasHidden();
191 void BrowserPluginGuest::DragStatusUpdate(WebKit::WebDragStatus drag_status,
192 const WebDropData& drop_data,
193 WebKit::WebDragOperationsMask mask,
194 const gfx::Point& location) {
195 RenderViewHost* host = web_contents()->GetRenderViewHost();
196 switch (drag_status) {
197 case WebKit::WebDragStatusEnter:
198 host->DragTargetDragEnter(drop_data, location, location, mask, 0);
199 break;
200 case WebKit::WebDragStatusOver:
201 host->DragTargetDragOver(location, location, mask, 0);
202 break;
203 case WebKit::WebDragStatusLeave:
204 host->DragTargetDragLeave();
205 break;
206 case WebKit::WebDragStatusDrop:
207 host->DragTargetDrop(location, location, 0);
208 break;
209 case WebKit::WebDragStatusUnknown:
210 NOTREACHED();
214 void BrowserPluginGuest::SetSize(
215 const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
216 const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
217 bool old_auto_size_enabled = auto_size_enabled_;
218 gfx::Size old_max_size = max_auto_size_;
219 gfx::Size old_min_size = min_auto_size_;
220 auto_size_enabled_ = auto_size_params.enable;
221 max_auto_size_ = auto_size_params.max_size;
222 min_auto_size_ = auto_size_params.min_size;
223 if (auto_size_enabled_ && (!old_auto_size_enabled ||
224 (old_max_size != max_auto_size_) ||
225 (old_min_size != min_auto_size_))) {
226 web_contents()->GetRenderViewHost()->EnableAutoResize(
227 min_auto_size_, max_auto_size_);
228 // TODO(fsamuel): If we're changing autosize parameters, then we force
229 // the guest to completely repaint itself, because BrowserPlugin has
230 // allocated a new damage buffer and expects a full frame of pixels.
231 // Ideally, we shouldn't need to do this because we shouldn't need to
232 // allocate a new damage buffer unless |max_auto_size_| has changed.
233 // However, even in that case, layout may not change and so we may
234 // not get a full frame worth of pixels.
235 web_contents()->GetRenderViewHost()->Send(new ViewMsg_Repaint(
236 web_contents()->GetRenderViewHost()->GetRoutingID(),
237 max_auto_size_));
238 } else if (!auto_size_enabled_ && old_auto_size_enabled) {
239 web_contents()->GetRenderViewHost()->DisableAutoResize(
240 resize_guest_params.view_size);
242 Resize(embedder_web_contents_->GetRenderViewHost(), resize_guest_params);
245 void BrowserPluginGuest::UpdateDragCursor(WebKit::WebDragOperation operation) {
246 RenderViewHostImpl* embedder_render_view_host =
247 static_cast<RenderViewHostImpl*>(
248 embedder_web_contents_->GetRenderViewHost());
249 CHECK(embedder_render_view_host);
250 RenderViewHostDelegateView* view =
251 embedder_render_view_host->GetDelegate()->GetDelegateView();
252 if (view)
253 view->UpdateDragCursor(operation);
256 WebContents* BrowserPluginGuest::GetWebContents() {
257 return web_contents();
260 void BrowserPluginGuest::Terminate() {
261 RecordAction(UserMetricsAction("BrowserPlugin.Guest.Terminate"));
262 base::ProcessHandle process_handle =
263 web_contents()->GetRenderProcessHost()->GetHandle();
264 base::KillProcess(process_handle, RESULT_CODE_KILLED, false);
267 void BrowserPluginGuest::Resize(
268 RenderViewHost* embedder_rvh,
269 const BrowserPluginHostMsg_ResizeGuest_Params& params) {
270 // BrowserPlugin manages resize flow control itself and does not depend
271 // on RenderWidgetHost's mechanisms for flow control, so we reset those flags
272 // here.
273 RenderWidgetHostImpl* render_widget_host =
274 RenderWidgetHostImpl::From(web_contents()->GetRenderViewHost());
275 render_widget_host->ResetSizeAndRepaintPendingFlags();
276 if (!TransportDIB::is_valid_id(params.damage_buffer_id)) {
277 // Invalid transport dib, so just resize the WebContents.
278 if (!params.view_size.IsEmpty())
279 web_contents()->GetView()->SizeContents(params.view_size);
280 return;
282 TransportDIB* damage_buffer =
283 GetDamageBufferFromEmbedder(embedder_rvh, params);
284 SetDamageBuffer(damage_buffer,
285 #if defined(OS_WIN)
286 params.damage_buffer_size,
287 params.damage_buffer_id.handle,
288 #endif
289 params.view_size,
290 params.scale_factor);
291 web_contents()->GetView()->SizeContents(params.view_size);
294 TransportDIB* BrowserPluginGuest::GetDamageBufferFromEmbedder(
295 RenderViewHost* embedder_rvh,
296 const BrowserPluginHostMsg_ResizeGuest_Params& params) {
297 TransportDIB* damage_buffer = NULL;
298 #if defined(OS_WIN)
299 // On Windows we need to duplicate the handle from the remote process.
300 HANDLE section;
301 DuplicateHandle(embedder_rvh->GetProcess()->GetHandle(),
302 params.damage_buffer_id.handle,
303 GetCurrentProcess(),
304 &section,
305 STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
306 FALSE,
308 damage_buffer = TransportDIB::Map(section);
309 #elif defined(OS_MACOSX)
310 // On OSX, we need the handle to map the transport dib.
311 damage_buffer = TransportDIB::Map(params.damage_buffer_handle);
312 #elif defined(OS_ANDROID)
313 damage_buffer = TransportDIB::Map(params.damage_buffer_id);
314 #elif defined(OS_POSIX)
315 damage_buffer = TransportDIB::Map(params.damage_buffer_id.shmkey);
316 #endif // defined(OS_POSIX)
317 DCHECK(damage_buffer);
318 return damage_buffer;
321 void BrowserPluginGuest::SetDamageBuffer(
322 TransportDIB* damage_buffer,
323 #if defined(OS_WIN)
324 int damage_buffer_size,
325 TransportDIB::Handle remote_handle,
326 #endif
327 const gfx::Size& damage_view_size,
328 float scale_factor) {
329 // Sanity check: Verify that we've correctly shared the damage buffer memory
330 // between the embedder and browser processes.
331 DCHECK(*static_cast<unsigned int*>(damage_buffer->memory()) == 0xdeadbeef);
332 damage_buffer_.reset(damage_buffer);
333 #if defined(OS_WIN)
334 damage_buffer_size_ = damage_buffer_size;
335 remote_damage_buffer_handle_ = remote_handle;
336 #endif
337 damage_view_size_ = damage_view_size;
338 damage_buffer_scale_factor_ = scale_factor;
341 gfx::Point BrowserPluginGuest::GetScreenCoordinates(
342 const gfx::Point& relative_position) const {
343 gfx::Point screen_pos(relative_position);
344 screen_pos += guest_window_rect_.OffsetFromOrigin();
345 return screen_pos;
348 int BrowserPluginGuest::embedder_routing_id() const {
349 return embedder_web_contents_->GetRoutingID();
352 bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const {
353 return size.width() <= max_auto_size_.width() &&
354 size.height() <= max_auto_size_.height();
357 void BrowserPluginGuest::UpdateRect(
358 RenderViewHost* render_view_host,
359 const ViewHostMsg_UpdateRect_Params& params) {
360 BrowserPluginMsg_UpdateRect_Params relay_params;
361 relay_params.view_size = params.view_size;
362 relay_params.scale_factor = params.scale_factor;
363 relay_params.is_resize_ack = ViewHostMsg_UpdateRect_Flags::is_resize_ack(
364 params.flags);
366 // HW accelerated case, acknowledge resize only
367 if (!params.needs_ack) {
368 #if defined(OS_MACOSX)
369 relay_params.damage_buffer_identifier = 0;
370 #else
371 relay_params.damage_buffer_identifier = TransportDIB::DefaultHandleValue();
372 #endif
373 SendMessageToEmbedder(new BrowserPluginMsg_UpdateRect(
374 embedder_routing_id(),
375 instance_id(),
377 relay_params));
378 return;
381 // Only copy damage if the guest is in autosize mode and the guest's view size
382 // is less than the maximum size or the guest's view size is equal to the
383 // damage buffer's size and the guest's scale factor is equal to the damage
384 // buffer's scale factor.
385 // The scaling change can happen due to asynchronous updates of the DPI on a
386 // resolution change.
387 if (((auto_size_enabled_ && InAutoSizeBounds(params.view_size)) ||
388 (params.view_size.width() == damage_view_size().width() &&
389 params.view_size.height() == damage_view_size().height())) &&
390 params.scale_factor == damage_buffer_scale_factor()) {
391 TransportDIB* dib = render_view_host->GetProcess()->
392 GetTransportDIB(params.bitmap);
393 if (dib) {
394 #if defined(OS_WIN)
395 size_t guest_damage_buffer_size = params.bitmap_rect.width() *
396 params.bitmap_rect.height() * 4;
397 size_t embedder_damage_buffer_size = damage_buffer_size_;
398 #else
399 size_t guest_damage_buffer_size = dib->size();
400 size_t embedder_damage_buffer_size = damage_buffer_->size();
401 #endif
402 void* guest_memory = dib->memory();
403 void* embedder_memory = damage_buffer_->memory();
404 size_t size = std::min(guest_damage_buffer_size,
405 embedder_damage_buffer_size);
406 memcpy(embedder_memory, guest_memory, size);
409 #if defined(OS_MACOSX)
410 relay_params.damage_buffer_identifier = damage_buffer_->id();
411 #elif defined(OS_WIN)
412 // On Windows, the handle used locally differs from the handle received from
413 // the embedder process, since we duplicate the remote handle.
414 relay_params.damage_buffer_identifier = remote_damage_buffer_handle_;
415 #else
416 relay_params.damage_buffer_identifier = damage_buffer_->handle();
417 #endif
418 relay_params.bitmap_rect = params.bitmap_rect;
419 relay_params.scroll_delta = params.scroll_delta;
420 relay_params.scroll_rect = params.scroll_rect;
421 relay_params.copy_rects = params.copy_rects;
423 // We need to send the ACK to the same render_view_host that issued
424 // the UpdateRect. We keep track of this correspondence via a message_id.
425 int message_id = pending_update_counter_++;
426 pending_updates_.AddWithID(render_view_host, message_id);
428 SendMessageToEmbedder(new BrowserPluginMsg_UpdateRect(embedder_routing_id(),
429 instance_id(),
430 message_id,
431 relay_params));
434 void BrowserPluginGuest::UpdateRectACK(
435 int message_id,
436 const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
437 const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
438 RenderViewHost* render_view_host = pending_updates_.Lookup(message_id);
439 // If the guest has crashed since it sent the initial ViewHostMsg_UpdateRect
440 // then the pending_updates_ map will have been cleared.
441 if (render_view_host) {
442 pending_updates_.Remove(message_id);
443 render_view_host->Send(
444 new ViewMsg_UpdateRect_ACK(render_view_host->GetRoutingID()));
446 SetSize(auto_size_params, resize_guest_params);
449 void BrowserPluginGuest::HandleInputEvent(RenderViewHost* render_view_host,
450 const gfx::Rect& guest_window_rect,
451 const gfx::Rect& guest_screen_rect,
452 const WebKit::WebInputEvent& event) {
453 guest_window_rect_ = guest_window_rect;
454 guest_screen_rect_ = guest_screen_rect;
455 RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
456 web_contents()->GetRenderViewHost());
458 IPC::Message* message = NULL;
460 // TODO(fsamuel): What should we do for keyboard_shortcut field?
461 if (event.type == WebKit::WebInputEvent::KeyDown) {
462 CHECK_EQ(sizeof(WebKit::WebKeyboardEvent), event.size);
463 WebKit::WebKeyboardEvent key_event;
464 memcpy(&key_event, &event, event.size);
465 key_event.type = WebKit::WebInputEvent::RawKeyDown;
466 message = new ViewMsg_HandleInputEvent(routing_id(), &key_event, false);
467 } else {
468 message = new ViewMsg_HandleInputEvent(routing_id(), &event, false);
471 guest_rvh->Send(message);
472 guest_rvh->StartHangMonitorTimeout(guest_hang_timeout_);
475 void BrowserPluginGuest::HandleInputEventAck(RenderViewHost* render_view_host,
476 bool handled) {
477 RenderViewHostImpl* guest_rvh =
478 static_cast<RenderViewHostImpl*>(render_view_host);
479 guest_rvh->StopHangMonitorTimeout();
482 void BrowserPluginGuest::Stop() {
483 web_contents()->Stop();
486 void BrowserPluginGuest::Reload() {
487 // TODO(fsamuel): Don't check for repost because we don't want to show
488 // Chromium's repost warning. We might want to implement a separate API
489 // for registering a callback if a repost is about to happen.
490 web_contents()->GetController().Reload(false);
493 void BrowserPluginGuest::SetFocus(bool focused) {
494 if (focused_ == focused)
495 return;
496 focused_ = focused;
497 Send(new ViewMsg_SetFocus(routing_id(), focused));
500 void BrowserPluginGuest::ShowWidget(RenderViewHost* render_view_host,
501 int route_id,
502 const gfx::Rect& initial_pos) {
503 gfx::Rect screen_pos(initial_pos);
504 screen_pos.Offset(guest_screen_rect_.OffsetFromOrigin());
505 static_cast<WebContentsImpl*>(web_contents())->ShowCreatedWidget(route_id,
506 screen_pos);
509 #if defined(OS_MACOSX)
510 void BrowserPluginGuest::ShowPopup(RenderViewHost* render_view_host,
511 const ViewHostMsg_ShowPopup_Params& params) {
512 gfx::Rect translated_bounds(params.bounds);
513 translated_bounds.Offset(guest_window_rect_.OffsetFromOrigin());
514 BrowserPluginPopupMenuHelper popup_menu_helper(
515 embedder_web_contents_->GetRenderViewHost(), render_view_host);
516 popup_menu_helper.ShowPopupMenu(translated_bounds,
517 params.item_height,
518 params.item_font_size,
519 params.selected_item,
520 params.popup_items,
521 params.right_aligned,
522 params.allow_multiple_selection);
524 #endif
526 void BrowserPluginGuest::SetCursor(const WebCursor& cursor) {
527 SendMessageToEmbedder(new BrowserPluginMsg_SetCursor(embedder_routing_id(),
528 instance_id(),
529 cursor));
532 void BrowserPluginGuest::DidStartProvisionalLoadForFrame(
533 int64 frame_id,
534 int64 parent_frame_id,
535 bool is_main_frame,
536 const GURL& validated_url,
537 bool is_error_page,
538 RenderViewHost* render_view_host) {
539 // Inform the embedder of the loadStart.
540 SendMessageToEmbedder(
541 new BrowserPluginMsg_LoadStart(embedder_routing_id(),
542 instance_id(),
543 validated_url,
544 is_main_frame));
547 void BrowserPluginGuest::DidFailProvisionalLoad(
548 int64 frame_id,
549 bool is_main_frame,
550 const GURL& validated_url,
551 int error_code,
552 const string16& error_description,
553 RenderViewHost* render_view_host) {
554 // Translate the |error_code| into an error string.
555 std::string error_type;
556 RemoveChars(net::ErrorToString(error_code), "net::", &error_type);
557 // Inform the embedder of the loadAbort.
558 SendMessageToEmbedder(
559 new BrowserPluginMsg_LoadAbort(embedder_routing_id(),
560 instance_id(),
561 validated_url,
562 is_main_frame,
563 error_type));
566 void BrowserPluginGuest::LoadRedirect(
567 const GURL& old_url,
568 const GURL& new_url,
569 bool is_top_level) {
570 SendMessageToEmbedder(
571 new BrowserPluginMsg_LoadRedirect(embedder_routing_id(),
572 instance_id(),
573 old_url,
574 new_url,
575 is_top_level));
578 void BrowserPluginGuest::DidCommitProvisionalLoadForFrame(
579 int64 frame_id,
580 bool is_main_frame,
581 const GURL& url,
582 PageTransition transition_type,
583 RenderViewHost* render_view_host) {
584 // Inform its embedder of the updated URL.
585 BrowserPluginMsg_LoadCommit_Params params;
586 params.url = url;
587 params.is_top_level = is_main_frame;
588 params.process_id = render_view_host->GetProcess()->GetID();
589 params.current_entry_index =
590 web_contents()->GetController().GetCurrentEntryIndex();
591 params.entry_count =
592 web_contents()->GetController().GetEntryCount();
593 SendMessageToEmbedder(
594 new BrowserPluginMsg_LoadCommit(embedder_routing_id(),
595 instance_id(),
596 params));
597 RecordAction(UserMetricsAction("BrowserPlugin.Guest.DidNavigate"));
600 void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) {
601 SendMessageToEmbedder(new BrowserPluginMsg_LoadStop(embedder_routing_id(),
602 instance_id()));
605 void BrowserPluginGuest::RenderViewReady() {
606 // TODO(fsamuel): Investigate whether it's possible to update state earlier
607 // here (see http://crbug.com/158151).
608 Send(new ViewMsg_SetFocus(routing_id(), focused_));
609 bool embedder_visible =
610 embedder_web_contents_->GetBrowserPluginEmbedder()->visible();
611 SetVisibility(embedder_visible, visible());
612 if (auto_size_enabled_) {
613 web_contents()->GetRenderViewHost()->EnableAutoResize(
614 min_auto_size_, max_auto_size_);
615 } else {
616 web_contents()->GetRenderViewHost()->DisableAutoResize(damage_view_size_);
620 void BrowserPluginGuest::RenderViewGone(base::TerminationStatus status) {
621 int process_id = web_contents()->GetRenderProcessHost()->GetID();
622 SendMessageToEmbedder(new BrowserPluginMsg_GuestGone(embedder_routing_id(),
623 instance_id(),
624 process_id,
625 status));
626 IDMap<RenderViewHost>::const_iterator iter(&pending_updates_);
627 while (!iter.IsAtEnd()) {
628 pending_updates_.Remove(iter.GetCurrentKey());
629 iter.Advance();
632 switch (status) {
633 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
634 RecordAction(UserMetricsAction("BrowserPlugin.Guest.Killed"));
635 break;
636 case base::TERMINATION_STATUS_PROCESS_CRASHED:
637 RecordAction(UserMetricsAction("BrowserPlugin.Guest.Crashed"));
638 break;
639 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
640 RecordAction(UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath"));
641 break;
642 default:
643 break;
647 void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) {
648 embedder_web_contents_->Send(msg);
651 } // namespace content