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 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 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 webframe()70 blink::WebFrame* webframe() { return webframe_; } delegate()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) SetWindowlessData(HANDLE pump_messages_event,gfx::NativeViewId dummy_activation_window)137 void SetWindowlessData(HANDLE pump_messages_event, 138 gfx::NativeViewId dummy_activation_window) { } ReparentPluginWindow(HWND window,HWND parent)139 void ReparentPluginWindow(HWND window, HWND parent) { } ReportExecutableMemory(size_t size)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