Home | History | Annotate | Download | only in npapi
      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_RENDERER_NPAPI_WEBPLUGIN_IMPL_H_
      6 #define CONTENT_RENDERER_NPAPI_WEBPLUGIN_IMPL_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/files/file_path.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "content/child/npapi/webplugin.h"
     17 #include "content/common/content_export.h"
     18 #include "content/common/webplugin_geometry.h"
     19 #include "third_party/WebKit/public/platform/WebRect.h"
     20 #include "third_party/WebKit/public/platform/WebString.h"
     21 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
     22 #include "third_party/WebKit/public/platform/WebURLRequest.h"
     23 #include "third_party/WebKit/public/platform/WebVector.h"
     24 #include "third_party/WebKit/public/web/WebPlugin.h"
     25 #include "ui/gfx/native_widget_types.h"
     26 #include "url/gurl.h"
     27 
     28 namespace cc {
     29 class IOSurfaceLayer;
     30 }
     31 
     32 namespace blink {
     33 class WebFrame;
     34 class WebLayer;
     35 class WebPluginContainer;
     36 class WebURLResponse;
     37 class WebURLLoader;
     38 class WebURLRequest;
     39 }
     40 
     41 namespace webkit_glue {
     42 class MultipartResponseDelegate;
     43 }  // namespace webkit_glue
     44 
     45 namespace content {
     46 class RenderFrameImpl;
     47 class RenderViewImpl;
     48 class WebPluginDelegateProxy;
     49 
     50 // This is the WebKit side of the plugin implementation that forwards calls,
     51 // after changing out of WebCore types, to a delegate.  The delegate may
     52 // be in a different process.
     53 class WebPluginImpl : public WebPlugin,
     54                       public blink::WebPlugin {
     55  public:
     56   WebPluginImpl(
     57       blink::WebFrame* frame,
     58       const blink::WebPluginParams& params,
     59       const base::FilePath& file_path,
     60       const base::WeakPtr<RenderViewImpl>& render_view,
     61       RenderFrameImpl* render_frame);
     62   virtual ~WebPluginImpl();
     63 
     64   // Helper function for sorting post data.
     65   CONTENT_EXPORT static bool SetPostData(blink::WebURLRequest* request,
     66                                          const char* buf,
     67                                          uint32 length);
     68 
     69   blink::WebFrame* webframe() { return webframe_; }
     70 
     71   // blink::WebPlugin methods:
     72   virtual bool initialize(
     73       blink::WebPluginContainer* container);
     74   virtual void destroy();
     75   virtual NPObject* scriptableObject();
     76   virtual struct _NPP* pluginNPP();
     77   virtual bool getFormValue(blink::WebString& value);
     78   virtual void paint(
     79       blink::WebCanvas* canvas, const blink::WebRect& paint_rect);
     80   virtual void updateGeometry(
     81       const blink::WebRect& frame_rect, const blink::WebRect& clip_rect,
     82       const blink::WebVector<blink::WebRect>& cut_outs, bool is_visible);
     83   virtual void updateFocus(bool focused);
     84   virtual void updateVisibility(bool visible);
     85   virtual bool acceptsInputEvents();
     86   virtual bool handleInputEvent(
     87       const blink::WebInputEvent& event, blink::WebCursorInfo& cursor_info);
     88   virtual void didReceiveResponse(const blink::WebURLResponse& response);
     89   virtual void didReceiveData(const char* data, int data_length);
     90   virtual void didFinishLoading();
     91   virtual void didFailLoading(const blink::WebURLError& error);
     92   virtual void didFinishLoadingFrameRequest(
     93       const blink::WebURL& url, void* notify_data);
     94   virtual void didFailLoadingFrameRequest(
     95       const blink::WebURL& url, void* notify_data,
     96       const blink::WebURLError& error);
     97   virtual bool isPlaceholder() OVERRIDE;
     98 
     99   // WebPlugin implementation:
    100   virtual void SetWindow(gfx::PluginWindowHandle window) OVERRIDE;
    101   virtual void SetAcceptsInputEvents(bool accepts) OVERRIDE;
    102   virtual void WillDestroyWindow(gfx::PluginWindowHandle window) OVERRIDE;
    103   virtual void CancelResource(unsigned long id) OVERRIDE;
    104   virtual void Invalidate() OVERRIDE;
    105   virtual void InvalidateRect(const gfx::Rect& rect) OVERRIDE;
    106   virtual NPObject* GetWindowScriptNPObject() OVERRIDE;
    107   virtual NPObject* GetPluginElement() OVERRIDE;
    108   virtual bool FindProxyForUrl(const GURL& url,
    109                                std::string* proxy_list) OVERRIDE;
    110   virtual void SetCookie(const GURL& url,
    111                          const GURL& first_party_for_cookies,
    112                          const std::string& cookie) OVERRIDE;
    113   virtual std::string GetCookies(const GURL& url,
    114                                  const GURL& first_party_for_cookies) OVERRIDE;
    115   virtual void HandleURLRequest(const char* url,
    116                                 const char *method,
    117                                 const char* target,
    118                                 const char* buf,
    119                                 unsigned int len,
    120                                 int notify_id,
    121                                 bool popups_allowed,
    122                                 bool notify_redirects) OVERRIDE;
    123   virtual void CancelDocumentLoad() OVERRIDE;
    124   virtual void InitiateHTTPRangeRequest(const char* url,
    125                                         const char* range_info,
    126                                         int pending_request_id) OVERRIDE;
    127   virtual void DidStartLoading() OVERRIDE;
    128   virtual void DidStopLoading() OVERRIDE;
    129   virtual bool IsOffTheRecord() OVERRIDE;
    130   virtual void SetDeferResourceLoading(unsigned long resource_id,
    131                                        bool defer) OVERRIDE;
    132   virtual void URLRedirectResponse(bool allow, int resource_id) OVERRIDE;
    133   virtual bool CheckIfRunInsecureContent(const GURL& url) OVERRIDE;
    134 #if defined(OS_WIN)
    135   void SetWindowlessData(HANDLE pump_messages_event,
    136                          gfx::NativeViewId dummy_activation_window) { }
    137   void ReparentPluginWindow(HWND window, HWND parent) { }
    138   void ReportExecutableMemory(size_t size) { }
    139 #endif
    140 #if defined(OS_MACOSX)
    141   virtual WebPluginAcceleratedSurface* GetAcceleratedSurface(
    142       gfx::GpuPreference gpu_preference) OVERRIDE;
    143   virtual void AcceleratedPluginEnabledRendering() OVERRIDE;
    144   virtual void AcceleratedPluginAllocatedIOSurface(int32 width,
    145                                                    int32 height,
    146                                                    uint32 surface_id) OVERRIDE;
    147   virtual void AcceleratedPluginSwappedIOSurface() OVERRIDE;
    148 #endif
    149 
    150  private:
    151   // Given a (maybe partial) url, completes using the base url.
    152   GURL CompleteURL(const char* url);
    153 
    154   enum RoutingStatus {
    155     ROUTED,
    156     NOT_ROUTED,
    157     INVALID_URL,
    158     GENERAL_FAILURE
    159   };
    160 
    161   // Determines the referrer value sent along with outgoing HTTP requests
    162   // issued by plugins.
    163   enum Referrer {
    164     PLUGIN_SRC,
    165     DOCUMENT_URL,
    166     NO_REFERRER
    167   };
    168 
    169   // Given a download request, check if we need to route the output to a frame.
    170   // Returns ROUTED if the load is done and routed to a frame, NOT_ROUTED or
    171   // corresponding error codes otherwise.
    172   RoutingStatus RouteToFrame(const char* url,
    173                              bool is_javascript_url,
    174                              bool popups_allowed,
    175                              const char* method,
    176                              const char* target,
    177                              const char* buf,
    178                              unsigned int len,
    179                              int notify_id,
    180                              Referrer referrer_flag);
    181 
    182   // Returns the next avaiable resource id. Returns 0 if the operation fails.
    183   // It may fail if the page has already been closed.
    184   unsigned long GetNextResourceId();
    185 
    186   // Initiates HTTP GET/POST requests.
    187   // Returns true on success.
    188   bool InitiateHTTPRequest(unsigned long resource_id,
    189                            WebPluginResourceClient* client,
    190                            const GURL& url,
    191                            const char* method,
    192                            const char* buf,
    193                            int len,
    194                            const char* range_info,
    195                            Referrer referrer_flag,
    196                            bool notify_redirects,
    197                            bool check_mixed_scripting);
    198 
    199   gfx::Rect GetWindowClipRect(const gfx::Rect& rect);
    200 
    201   // Sets the actual Widget for the plugin.
    202   void SetContainer(blink::WebPluginContainer* container);
    203 
    204   // Destroys the plugin instance.
    205   // The response_handle_to_ignore parameter if not NULL indicates the
    206   // resource handle to be left valid during plugin shutdown.
    207   void TearDownPluginInstance(blink::WebURLLoader* loader_to_ignore);
    208 
    209   // WebURLLoaderClient implementation.  We implement this interface in the
    210   // renderer process, and then use the simple WebPluginResourceClient interface
    211   // to relay the callbacks to the plugin.
    212   void willSendRequest(blink::WebURLLoader* loader,
    213                        blink::WebURLRequest& request,
    214                        const blink::WebURLResponse& response);
    215   void didSendData(blink::WebURLLoader* loader,
    216                    unsigned long long bytes_sent,
    217                    unsigned long long total_bytes_to_be_sent);
    218   void didReceiveResponse(blink::WebURLLoader* loader,
    219                                   const blink::WebURLResponse& response);
    220 
    221   void didReceiveData(blink::WebURLLoader* loader, const char *buffer,
    222                       int data_length, int encoded_data_length);
    223   void didFinishLoading(blink::WebURLLoader* loader,
    224                         double finishTime);
    225   void didFail(blink::WebURLLoader* loader,
    226                const blink::WebURLError& error);
    227 
    228   // Helper function to remove the stored information about a resource
    229   // request given its index in m_clients.
    230   void RemoveClient(size_t i);
    231 
    232   // Helper function to remove the stored information about a resource
    233   // request given a handle.
    234   void RemoveClient(blink::WebURLLoader* loader);
    235 
    236   // Handles HTTP multipart responses, i.e. responses received with a HTTP
    237   // status code of 206.
    238   // Returns false if response is not multipart (may be if we requested
    239   // single range).
    240   bool HandleHttpMultipartResponse(const blink::WebURLResponse& response,
    241                                    WebPluginResourceClient* client);
    242 
    243   void HandleURLRequestInternal(const char* url,
    244                                 const char* method,
    245                                 const char* target,
    246                                 const char* buf,
    247                                 unsigned int len,
    248                                 int notify_id,
    249                                 bool popups_allowed,
    250                                 Referrer referrer_flag,
    251                                 bool notify_redirects,
    252                                 bool check_mixed_scripting);
    253 
    254   // Tears down the existing plugin instance and creates a new plugin instance
    255   // to handle the response identified by the loader parameter.
    256   bool ReinitializePluginForResponse(blink::WebURLLoader* loader);
    257 
    258   // Delayed task for downloading the plugin source URL.
    259   void OnDownloadPluginSrcUrl();
    260 
    261   struct ClientInfo;
    262 
    263   // Helper functions
    264   WebPluginResourceClient* GetClientFromLoader(blink::WebURLLoader* loader);
    265   ClientInfo* GetClientInfoFromLoader(blink::WebURLLoader* loader);
    266 
    267   // Helper function to set the referrer on the request passed in.
    268   void SetReferrer(blink::WebURLRequest* request, Referrer referrer_flag);
    269 
    270   // Check for invalid chars like @, ;, \ before the first / (in path).
    271   bool IsValidUrl(const GURL& url, Referrer referrer_flag);
    272 
    273   std::vector<ClientInfo> clients_;
    274 
    275   bool windowless_;
    276   gfx::PluginWindowHandle window_;
    277 #if defined(OS_MACOSX)
    278   bool next_io_surface_allocated_;
    279   int32 next_io_surface_width_;
    280   int32 next_io_surface_height_;
    281   uint32 next_io_surface_id_;
    282   scoped_refptr<cc::IOSurfaceLayer> io_surface_layer_;
    283   scoped_ptr<blink::WebLayer> web_layer_;
    284 #endif
    285   bool accepts_input_events_;
    286   RenderFrameImpl* render_frame_;
    287   base::WeakPtr<RenderViewImpl> render_view_;
    288   blink::WebFrame* webframe_;
    289 
    290   WebPluginDelegateProxy* delegate_;
    291 
    292   // This is just a weak reference.
    293   blink::WebPluginContainer* container_;
    294 
    295   // Unique identifier for this plugin, used to track script objects.
    296   struct _NPP* npp_;
    297 
    298   typedef std::map<WebPluginResourceClient*,
    299                    webkit_glue::MultipartResponseDelegate*>
    300       MultiPartResponseHandlerMap;
    301   // Tracks HTTP multipart response handlers instantiated for
    302   // a WebPluginResourceClient instance.
    303   MultiPartResponseHandlerMap multi_part_response_map_;
    304 
    305   // The plugin source URL.
    306   GURL plugin_url_;
    307 
    308   // Indicates if the download would be initiated by the plugin or us.
    309   bool load_manually_;
    310 
    311   // Indicates if this is the first geometry update received by the plugin.
    312   bool first_geometry_update_;
    313 
    314   // Set to true if the next response error should be ignored.
    315   bool ignore_response_error_;
    316 
    317   // The current plugin geometry and clip rectangle.
    318   WebPluginGeometry geometry_;
    319 
    320   // The location of the plugin on disk.
    321   base::FilePath file_path_;
    322 
    323   // The mime type of the plugin.
    324   std::string mime_type_;
    325 
    326   // Holds the list of argument names and values passed to the plugin.  We keep
    327   // these so that we can re-initialize the plugin if we need to.
    328   std::vector<std::string> arg_names_;
    329   std::vector<std::string> arg_values_;
    330 
    331   base::WeakPtrFactory<WebPluginImpl> weak_factory_;
    332 
    333   class LoaderClient : public blink::WebURLLoaderClient {
    334    public:
    335     LoaderClient(WebPluginImpl*);
    336 
    337     virtual void willSendRequest(blink::WebURLLoader*,
    338                                  blink::WebURLRequest&,
    339                                  const blink::WebURLResponse&) OVERRIDE;
    340     virtual void didSendData(blink::WebURLLoader*,
    341                              unsigned long long bytesSent,
    342                              unsigned long long totalBytesToBeSent) OVERRIDE;
    343     virtual void didReceiveResponse(blink::WebURLLoader*,
    344                                     const blink::WebURLResponse&) OVERRIDE;
    345     virtual void didDownloadData(blink::WebURLLoader*,
    346                                  int dataLength,
    347                                  int encodedDataLength) OVERRIDE;
    348     virtual void didReceiveData(blink::WebURLLoader*,
    349                                 const char* data,
    350                                 int dataLength,
    351                                 int encodedDataLength) OVERRIDE;
    352     virtual void didReceiveCachedMetadata(blink::WebURLLoader*,
    353                                           const char* data,
    354                                           int dataLength) OVERRIDE;
    355     virtual void didFinishLoading(blink::WebURLLoader*,
    356                                   double finishTime,
    357                                   int64_t total_encoded_data_length) OVERRIDE;
    358     virtual void didFail(blink::WebURLLoader*,
    359                          const blink::WebURLError&) OVERRIDE;
    360 
    361    private:
    362     WebPluginImpl* parent_;
    363   };
    364 
    365   LoaderClient loader_client_;
    366 
    367   DISALLOW_COPY_AND_ASSIGN(WebPluginImpl);
    368 };
    369 
    370 }  // namespace content
    371 
    372 #endif  // CONTENT_RENDERER_NPAPI_WEBPLUGIN_IMPL_H_
    373