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