Home | History | Annotate | Download | only in browser_plugin
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
      6 
      7 #include "base/values.h"
      8 #include "content/browser/browser_plugin/browser_plugin_guest.h"
      9 #include "content/browser/renderer_host/render_view_host_impl.h"
     10 #include "content/browser/web_contents/web_contents_impl.h"
     11 #include "content/common/browser_plugin/browser_plugin_constants.h"
     12 #include "content/common/browser_plugin/browser_plugin_messages.h"
     13 #include "content/common/drag_messages.h"
     14 #include "content/common/gpu/gpu_messages.h"
     15 #include "content/public/browser/browser_context.h"
     16 #include "content/public/browser/browser_plugin_guest_manager.h"
     17 #include "content/public/browser/content_browser_client.h"
     18 #include "content/public/browser/native_web_keyboard_event.h"
     19 #include "content/public/browser/render_view_host.h"
     20 #include "content/public/browser/user_metrics.h"
     21 #include "content/public/common/content_switches.h"
     22 #include "content/public/common/result_codes.h"
     23 #include "content/public/common/url_constants.h"
     24 #include "net/base/escape.h"
     25 #include "ui/events/keycodes/keyboard_codes.h"
     26 
     27 namespace content {
     28 
     29 BrowserPluginEmbedder::BrowserPluginEmbedder(WebContentsImpl* web_contents)
     30     : WebContentsObserver(web_contents),
     31       weak_ptr_factory_(this) {
     32 }
     33 
     34 BrowserPluginEmbedder::~BrowserPluginEmbedder() {
     35 }
     36 
     37 // static
     38 BrowserPluginEmbedder* BrowserPluginEmbedder::Create(
     39     WebContentsImpl* web_contents) {
     40   return new BrowserPluginEmbedder(web_contents);
     41 }
     42 
     43 void BrowserPluginEmbedder::DragEnteredGuest(BrowserPluginGuest* guest) {
     44   guest_dragging_over_ = guest->AsWeakPtr();
     45 }
     46 
     47 void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) {
     48   // Avoid race conditions in switching between guests being hovered over by
     49   // only un-setting if the caller is marked as the guest being dragged over.
     50   if (guest_dragging_over_.get() == guest) {
     51     guest_dragging_over_.reset();
     52   }
     53 }
     54 
     55 void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) {
     56   guest_started_drag_ = guest->AsWeakPtr();
     57 }
     58 
     59 WebContentsImpl* BrowserPluginEmbedder::GetWebContents() const {
     60   return static_cast<WebContentsImpl*>(web_contents());
     61 }
     62 
     63 BrowserPluginGuestManager*
     64 BrowserPluginEmbedder::GetBrowserPluginGuestManager() const {
     65   return GetWebContents()->GetBrowserContext()->GetGuestManager();
     66 }
     67 
     68 bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
     69    WebContents* guest_web_contents) {
     70   static_cast<RenderViewHostImpl*>(
     71       guest_web_contents->GetRenderViewHost())->SendScreenRects();
     72   // Not handled => Iterate over all guests.
     73   return false;
     74 }
     75 
     76 void BrowserPluginEmbedder::DidSendScreenRects() {
     77   GetBrowserPluginGuestManager()->ForEachGuest(
     78           GetWebContents(), base::Bind(
     79               &BrowserPluginEmbedder::DidSendScreenRectsCallback,
     80               base::Unretained(this)));
     81 }
     82 
     83 bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) {
     84   bool handled = true;
     85   IPC_BEGIN_MESSAGE_MAP(BrowserPluginEmbedder, message)
     86     IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Attach, OnAttach)
     87     IPC_MESSAGE_HANDLER_GENERIC(DragHostMsg_UpdateDragCursor,
     88                                 OnUpdateDragCursor(&handled));
     89     IPC_MESSAGE_UNHANDLED(handled = false)
     90   IPC_END_MESSAGE_MAP()
     91   return handled;
     92 }
     93 
     94 void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y,
     95     int screen_x, int screen_y, blink::WebDragOperation operation) {
     96   if (guest_started_drag_.get()) {
     97     gfx::Point guest_offset =
     98         guest_started_drag_->GetScreenCoordinates(gfx::Point());
     99     guest_started_drag_->DragSourceEndedAt(client_x - guest_offset.x(),
    100         client_y - guest_offset.y(), screen_x, screen_y, operation);
    101   }
    102 }
    103 
    104 void BrowserPluginEmbedder::SystemDragEnded() {
    105   // When the embedder's drag/drop operation ends, we need to pass the message
    106   // to the guest that initiated the drag/drop operation. This will ensure that
    107   // the guest's RVH state is reset properly.
    108   if (guest_started_drag_.get())
    109     guest_started_drag_->EndSystemDrag();
    110   guest_started_drag_.reset();
    111   guest_dragging_over_.reset();
    112 }
    113 
    114 void BrowserPluginEmbedder::OnUpdateDragCursor(bool* handled) {
    115   *handled = (guest_dragging_over_.get() != NULL);
    116 }
    117 
    118 void BrowserPluginEmbedder::OnGuestCallback(
    119     int instance_id,
    120     const BrowserPluginHostMsg_Attach_Params& params,
    121     const base::DictionaryValue* extra_params,
    122     WebContents* guest_web_contents) {
    123   BrowserPluginGuest* guest = guest_web_contents ?
    124       static_cast<WebContentsImpl*>(guest_web_contents)->
    125           GetBrowserPluginGuest() : NULL;
    126   if (!guest) {
    127     scoped_ptr<base::DictionaryValue> copy_extra_params(
    128         extra_params->DeepCopy());
    129     guest_web_contents = GetBrowserPluginGuestManager()->CreateGuest(
    130         GetWebContents()->GetSiteInstance(),
    131         instance_id,
    132         copy_extra_params.Pass());
    133     guest = guest_web_contents
    134                 ? static_cast<WebContentsImpl*>(guest_web_contents)
    135                       ->GetBrowserPluginGuest()
    136                 : NULL;
    137   }
    138 
    139   if (guest)
    140     guest->Attach(GetWebContents(), params, *extra_params);
    141 }
    142 
    143 void BrowserPluginEmbedder::OnAttach(
    144     int instance_id,
    145     const BrowserPluginHostMsg_Attach_Params& params,
    146     const base::DictionaryValue& extra_params) {
    147   GetBrowserPluginGuestManager()->MaybeGetGuestByInstanceIDOrKill(
    148       instance_id, GetWebContents()->GetRenderProcessHost()->GetID(),
    149       base::Bind(&BrowserPluginEmbedder::OnGuestCallback,
    150                  base::Unretained(this),
    151                  instance_id,
    152                  params,
    153                  &extra_params));
    154 }
    155 
    156 }  // namespace content
    157