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