Home | History | Annotate | Download | only in 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 #ifndef CONTENT_PLUGIN_WEBPLUGIN_PROXY_H_
      6 #define CONTENT_PLUGIN_WEBPLUGIN_PROXY_H_
      7 
      8 #include <string>
      9 
     10 #include "base/containers/hash_tables.h"
     11 #include "base/memory/ref_counted.h"
     12 #if defined(OS_MACOSX)
     13 #include "base/mac/scoped_cftyperef.h"
     14 #endif
     15 #include "base/memory/scoped_handle.h"
     16 #include "base/memory/scoped_ptr.h"
     17 #include "base/memory/shared_memory.h"
     18 #include "base/memory/weak_ptr.h"
     19 #include "base/timer/timer.h"
     20 #include "content/child/npapi/webplugin.h"
     21 #include "ipc/ipc_message.h"
     22 #include "skia/ext/refptr.h"
     23 #include "third_party/skia/include/core/SkCanvas.h"
     24 #include "url/gurl.h"
     25 #if defined(USE_X11)
     26 #include "ui/base/x/x11_util.h"
     27 #endif
     28 #include "ui/gl/gpu_preference.h"
     29 #include "ui/surface/transport_dib.h"
     30 
     31 namespace content {
     32 class PluginChannel;
     33 class WebPluginDelegateImpl;
     34 
     35 #if defined(OS_MACOSX)
     36 class WebPluginAcceleratedSurfaceProxy;
     37 #endif
     38 
     39 // This is an implementation of WebPlugin that proxies all calls to the
     40 // renderer.
     41 class WebPluginProxy : public WebPlugin {
     42  public:
     43   // Creates a new proxy for WebPlugin, using the given sender to send the
     44   // marshalled WebPlugin calls.
     45   WebPluginProxy(PluginChannel* channel,
     46                  int route_id,
     47                  const GURL& page_url,
     48                  int host_render_view_routing_id);
     49   virtual ~WebPluginProxy();
     50 
     51   void set_delegate(WebPluginDelegateImpl* d) { delegate_ = d; }
     52 
     53   // WebPlugin overrides
     54   virtual void SetWindow(gfx::PluginWindowHandle window) OVERRIDE;
     55 
     56   // Whether input events should be sent to the delegate.
     57   virtual void SetAcceptsInputEvents(bool accepts) OVERRIDE;
     58 
     59   virtual void WillDestroyWindow(gfx::PluginWindowHandle window) OVERRIDE;
     60 #if defined(OS_WIN)
     61   void SetWindowlessData(HANDLE pump_messages_event,
     62                          gfx::NativeViewId dummy_activation_window);
     63 #endif
     64 
     65   virtual void CancelResource(unsigned long id) OVERRIDE;
     66   virtual void Invalidate() OVERRIDE;
     67   virtual void InvalidateRect(const gfx::Rect& rect) OVERRIDE;
     68   virtual NPObject* GetWindowScriptNPObject() OVERRIDE;
     69   virtual NPObject* GetPluginElement() OVERRIDE;
     70   virtual bool FindProxyForUrl(const GURL& url,
     71                                std::string* proxy_list) OVERRIDE;
     72   virtual void SetCookie(const GURL& url,
     73                          const GURL& first_party_for_cookies,
     74                          const std::string& cookie) OVERRIDE;
     75   virtual std::string GetCookies(const GURL& url,
     76                                  const GURL& first_party_for_cookies) OVERRIDE;
     77 
     78   // class-specific methods
     79 
     80   // Returns a WebPluginResourceClient object given its id, or NULL if no
     81   // object with that id exists.
     82   WebPluginResourceClient* GetResourceClient(int id);
     83 
     84   // Returns the id of the renderer that contains this plugin.
     85   int GetRendererId();
     86 
     87   // Returns the id of the associated render view.
     88   int host_render_view_routing_id() const {
     89     return host_render_view_routing_id_;
     90   }
     91 
     92   // For windowless plugins, paints the given rectangle into the local buffer.
     93   void Paint(const gfx::Rect& rect);
     94 
     95   // Callback from the renderer to let us know that a paint occurred.
     96   void DidPaint();
     97 
     98   // Notification received on a plugin issued resource request creation.
     99   void OnResourceCreated(int resource_id, WebPluginResourceClient* client);
    100 
    101   virtual void HandleURLRequest(const char* url,
    102                                 const char* method,
    103                                 const char* target,
    104                                 const char* buf,
    105                                 unsigned int len,
    106                                 int notify_id,
    107                                 bool popups_allowed,
    108                                 bool notify_redirects) OVERRIDE;
    109   void UpdateGeometry(const gfx::Rect& window_rect,
    110                       const gfx::Rect& clip_rect,
    111                       const TransportDIB::Handle& windowless_buffer0,
    112                       const TransportDIB::Handle& windowless_buffer1,
    113                       int windowless_buffer_index);
    114   virtual void CancelDocumentLoad() OVERRIDE;
    115   virtual void InitiateHTTPRangeRequest(
    116       const char* url, const char* range_info, int range_request_id) OVERRIDE;
    117   virtual void SetDeferResourceLoading(unsigned long resource_id,
    118                                        bool defer) OVERRIDE;
    119   virtual bool IsOffTheRecord() OVERRIDE;
    120   virtual void ResourceClientDeleted(
    121       WebPluginResourceClient* resource_client) OVERRIDE;
    122 
    123 #if defined(OS_MACOSX)
    124   virtual void FocusChanged(bool focused) OVERRIDE;
    125   virtual void StartIme() OVERRIDE;
    126   virtual WebPluginAcceleratedSurface*
    127       GetAcceleratedSurface(gfx::GpuPreference gpu_preference) OVERRIDE;
    128 
    129   //----------------------------------------------------------------------
    130   // Accelerated plugin implementation which renders via the compositor.
    131 
    132   // Tells the renderer, and from there the GPU process, that the plugin
    133   // is using accelerated rather than software rendering.
    134   virtual void AcceleratedPluginEnabledRendering() OVERRIDE;
    135 
    136   // Tells the renderer, and from there the GPU process, that the plugin
    137   // allocated the given IOSurface to be used as its backing store.
    138   virtual void AcceleratedPluginAllocatedIOSurface(int32 width,
    139                                                    int32 height,
    140                                                    uint32 surface_id) OVERRIDE;
    141   virtual void AcceleratedPluginSwappedIOSurface() OVERRIDE;
    142 #endif
    143 
    144   virtual void URLRedirectResponse(bool allow, int resource_id) OVERRIDE;
    145 
    146 #if defined(OS_WIN) && !defined(USE_AURA)
    147   // Retrieves the IME status from a windowless plug-in and sends it to a
    148   // renderer process. A renderer process will convert the coordinates from
    149   // local to the window coordinates and send the converted coordinates to a
    150   // browser process.
    151   void UpdateIMEStatus();
    152 #endif
    153 
    154  private:
    155   class SharedTransportDIB : public base::RefCounted<SharedTransportDIB> {
    156    public:
    157     explicit SharedTransportDIB(TransportDIB* dib);
    158     TransportDIB* dib() { return dib_.get(); }
    159    private:
    160     friend class base::RefCounted<SharedTransportDIB>;
    161     ~SharedTransportDIB();
    162 
    163     scoped_ptr<TransportDIB> dib_;
    164   };
    165 
    166   bool Send(IPC::Message* msg);
    167 
    168   // Handler for sending over the paint event to the plugin.
    169   void OnPaint(const gfx::Rect& damaged_rect);
    170 
    171 #if defined(OS_WIN)
    172   void CreateCanvasFromHandle(const TransportDIB::Handle& dib_handle,
    173                               const gfx::Rect& window_rect,
    174                               skia::RefPtr<SkCanvas>* canvas);
    175 #elif defined(OS_MACOSX)
    176   static void CreateDIBAndCGContextFromHandle(
    177       const TransportDIB::Handle& dib_handle,
    178       const gfx::Rect& window_rect,
    179       scoped_ptr<TransportDIB>* dib_out,
    180       base::ScopedCFTypeRef<CGContextRef>* cg_context_out);
    181 #elif defined(USE_X11)
    182   static void CreateDIBAndCanvasFromHandle(
    183       const TransportDIB::Handle& dib_handle,
    184       const gfx::Rect& window_rect,
    185       scoped_refptr<SharedTransportDIB>* dib_out,
    186       skia::RefPtr<SkCanvas>* canvas);
    187 
    188   static void CreateShmPixmapFromDIB(
    189       TransportDIB* dib,
    190       const gfx::Rect& window_rect,
    191       XID* pixmap_out);
    192 #endif
    193 
    194   // Updates the shared memory sections where windowless plugins paint.
    195   void SetWindowlessBuffers(const TransportDIB::Handle& windowless_buffer0,
    196                             const TransportDIB::Handle& windowless_buffer1,
    197                             const gfx::Rect& window_rect);
    198 
    199 #if defined(OS_MACOSX)
    200   CGContextRef windowless_context() const {
    201     return windowless_contexts_[windowless_buffer_index_].get();
    202   }
    203 #else
    204   skia::RefPtr<SkCanvas> windowless_canvas() const {
    205     return windowless_canvases_[windowless_buffer_index_];
    206   }
    207 
    208 #if defined(USE_X11)
    209   XID windowless_shm_pixmap() const {
    210     return windowless_shm_pixmaps_[windowless_buffer_index_];
    211   }
    212 #endif
    213 
    214 #endif
    215 
    216   typedef base::hash_map<int, WebPluginResourceClient*> ResourceClientMap;
    217   ResourceClientMap resource_clients_;
    218 
    219   scoped_refptr<PluginChannel> channel_;
    220   int route_id_;
    221   NPObject* window_npobject_;
    222   NPObject* plugin_element_;
    223   WebPluginDelegateImpl* delegate_;
    224   gfx::Rect damaged_rect_;
    225   bool waiting_for_paint_;
    226   // The url of the main frame hosting the plugin.
    227   GURL page_url_;
    228 
    229   // Variables used for desynchronized windowless plugin painting. See note in
    230   // webplugin_delegate_proxy.h for how this works. The two sets of windowless_*
    231   // fields are for the front-buffer and back-buffer of a buffer flipping system
    232   // and windowless_buffer_index_ identifies which set we are using as the
    233   // back-buffer at any given time.
    234   int windowless_buffer_index_;
    235 #if defined(OS_MACOSX)
    236   scoped_ptr<TransportDIB> windowless_dibs_[2];
    237   base::ScopedCFTypeRef<CGContextRef> windowless_contexts_[2];
    238   scoped_ptr<WebPluginAcceleratedSurfaceProxy> accelerated_surface_;
    239 #else
    240   skia::RefPtr<SkCanvas> windowless_canvases_[2];
    241 
    242 #if defined(USE_X11)
    243   scoped_refptr<SharedTransportDIB> windowless_dibs_[2];
    244   // If we can use SHM pixmaps for windowless plugin painting or not.
    245   bool use_shm_pixmap_;
    246   // The SHM pixmaps for windowless plugin painting.
    247   XID windowless_shm_pixmaps_[2];
    248 #endif
    249 
    250 #endif
    251 
    252   // Contains the routing id of the host render view.
    253   int host_render_view_routing_id_;
    254 
    255   base::WeakPtrFactory<WebPluginProxy> weak_factory_;
    256 };
    257 
    258 }  // namespace content
    259 
    260 #endif  // CONTENT_PLUGIN_WEBPLUGIN_PROXY_H_
    261