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