webplugin_impl.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 webkit_glue {
42class MultipartResponseDelegate;
43}  // namespace webkit_glue
44
45namespace content {
46class RenderFrameImpl;
47class RenderViewImpl;
48class 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.
53class 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