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