browser_plugin.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/browser_plugin/browser_plugin.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_string_value_serializer.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/browser_plugin/browser_plugin_constants.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/browser_plugin/browser_plugin_messages.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/content_renderer_client.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/browser_plugin/browser_plugin_bindings.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/browser_plugin/browser_plugin_compositing_helper.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/browser_plugin/browser_plugin_manager.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/renderer/drop_data_builder.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_process_impl.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_thread_impl.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/v8_value_converter_impl.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebBindings.h"
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDOMCustomEvent.h"
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h"
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebPluginContainer.h"
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebPluginParams.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScriptSource.h"
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRect.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/keycodes/keyboard_codes.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/plugins/sad_plugin.h"
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/renderer/cursor_utils.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined (OS_WIN)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sys_info.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebCanvas;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebPluginContainer;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebPluginParams;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebPoint;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebRect;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebURL;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebVector;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static std::string GetInternalEventName(const char* event_name) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::StringPrintf("-internal-%s", event_name);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static std::string PermissionTypeToString(BrowserPluginPermissionType type) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type) {
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BrowserPluginPermissionTypeDownload:
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return browser_plugin::kPermissionTypeDownload;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginPermissionTypeGeolocation:
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return browser_plugin::kPermissionTypeGeolocation;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginPermissionTypeMedia:
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return browser_plugin::kPermissionTypeMedia;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginPermissionTypeNewWindow:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return browser_plugin::kPermissionTypeNewWindow;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginPermissionTypePointerLock:
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return browser_plugin::kPermissionTypePointerLock;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginPermissionTypeUnknown:
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::string();
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::map<WebKit::WebPluginContainer*,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 BrowserPlugin*> PluginContainerMap;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::LazyInstance<PluginContainerMap> g_plugin_container_map =
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserPlugin::BrowserPlugin(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewImpl* render_view,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebKit::WebFrame* frame,
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const WebPluginParams& params,
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int instance_id)
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : guest_instance_id_(browser_plugin::kInstanceIDNone),
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      instance_id_(instance_id),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_(render_view->AsWeakPtr()),
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_routing_id_(render_view->GetRoutingID()),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      container_(NULL),
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      damage_buffer_sequence_id_(0),
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resize_ack_received_(true),
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      last_device_scale_factor_(1.0f),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sad_guest_(NULL),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      guest_crashed_(false),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_size_ack_pending_(false),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      persist_storage_(false),
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      valid_partition_id_(true),
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content_window_routing_id_(MSG_ROUTING_NONE),
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      plugin_focused_(false),
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visible_(true),
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_changed_in_flight_(false),
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      before_first_navigation_(true),
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser_plugin_manager_(render_view->GetBrowserPluginManager()),
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      compositing_enabled_(false),
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserPlugin::~BrowserPlugin() {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the BrowserPlugin has never navigated then the browser process and
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // BrowserPluginManager don't know about it and so there is nothing to do
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // here.
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!HasGuestInstanceID())
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_,
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                               guest_instance_id_));
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*static*/
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserPlugin* BrowserPlugin::FromContainer(
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebKit::WebPluginContainer* container) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PluginContainerMap* browser_plugins = g_plugin_container_map.Pointer();
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PluginContainerMap::iterator it = browser_plugins->find(container);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return it == browser_plugins->end() ? NULL : it->second;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool handled = true;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK, OnAttachACK)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped, OnBuffersSwapped)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped,
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                OnCompositorFrameSwapped(message))
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnGuestContentWindowReady)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestResponsive, OnGuestResponsive)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestUnresponsive, OnGuestUnresponsive)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_RequestPermission, OnRequestPermission)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnShouldAcceptTouchEvents)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_UnlockMouse, OnUnlockMouse)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return handled;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const std::string& attribute_value) {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!container())
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebElement element = container()->element();
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebString web_attribute_name =
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebKit::WebString::fromUTF8(attribute_name);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasDOMAttribute(attribute_name) ||
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (std::string(element.getAttribute(web_attribute_name).utf8()) !=
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          attribute_value)) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    element.setAttribute(web_attribute_name,
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        WebKit::WebString::fromUTF8(attribute_value));
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::RemoveDOMAttribute(const std::string& attribute_name) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!container())
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  container()->element().removeAttribute(
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebKit::WebString::fromUTF8(attribute_name));
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string BrowserPlugin::GetDOMAttributeValue(
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& attribute_name) const {
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!container())
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return container()->element().getAttribute(
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebKit::WebString::fromUTF8(attribute_name)).utf8();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::HasDOMAttribute(const std::string& attribute_name) const {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!container())
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return container()->element().hasAttribute(
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebKit::WebString::fromUTF8(attribute_name));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string BrowserPlugin::GetNameAttribute() const {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetDOMAttributeValue(browser_plugin::kAttributeName);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string BrowserPlugin::GetSrcAttribute() const {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetDOMAttributeValue(browser_plugin::kAttributeSrc);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string BrowserPlugin::GetApiAttribute() const {
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return GetDOMAttributeValue(browser_plugin::kAttributeApi);
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::GetAutoSizeAttribute() const {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return HasDOMAttribute(browser_plugin::kAttributeAutoSize);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetMaxHeightAttribute() const {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int max_height;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMaxHeight),
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    &max_height);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_height;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetMaxWidthAttribute() const {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int max_width;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMaxWidth),
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    &max_width);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_width;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetMinHeightAttribute() const {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int min_height;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMinHeight),
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    &min_height);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return min_height;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetMinWidthAttribute() const {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int min_width;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringToInt(GetDOMAttributeValue(browser_plugin::kAttributeMinWidth),
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    &min_width);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return min_width;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetAdjustedMaxHeight() const {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int max_height = GetMaxHeightAttribute();
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_height ? max_height : height();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetAdjustedMaxWidth() const {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int max_width = GetMaxWidthAttribute();
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_width ? max_width : width();
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetAdjustedMinHeight() const {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int min_height = GetMinHeightAttribute();
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FrameView.cpp does not allow this value to be <= 0, so when the value is
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unset (or set to 0), we set it to the container size.
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  min_height = min_height ? min_height : height();
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For autosize, minHeight should not be bigger than maxHeight.
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return std::min(min_height, GetAdjustedMaxHeight());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BrowserPlugin::GetAdjustedMinWidth() const {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int min_width = GetMinWidthAttribute();
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FrameView.cpp does not allow this value to be <= 0, so when the value is
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unset (or set to 0), we set it to the container size.
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  min_width = min_width ? min_width : width();
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For autosize, minWidth should not be bigger than maxWidth.
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return std::min(min_width, GetAdjustedMaxWidth());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string BrowserPlugin::GetPartitionAttribute() const {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetDOMAttributeValue(browser_plugin::kAttributePartition);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::ParseNameAttribute() {
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!HasGuestInstanceID())
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BrowserPluginHostMsg_SetName(render_view_routing_id_,
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       guest_instance_id_,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       GetNameAttribute()));
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::ParseSrcAttribute(std::string* error_message) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!valid_partition_id_) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *error_message = browser_plugin::kErrorInvalidPartition;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string src = GetSrcAttribute();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (src.empty())
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we haven't created the guest yet, do so now. We will navigate it right
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after creation. If |src| is empty, we can delay the creation until we
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // actually need it.
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!HasGuestInstanceID()) {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On initial navigation, we request an instance ID from the browser
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // process. We essentially ignore all subsequent calls to SetSrcAttribute
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // until we receive an instance ID. |before_first_navigation_|
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // prevents BrowserPlugin from allocating more than one instance ID.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Upon receiving an instance ID from the browser process, we continue
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the process of navigation by populating the
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // BrowserPluginHostMsg_Attach_Params with the current state of
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // BrowserPlugin and sending a BrowserPluginHostMsg_CreateGuest to the
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // browser process in order to create a new guest.
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (before_first_navigation_) {
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser_plugin_manager()->AllocateInstanceID(this);
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      before_first_navigation_ = false;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BrowserPluginHostMsg_NavigateGuest(render_view_routing_id_,
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                             guest_instance_id_,
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             src));
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::ParseAutoSizeAttribute() {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_size_ack_pending_ = true;
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  last_view_size_ = plugin_rect_.size();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateGuestAutoSizeState(GetAutoSizeAttribute());
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::PopulateAutoSizeParameters(
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserPluginHostMsg_AutoSize_Params* params, bool current_auto_size) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params->enable = current_auto_size;
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No need to populate the params if autosize is off.
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_auto_size) {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params->max_size = gfx::Size(GetAdjustedMaxWidth(), GetAdjustedMaxHeight());
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params->min_size = gfx::Size(GetAdjustedMinWidth(), GetAdjustedMinHeight());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::UpdateGuestAutoSizeState(bool current_auto_size) {
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we haven't yet heard back from the guest about the last resize request,
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // then we don't issue another request until we do in
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // BrowserPlugin::UpdateRect.
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!HasGuestInstanceID() || !resize_ack_received_)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserPluginHostMsg_AutoSize_Params auto_size_params;
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params;
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_auto_size) {
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetDamageBufferWithSizeParams(&auto_size_params, &resize_guest_params);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetDamageBufferWithSizeParams(NULL, &resize_guest_params);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resize_ack_received_ = false;
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BrowserPluginHostMsg_SetAutoSize(render_view_routing_id_,
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           guest_instance_id_,
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           auto_size_params,
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           resize_guest_params));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::SizeChangedDueToAutoSize(const gfx::Size& old_view_size) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_changed_in_flight_ = false;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, base::Value*> props;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kOldHeight] =
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new base::FundamentalValue(old_view_size.height());
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kOldWidth] =
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new base::FundamentalValue(old_view_size.width());
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kNewHeight] =
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new base::FundamentalValue(last_view_size_.height());
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kNewWidth] =
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new base::FundamentalValue(last_view_size_.width());
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TriggerEvent(browser_plugin::kEventSizeChanged, &props);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::UsesDamageBuffer(
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BrowserPluginMsg_UpdateRect_Params& params) {
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return params.damage_buffer_sequence_id != 0 || params.needs_ack;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::UsesPendingDamageBuffer(
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BrowserPluginMsg_UpdateRect_Params& params) {
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!pending_damage_buffer_)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return damage_buffer_sequence_id_ == params.damage_buffer_sequence_id;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::Attach(int guest_instance_id) {
390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(guest_instance_id != browser_plugin::kInstanceIDNone);
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  before_first_navigation_ = false;
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  guest_instance_id_ = guest_instance_id;
393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::map<std::string, base::Value*> props;
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  props[browser_plugin::kWindowID] =
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new base::FundamentalValue(guest_instance_id);
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TriggerEvent(browser_plugin::kEventInternalAttached, &props);
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BrowserPluginHostMsg_Attach_Params attach_params;
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  attach_params.browser_plugin_instance_id = instance_id_;
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  attach_params.focused = ShouldGuestBeFocused();
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  attach_params.visible = visible_;
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  attach_params.name = GetNameAttribute();
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  attach_params.storage_partition_id = storage_partition_id_;
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  attach_params.persist_storage = persist_storage_;
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  attach_params.src = GetSrcAttribute();
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetDamageBufferWithSizeParams(&attach_params.auto_size_params,
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                &attach_params.resize_guest_params);
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(fsamuel): These params should be populated by a new internal attach
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // API in the near future. This will permit shims that use BrowserPlugin to
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // propagate shim-specific data on attachment that will be handled by the
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // content embedder.
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue extra_params;
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  extra_params.SetString(browser_plugin::kAttributeApi, GetApiAttribute());
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new BrowserPluginHostMsg_Attach(render_view_routing_id_,
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      guest_instance_id_, attach_params,
420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      extra_params));
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPlugin::DidCommitCompositorFrame() {
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (compositing_helper_.get())
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    compositing_helper_->DidCommitCompositorFrame();
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnAdvanceFocus(int guest_instance_id, bool reverse) {
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(render_view_.get());
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  render_view_->GetWebView()->advanceFocus(reverse);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPlugin::OnAttachACK(
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int guest_instance_id,
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const BrowserPluginMsg_Attach_ACK_Params& params) {
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Update BrowserPlugin attributes to match the state of the guest.
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!params.name.empty())
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    OnUpdatedName(guest_instance_id, params.name);
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!params.storage_partition_id.empty()) {
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string partition_name =
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (params.persist_storage ? browser_plugin::kPersistPrefix : "") +
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            params.storage_partition_id;
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UpdateDOMAttribute(browser_plugin::kAttributePartition, partition_name);
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid BrowserPlugin::OnBuffersSwapped(
448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int guest_instance_id,
449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const BrowserPluginMsg_BuffersSwapped_Params& params) {
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(guest_instance_id == guest_instance_id_);
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableCompositing(true);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  compositing_helper_->OnBuffersSwapped(params.size,
454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        params.mailbox_name,
455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        params.route_id,
456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        params.host_id,
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        GetDeviceScaleFactor());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPlugin::OnCompositorFrameSwapped(const IPC::Message& message) {
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserPluginMsg_CompositorFrameSwapped::Param param;
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!BrowserPluginMsg_CompositorFrameSwapped::Read(&message, &param))
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  param.b.AssignTo(frame.get());
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EnableCompositing(true);
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositing_helper_->OnCompositorFrameSwapped(frame.Pass(),
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                param.c /* route_id */,
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                param.d /* host_id */);
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnGuestContentWindowReady(int guest_instance_id,
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              int content_window_routing_id) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content_window_routing_id != MSG_ROUTING_NONE);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content_window_routing_id_ = content_window_routing_id;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid BrowserPlugin::OnGuestGone(int guest_instance_id) {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  guest_crashed_ = true;
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Queue up showing the sad graphic to give content embedders an opportunity
4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // to fire their listeners and potentially overlay the webview with custom
4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // behavior. If the BrowserPlugin is destroyed in the meantime, then the
4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // task will not be executed.
4867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->PostTask(
4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE,
4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&BrowserPlugin::ShowSadGraphic,
4897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 weak_ptr_factory_.GetWeakPtr()));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnGuestResponsive(int guest_instance_id, int process_id) {
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, base::Value*> props;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kProcessId] = new base::FundamentalValue(process_id);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TriggerEvent(browser_plugin::kEventResponsive, &props);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnGuestUnresponsive(int guest_instance_id, int process_id) {
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, base::Value*> props;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kProcessId] = new base::FundamentalValue(process_id);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TriggerEvent(browser_plugin::kEventUnresponsive, &props);
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::OnRequestPermission(
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int guest_instance_id,
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserPluginPermissionType permission_type,
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int request_id,
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue& request_info) {
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The New Window API is very similiar to the permission API in structure,
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // but exposes a slightly different interface to the developer and so we put
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it in a separate event.
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* event_name =
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (permission_type == BrowserPluginPermissionTypeNewWindow) ?
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          browser_plugin::kEventNewWindow :
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              browser_plugin::kEventRequestPermission;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPermissionRequestToMap(request_id, permission_type);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, base::Value*> props;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kPermission] =
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Value::CreateStringValue(PermissionTypeToString(permission_type));
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  props[browser_plugin::kRequestId] =
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Value::CreateIntegerValue(request_id);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fill in the info provided by the browser.
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (DictionaryValue::Iterator iter(request_info); !iter.IsAtEnd();
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           iter.Advance()) {
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    props[iter.key()] = iter.value().DeepCopy();
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TriggerEvent(event_name, &props);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnSetCursor(int guest_instance_id,
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                const WebCursor& cursor) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cursor_ = cursor;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnShouldAcceptTouchEvents(int guest_instance_id,
539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                              bool accept) {
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (container()) {
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    container()->requestTouchEventType(accept ?
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        WebKit::WebPluginContainer::TouchEventRequestTypeRaw :
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        WebKit::WebPluginContainer::TouchEventRequestTypeNone);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnUnlockMouse(int guest_instance_id) {
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  render_view_->mouse_lock_dispatcher()->UnlockMouse(this);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BrowserPlugin::OnUpdatedName(int guest_instance_id,
552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  const std::string& name) {
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDOMAttribute(browser_plugin::kAttributeName, name);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::AddPermissionRequestToMap(int request_id,
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserPluginPermissionType type) {
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!pending_permission_requests_.count(request_id));
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_permission_requests_.insert(std::make_pair(request_id, type));
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::OnUpdateRect(
563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int guest_instance_id,
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BrowserPluginMsg_UpdateRect_Params& params) {
5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If the guest has updated pixels then it is no longer crashed.
5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  guest_crashed_ = false;
5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool use_new_damage_buffer = !backing_store_;
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserPluginHostMsg_AutoSize_Params auto_size_params;
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params;
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we have a pending damage buffer, and the guest has begun to use the
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // damage buffer then we know the guest will no longer use the current
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // damage buffer. At this point, we drop the current damage buffer, and
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // mark the pending damage buffer as the current damage buffer.
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (UsesPendingDamageBuffer(params)) {
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SwapDamageBuffers();
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    use_new_damage_buffer = true;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool auto_size = GetAutoSizeAttribute();
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We receive a resize ACK in regular mode, but not in autosize.
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In SW, |resize_ack_received_| is reset in SwapDamageBuffers().
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In HW mode, we need to do it here so we can continue sending
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // resize messages when needed.
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params.is_resize_ack ||
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (!params.needs_ack && (auto_size || auto_size_ack_pending_)))
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resize_ack_received_ = true;
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_size_ack_pending_ = false;
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if ((!auto_size && (width() != params.view_size.width() ||
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      height() != params.view_size.height())) ||
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      (auto_size && (!InAutoSizeBounds(params.view_size))) ||
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetDeviceScaleFactor() != params.scale_factor) {
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We are HW accelerated, render widget does not expect an ack,
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // but we still need to update the size.
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!params.needs_ack) {
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateGuestAutoSizeState(auto_size);
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!resize_ack_received_) {
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The guest has not yet responded to the last resize request, and
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // so we don't want to do anything at this point other than ACK the guest.
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (auto_size)
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        PopulateAutoSizeParameters(&auto_size_params, auto_size);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // If we have no pending damage buffer, then the guest has not caught up
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // with the BrowserPlugin container. We now tell the guest about the new
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // container size.
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (auto_size) {
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetDamageBufferWithSizeParams(&auto_size_params,
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      &resize_guest_params);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetDamageBufferWithSizeParams(NULL, &resize_guest_params);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateRect_ACK(
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        render_view_routing_id_,
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        guest_instance_id_,
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        auto_size_params,
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resize_guest_params));
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_size && (params.view_size != last_view_size_)) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (backing_store_)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backing_store_->Clear(SK_ColorWHITE);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size old_view_size = last_view_size_;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_view_size_ = params.view_size;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Schedule a SizeChanged instead of calling it directly to ensure that
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the backing store has been updated before the developer attempts to
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // resize to avoid flicker. |size_changed_in_flight_| acts as a form of
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // flow control for SizeChanged events. If the guest's view size is changing
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // rapidly before a SizeChanged event fires, then we avoid scheduling
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // another SizeChanged event. SizeChanged reads the new size from
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |last_view_size_| so we can be sure that it always fires an event
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // with the last seen view size.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (container_ && !size_changed_in_flight_) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_changed_in_flight_ = true;
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop::current()->PostTask(
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&BrowserPlugin::SizeChangedDueToAutoSize,
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this),
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     old_view_size));
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No more work to do since the guest is no longer using a damage buffer.
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!UsesDamageBuffer(params))
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we are seeing damage buffers, HW compositing should be turned off.
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableCompositing(false);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we are now using a new damage buffer, then that means that the guest
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // has updated its size state in response to a resize request. We change
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the backing store's size to accomodate the new damage buffer size.
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_new_damage_buffer) {
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int backing_store_width = auto_size ? GetAdjustedMaxWidth() : width();
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int backing_store_height = auto_size ? GetAdjustedMaxHeight(): height();
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backing_store_.reset(
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new BrowserPluginBackingStore(
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            gfx::Size(backing_store_width, backing_store_height),
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            params.scale_factor));
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If we just transitioned from the compositing path to the software path
669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // then we might not yet have a damage buffer.
670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (current_damage_buffer_) {
671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Update the backing store.
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!params.scroll_rect.IsEmpty()) {
673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      backing_store_->ScrollBackingStore(params.scroll_delta,
674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         params.scroll_rect,
675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         params.view_size);
676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    backing_store_->PaintToBackingStore(params.bitmap_rect,
678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        params.copy_rects,
679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        current_damage_buffer_->memory());
680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Invalidate the container.
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // If the BrowserPlugin is scheduled to be deleted, then container_ will be
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // NULL so we shouldn't attempt to access it.
683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (container_)
684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      container_->invalidate();
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_size)
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PopulateAutoSizeParameters(&auto_size_params, auto_size);
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateRect_ACK(
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_routing_id_,
691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_,
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_size_params,
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resize_guest_params));
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::ParseSizeContraintsChanged() {
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool auto_size = GetAutoSizeAttribute();
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_size)
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateGuestAutoSizeState(true);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::InAutoSizeBounds(const gfx::Size& size) const {
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return size.width() <= GetAdjustedMaxWidth() &&
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size.height() <= GetAdjustedMaxHeight();
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NPObject* BrowserPlugin::GetContentWindow() const {
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (content_window_routing_id_ == MSG_ROUTING_NONE)
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID(
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content_window_routing_id_);
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!guest_render_view)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame();
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return guest_frame->windowObject();
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::AttachWindowTo(const WebKit::WebNode& node, int window_id) {
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (node.isNull())
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!node.isElementNode())
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebElement shim_element = node.toConst<WebKit::WebElement>();
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The shim containing the BrowserPlugin must be attached to a document.
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shim_element.document().isNull())
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebNode shadow_root = shim_element.shadowRoot();
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shadow_root.isNull() || !shadow_root.hasChildNodes())
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebNode plugin_element = shadow_root.firstChild();
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebPluginContainer* plugin_container =
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      plugin_element.pluginContainer();
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!plugin_container)
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserPlugin* browser_plugin =
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserPlugin::FromContainer(plugin_container);
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!browser_plugin)
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If the BrowserPlugin has already begun to navigate then we shouldn't allow
747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // attaching a different guest.
748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  //
749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Navigation happens in two stages.
750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 1. BrowserPlugin requests an instance ID from the browser process.
751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 2. The browser process returns an instance ID and BrowserPlugin is
752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  //    "Attach"ed to that instance ID.
753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If the instance ID is new then a new guest will be created.
754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If the instance ID corresponds to an unattached guest then BrowserPlugin
755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // is attached to that guest.
756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  //
757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Between step 1, and step 2, BrowserPlugin::AttachWindowTo may be called.
758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The check below ensures that BrowserPlugin:Attach does not get called with
759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // a different instance ID after step 1 has happened.
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(fsamuel): We may wish to support reattaching guests in the future:
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // http://crbug.com/156219.
762868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (browser_plugin->HasNavigated())
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  browser_plugin->Attach(window_id);
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
769868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool BrowserPlugin::HasNavigated() const {
770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return !before_first_navigation_;
771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool BrowserPlugin::HasGuestInstanceID() const {
774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return guest_instance_id_ != browser_plugin::kInstanceIDNone;
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::ParsePartitionAttribute(std::string* error_message) {
778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (HasNavigated()) {
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *error_message = browser_plugin::kErrorAlreadyNavigated;
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string input = GetPartitionAttribute();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since the "persist:" prefix is in ASCII, StartsWith will work fine on
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // remove the prefix without splicing in the middle of a multi-byte codepoint.
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We can use the rest of the string as UTF-8 encoded one.
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (StartsWithASCII(input, browser_plugin::kPersistPrefix, true)) {
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t index = input.find(":");
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(index != std::string::npos);
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // It is safe to do index + 1, since we tested for the full prefix above.
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    input = input.substr(index + 1);
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (input.empty()) {
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      valid_partition_id_ = false;
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *error_message = browser_plugin::kErrorInvalidPartition;
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    persist_storage_ = true;
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    persist_storage_ = false;
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  valid_partition_id_ = true;
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  storage_partition_id_ = input;
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::CanRemovePartitionAttribute(std::string* error_message) {
810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (HasGuestInstanceID())
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *error_message = browser_plugin::kErrorCannotRemovePartition;
812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return !HasGuestInstanceID();
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid BrowserPlugin::ShowSadGraphic() {
8167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // We won't paint the contents of the current backing store again so we might
8177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // as well toss it out and save memory.
8187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  backing_store_.reset();
8197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If the BrowserPlugin is scheduled to be deleted, then container_ will be
8207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // NULL so we shouldn't attempt to access it.
8217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (container_)
8227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    container_->invalidate();
8237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Turn off compositing so we can display the sad graphic.
8247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EnableCompositing(false);
8257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
8267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::ParseAttributes() {
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(mthiesse): Handle errors here?
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string error;
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ParsePartitionAttribute(&error);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Parse the 'src' attribute last, as it will set the has_navigated_ flag to
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // true, which prevents changing the 'partition' attribute.
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ParseSrcAttribute(&error);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)float BrowserPlugin::GetDeviceScaleFactor() const {
838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!render_view_.get())
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 1.0f;
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return render_view_->GetWebView()->deviceScaleFactor();
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserPlugin::UpdateDeviceScaleFactor(float device_scale_factor) {
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (last_device_scale_factor_ == device_scale_factor || !resize_ack_received_)
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserPluginHostMsg_ResizeGuest_Params params;
84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PopulateResizeGuestParameters(&params, plugin_rect());
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      render_view_routing_id_,
851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_,
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      params));
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::TriggerEvent(const std::string& event_name,
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::map<std::string, base::Value*>* props) {
857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!container())
858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  WebKit::WebFrame* frame = container()->element().document().frame();
861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!frame)
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v8::HandleScope handle_scope;
865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Local<v8::Context> context = frame->mainWorldScriptContext();
866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Context::Scope context_scope(context);
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string json_string;
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (props) {
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue dict;
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (std::map<std::string, base::Value*>::iterator iter = props->begin(),
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             end = props->end(); iter != end; ++iter) {
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.Set(iter->first, iter->second);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    JSONStringValueSerializer serializer(&json_string);
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!serializer.Serialize(dict))
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebDOMEvent dom_event = frame->document().createEvent("CustomEvent");
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebDOMCustomEvent event = dom_event.to<WebKit::WebDOMCustomEvent>();
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The events triggered directly from the plugin <object> are internal events
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // whose implementation details can (and likely will) change over time. The
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // more appropriate (and stable) event to the consumers as part of the API.
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event.initCustomEvent(
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())),
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      false, false,
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebKit::WebSerializedScriptValue::serialize(
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          v8::String::New(json_string.c_str(), json_string.size())));
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  container()->element().dispatchEvent(event);
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid BrowserPlugin::OnTrackedObjectGarbageCollected(int id) {
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove from alive objects.
8987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::map<int, TrackedV8ObjectID*>::iterator iter =
8997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tracked_v8_objects_.find(id);
9007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (iter != tracked_v8_objects_.end())
9017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    tracked_v8_objects_.erase(iter);
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::map<std::string, base::Value*> props;
9047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  props[browser_plugin::kId] = new base::FundamentalValue(id);
9057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TriggerEvent(browser_plugin::kEventInternalTrackedObjectGone, &props);
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid BrowserPlugin::TrackObjectLifetime(const NPVariant* request, int id) {
9097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // An object of a given ID can only be tracked once.
9107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (tracked_v8_objects_.find(id) != tracked_v8_objects_.end())
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  v8::Isolate* isolate = v8::Isolate::GetCurrent();
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v8::Persistent<v8::Value> weak_request(
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      isolate, WebKit::WebBindings::toV8Value(request));
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TrackedV8ObjectID* new_item =
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new std::pair<int, base::WeakPtr<BrowserPlugin> >(
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          id, weak_ptr_factory_.GetWeakPtr());
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::pair<std::map<int, TrackedV8ObjectID*>::iterator, bool>
9227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      result = tracked_v8_objects_.insert(
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          std::make_pair(id, new_item));
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(result.second);  // Inserted in the map.
9257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TrackedV8ObjectID* request_item = result.first->second;
9267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  weak_request.MakeWeak(static_cast<void*>(request_item),
9277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                        WeakCallbackForTrackedObject);
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
9317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid BrowserPlugin::WeakCallbackForTrackedObject(
932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::Isolate* isolate, v8::Persistent<v8::Value>* object, void* param) {
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TrackedV8ObjectID* item_ptr = static_cast<TrackedV8ObjectID*>(param);
9357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int object_id = item_ptr->first;
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtr<BrowserPlugin> plugin = item_ptr->second;
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete item_ptr;
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  object->Dispose();
940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (plugin.get()) {
9417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Asynchronously remove item from |tracked_v8_objects_|.
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Note that we are using weak pointer for the following PostTask, so we
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // don't need to worry about BrowserPlugin going away.
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
9467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(&BrowserPlugin::OnTrackedObjectGarbageCollected,
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   plugin,
9487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   object_id));
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::UpdateGuestFocusState() {
953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!HasGuestInstanceID())
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_be_focused = ShouldGuestBeFocused();
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetFocus(
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_routing_id_,
958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_,
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      should_be_focused));
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserPlugin::ShouldGuestBeFocused() const {
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool embedder_focused = false;
964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (render_view_.get())
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    embedder_focused = render_view_->has_focus();
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return plugin_focused_ && embedder_focused;
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebKit::WebPluginContainer* BrowserPlugin::container() const {
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return container_;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::RespondPermission(
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserPluginPermissionType permission_type, int request_id, bool allow) {
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (permission_type == BrowserPluginPermissionTypePointerLock)
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RespondPermissionPointerLock(allow);
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser_plugin_manager()->Send(
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new BrowserPluginHostMsg_RespondPermission(
9807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            render_view_routing_id_, guest_instance_id_, permission_type,
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            request_id, allow));
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::RespondPermissionPointerLock(bool allow) {
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (allow)
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    render_view_->mouse_lock_dispatcher()->LockMouse(this);
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnLockMouseACK(false);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::RespondPermissionIfRequestIsPending(
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int request_id, bool allow) {
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PendingPermissionRequests::iterator iter =
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_permission_requests_.find(request_id);
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == pending_permission_requests_.end())
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserPluginPermissionType permission_type = iter->second;
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_permission_requests_.erase(iter);
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RespondPermission(permission_type, request_id, allow);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::OnEmbedderDecidedPermission(int request_id, bool allow) {
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RespondPermissionIfRequestIsPending(request_id, allow);
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserPlugin::initialize(WebPluginContainer* container) {
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!container)
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetContentClient()->renderer()->AllowBrowserPlugin(container))
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
101490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Tell |container| to allow this plugin to use script objects.
101590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  npp_.reset(new NPP_t);
101690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  container->allowScriptObjects();
101790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bindings_.reset(new BrowserPluginBindings(this));
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_ = container;
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  container_->setWantsWheelEvents(true);
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ParseAttributes();
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_plugin_container_map.Get().insert(std::make_pair(container_, this));
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::EnableCompositing(bool enable) {
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (compositing_enabled_ == enable)
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  compositing_enabled_ = enable;
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enable) {
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No need to keep the backing store and damage buffer around if we're now
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // compositing.
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    backing_store_.reset();
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_damage_buffer_.reset();
1036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!compositing_helper_.get()) {
1037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      compositing_helper_ =
1038868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          new BrowserPluginCompositingHelper(container_,
1039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                             browser_plugin_manager(),
1040868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                             guest_instance_id_,
1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                             render_view_routing_id_);
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We're switching back to the software path. We create a new damage
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // buffer that can accommodate the current size of the container.
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserPluginHostMsg_ResizeGuest_Params params;
104790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PopulateResizeGuestParameters(&params, plugin_rect());
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Request a full repaint from the guest even if its size is not actually
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // changing.
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.repaint = true;
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resize_ack_received_ = false;
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        render_view_routing_id_,
1054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        guest_instance_id_,
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params));
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  compositing_helper_->EnableCompositing(enable);
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::destroy() {
106190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If the plugin was initialized then it has a valid |npp_| identifier, and
106290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // the |container_| must clear references to the plugin's script objects.
106390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!npp_ || container_);
106490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (container_)
106590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    container_->clearScriptObjects();
106690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The BrowserPlugin's WebPluginContainer is deleted immediately after this
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call returns, so let's not keep a reference to it around.
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_plugin_container_map.Get().erase(container_);
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_ = NULL;
1071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (compositing_helper_.get())
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    compositing_helper_->OnContainerDestroy();
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Will be a no-op if the mouse is not currently locked.
1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (render_view_.get())
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObject* BrowserPlugin::scriptableObject() {
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!bindings_)
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NPObject* browser_plugin_np_object(bindings_->np_object());
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The object is expected to be retained before it is returned.
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::WebBindings::retainObject(browser_plugin_np_object);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser_plugin_np_object;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NPP BrowserPlugin::pluginNPP() {
109090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return npp_.get();
109190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
109290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserPlugin::supportsKeyboardFocus() const {
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1097868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool BrowserPlugin::supportsEditCommands() const {
1098868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
1099868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserPlugin::canProcessDrag() const {
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::paint(WebCanvas* canvas, const WebRect& rect) {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (guest_crashed_) {
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sad_guest_)  // Lazily initialize bitmap.
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sad_guest_ = content::GetContentClient()->renderer()->
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetSadWebViewBitmap();
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // content_shell does not have the sad plugin bitmap, so we'll paint black
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // instead to make it clear that something went wrong.
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sad_guest_) {
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webkit::PaintSadPlugin(canvas, plugin_rect_, *sad_guest_);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoCanvasRestore auto_restore(canvas, true);
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->translate(plugin_rect_.x(), plugin_rect_.y());
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect image_data_rect = SkRect::MakeXYWH(
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(0),
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(0),
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(plugin_rect_.width()),
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(plugin_rect_.height()));
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->clipRect(image_data_rect);
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Paint black or white in case we have nothing in our backing store or we
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // need to show a gutter.
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(guest_crashed_ ? SK_ColorBLACK : SK_ColorWHITE);
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRect(image_data_rect, paint);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stay a solid color if we have never set a non-empty src, or we don't have a
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backing store.
1133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!backing_store_.get() || !HasGuestInstanceID())
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float inverse_scale_factor =  1.0f / backing_store_->GetScaleFactor();
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->scale(inverse_scale_factor, inverse_scale_factor);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawBitmap(backing_store_->GetBitmap(), 0, 0);
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::InBounds(const gfx::Point& position) const {
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note that even for plugins that are rotated using rotate transformations,
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we use the the |plugin_rect_| provided by updateGeometry, which means we
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will be off if |position| is within the plugin rect but does not fall
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // within the actual plugin boundary. Not supporting such edge case is OK
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // since this function should not be used for making security-sensitive
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // decisions.
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This also does not take overlapping plugins into account.
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = position.x() >= plugin_rect_.x() &&
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      position.x() < plugin_rect_.x() + plugin_rect_.width() &&
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      position.y() >= plugin_rect_.y() &&
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      position.y() < plugin_rect_.y() + plugin_rect_.height();
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Point BrowserPlugin::ToLocalCoordinates(const gfx::Point& point) const {
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (container_)
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return container_->windowToLocalPoint(WebKit::WebPoint(point));
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Point(point.x() - plugin_rect_.x(), point.y() - plugin_rect_.y());
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::ShouldForwardToBrowserPlugin(
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const IPC::Message& message) {
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (message.type()) {
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_AdvanceFocus::ID:
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BrowserPluginMsg_Attach_ACK::ID:
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_BuffersSwapped::ID:
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case BrowserPluginMsg_CompositorFrameSwapped::ID:
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_GuestContentWindowReady::ID:
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_GuestGone::ID:
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_GuestResponsive::ID:
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_GuestUnresponsive::ID:
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_RequestPermission::ID:
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_SetCursor::ID:
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_ShouldAcceptTouchEvents::ID:
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_UnlockMouse::ID:
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_UpdatedName::ID:
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case BrowserPluginMsg_UpdateRect::ID:
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::updateGeometry(
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebRect& window_rect,
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebRect& clip_rect,
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebVector<WebRect>& cut_outs_rects,
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_visible) {
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int old_width = width();
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int old_height = height();
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_rect_ = window_rect;
1194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!HasGuestInstanceID())
119590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
119690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In AutoSize mode, guests don't care when the BrowserPlugin container is
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // resized. If |!resize_ack_received_|, then we are still waiting on a
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // previous resize to be ACK'ed and so we don't issue additional resizes
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // until the previous one is ACK'ed.
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(mthiesse): Assess the performance of calling GetAutoSizeAttribute() on
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // resize.
120390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!resize_ack_received_ ||
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (old_width == window_rect.width && old_height == window_rect.height) ||
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetAutoSizeAttribute()) {
120690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Let the browser know about the updated view rect.
120790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry(
1208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        render_view_routing_id_, guest_instance_id_, plugin_rect_));
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserPluginHostMsg_ResizeGuest_Params params;
121390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PopulateResizeGuestParameters(&params, plugin_rect());
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resize_ack_received_ = false;
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_view_routing_id_,
1217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_,
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params));
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::SwapDamageBuffers() {
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_damage_buffer_.reset(pending_damage_buffer_.release());
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resize_ack_received_ = true;
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::PopulateResizeGuestParameters(
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserPluginHostMsg_ResizeGuest_Params* params,
122890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const gfx::Rect& view_rect) {
122990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params->view_rect = view_rect;
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params->scale_factor = GetDeviceScaleFactor();
1231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (last_device_scale_factor_ != params->scale_factor){
1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    params->repaint = true;
1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_scale_factor_ = params->scale_factor;
1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In HW compositing mode, we do not need a damage buffer.
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (compositing_enabled_)
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
124090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const size_t stride = skia::PlatformCanvasStrideForWidth(view_rect.width());
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the size of the damage buffer is at least four bytes so that we
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can fit in a magic word to verify that the memory is shared correctly.
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t size =
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::max(sizeof(unsigned int),
124590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               static_cast<size_t>(view_rect.height() *
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   stride *
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GetDeviceScaleFactor() *
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GetDeviceScaleFactor()));
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params->damage_buffer_size = size;
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_damage_buffer_.reset(
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateDamageBuffer(size, &params->damage_buffer_handle));
1253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!pending_damage_buffer_)
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params->damage_buffer_sequence_id = ++damage_buffer_sequence_id_;
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::GetDamageBufferWithSizeParams(
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserPluginHostMsg_AutoSize_Params* auto_size_params,
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserPluginHostMsg_ResizeGuest_Params* resize_guest_params) {
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_size_params)
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PopulateAutoSizeParameters(auto_size_params, GetAutoSizeAttribute());
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size view_size = (auto_size_params && auto_size_params->enable) ?
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_size_params->max_size : gfx::Size(width(), height());
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (view_size.IsEmpty())
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resize_ack_received_ = false;
126890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::Rect view_rect = gfx::Rect(plugin_rect_.origin(), view_size);
126990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PopulateResizeGuestParameters(resize_guest_params, view_rect);
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_POSIX)
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemory* BrowserPlugin::CreateDamageBuffer(
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const size_t size,
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::SharedMemoryHandle* damage_buffer_handle) {
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_buf(
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          size).release());
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (shared_buf) {
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (shared_buf->Map(size)) {
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Insert the magic word.
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *static_cast<unsigned int*>(shared_buf->memory()) = 0xdeadbeef;
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shared_buf->ShareToProcess(base::GetCurrentProcessHandle(),
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 damage_buffer_handle);
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return shared_buf.release();
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_WIN)
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemory* BrowserPlugin::CreateDamageBuffer(
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const size_t size,
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::SharedMemoryHandle* damage_buffer_handle) {
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_buf(new base::SharedMemory());
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!shared_buf->CreateAndMapAnonymous(size)) {
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED() << "Buffer allocation failed";
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Insert the magic word.
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *static_cast<unsigned int*>(shared_buf->memory()) = 0xdeadbeef;
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shared_buf->ShareToProcess(base::GetCurrentProcessHandle(),
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 damage_buffer_handle))
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return shared_buf.release();
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::updateFocus(bool focused) {
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (plugin_focused_ == focused)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool old_guest_focus_state = ShouldGuestBeFocused();
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_focused_ = focused;
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ShouldGuestBeFocused() != old_guest_focus_state)
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateGuestFocusState();
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::updateVisibility(bool visible) {
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (visible_ == visible)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visible_ = visible;
1329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!HasGuestInstanceID())
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (compositing_helper_.get())
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    compositing_helper_->UpdateVisibility(visible);
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetVisibility(
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_routing_id_,
1337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_,
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visible));
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserPlugin::acceptsInputEvents() {
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserPlugin::handleInputEvent(const WebKit::WebInputEvent& event,
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     WebKit::WebCursorInfo& cursor_info) {
13477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (guest_crashed_ || !HasGuestInstanceID())
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (event.type == WebKit::WebInputEvent::ContextMenu)
13517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return true;
13527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const WebKit::WebInputEvent* modified_event = &event;
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebKit::WebTouchEvent> touch_event;
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebKit gives BrowserPlugin a list of touches that are down, but the browser
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // process expects a list of all touches. We modify the TouchEnd event here to
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // match these expectations.
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (event.type == WebKit::WebInputEvent::TouchEnd) {
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const WebKit::WebTouchEvent* orig_touch_event =
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        static_cast<const WebKit::WebTouchEvent*>(&event);
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    touch_event.reset(new WebKit::WebTouchEvent());
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(touch_event.get(), orig_touch_event, sizeof(WebKit::WebTouchEvent));
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (touch_event->changedTouchesLength > 0) {
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(&touch_event->touches[touch_event->touchesLength],
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             &touch_event->changedTouches,
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            touch_event->changedTouchesLength * sizeof(WebKit::WebTouchPoint));
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    touch_event->touchesLength += touch_event->changedTouchesLength;
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    modified_event = touch_event.get();
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (WebKit::WebInputEvent::isKeyboardEventType(event.type) &&
1373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      !edit_commands_.empty()) {
1374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    browser_plugin_manager()->Send(
1375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent(
1376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            render_view_routing_id_,
1377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            instance_id_,
1378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            edit_commands_));
1379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    edit_commands_.clear();
1380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_,
1384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                guest_instance_id_,
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                plugin_rect_,
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                modified_event));
138790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  webkit_glue::GetWebKitCursorInfo(cursor_, &cursor_info);
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserPlugin::handleDragStatusUpdate(WebKit::WebDragStatus drag_status,
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const WebKit::WebDragData& drag_data,
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           WebKit::WebDragOperationsMask mask,
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const WebKit::WebPoint& position,
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const WebKit::WebPoint& screen) {
1396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (guest_crashed_ || !HasGuestInstanceID())
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BrowserPluginHostMsg_DragStatusUpdate(
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        render_view_routing_id_,
1401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        guest_instance_id_,
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        drag_status,
1403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        DropDataBuilder::Build(drag_data),
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mask,
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        position));
1406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::didReceiveResponse(
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebKit::WebURLResponse& response) {
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::didReceiveData(const char* data, int data_length) {
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::didFinishLoading() {
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::didFailLoading(const WebKit::WebURLError& error) {
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::didFinishLoadingFrameRequest(const WebKit::WebURL& url,
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 void* notify_data) {
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserPlugin::didFailLoadingFrameRequest(
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebKit::WebURL& url,
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* notify_data,
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebKit::WebURLError& error) {
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool BrowserPlugin::executeEditCommand(const WebKit::WebString& name) {
1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_ExecuteEditCommand(
1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      render_view_routing_id_,
1435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_,
1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      name.utf8()));
1437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // BrowserPlugin swallows edit commands.
1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool BrowserPlugin::executeEditCommand(const WebKit::WebString& name,
1443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       const WebKit::WebString& value) {
1444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  edit_commands_.push_back(EditCommand(name.utf8(), value.utf8()));
1445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // BrowserPlugin swallows edit commands.
1446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
1447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::OnLockMouseACK(bool succeeded) {
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_LockMouse_ACK(
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_view_routing_id_,
1452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_,
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      succeeded));
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserPlugin::OnMouseLockLost() {
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(new BrowserPluginHostMsg_UnlockMouse_ACK(
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_view_routing_id_,
1459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      guest_instance_id_));
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserPlugin::HandleMouseLockedInputEvent(
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const WebKit::WebMouseEvent& event) {
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_plugin_manager()->Send(
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_,
1466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                guest_instance_id_,
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                plugin_rect_,
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                &event));
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1473