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