• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
webframe()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)
SetWindowlessData(HANDLE pump_messages_event,gfx::NativeViewId dummy_activation_window)135   void SetWindowlessData(HANDLE pump_messages_event,
136                          gfx::NativeViewId dummy_activation_window) { }
ReparentPluginWindow(HWND window,HWND parent)137   void ReparentPluginWindow(HWND window, HWND parent) { }
ReportExecutableMemory(size_t size)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